Files
UHD_Media_Tool/apps/web/app/components/episode-mapping/preview-table.tsx
T

74 lines
3.4 KiB
TypeScript

import type { EpisodeMappingPreviewItem } from "@umt/contracts";
import { ArrowRight } from "lucide-react";
import { StatusBadge } from "~/components/console/status-badge.tsx";
import { cn, formatDateTime } from "~/lib/utils.ts";
import { canonicalText, methodText, sourceText, VALIDATION } from "./model.ts";
// 模拟预览表格:原始季集 → 当前结果 → 套用草稿后的结果、方式、校验;与当前不同的行高亮并标「有变化」。
export function PreviewTable({
items,
hasDraft,
empty = "这部作品还没有绑定的资源。",
}: {
items: EpisodeMappingPreviewItem[];
/** 有草稿时列名写「套用后」,否则写「重算」 */
hasDraft: boolean;
empty?: string;
}) {
if (!items.length) return <p className="px-4 py-6 text-caption text-muted-foreground sm:px-5">{empty}</p>;
return (
<div className="overflow-x-auto">
<table className="w-full min-w-[44rem] text-caption">
<thead>
<tr className="border-b border-border/60 text-left text-meta text-muted-foreground">
<th className="px-4 py-2 font-medium">资源</th>
<th className="px-3 py-2 font-medium">原始</th>
<th className="px-3 py-2 font-medium">当前</th>
<th className="px-3 py-2 font-medium">{hasDraft ? "套用后" : "重算"}</th>
<th className="px-3 py-2 font-medium">方式</th>
<th className="px-4 py-2 font-medium">校验</th>
</tr>
</thead>
<tbody>
{items.map((it) => {
const v = VALIDATION[it.validation];
return (
<tr
key={it.sourceReleaseId}
data-changed={it.changed || undefined}
className={cn("border-b border-border/60 last:border-b-0", it.changed && "bg-foreground/[0.04]")}
>
<td className="max-w-[22rem] px-4 py-2 align-top">
<div className="font-mono text-meta break-all text-foreground">{it.title}</div>
<div className="mt-0.5 text-meta text-muted-foreground">
{[it.releaseGroup, formatDateTime(it.publishedAt)].filter(Boolean).join(" · ")}
</div>
</td>
<td className="px-3 py-2 align-top font-mono tabular-nums">{sourceText(it.preview)}</td>
<td className="px-3 py-2 align-top">
<div className="font-mono tabular-nums">{canonicalText(it.current)}</div>
<div className="text-meta text-muted-foreground">{methodText(it.current)}</div>
</td>
<td className="px-3 py-2 align-top">
<div className="inline-flex items-center gap-1 font-mono tabular-nums">
{it.changed ? <ArrowRight aria-hidden className="h-3 w-3 text-muted-foreground" /> : null}
<span className={cn(it.changed && "font-semibold text-foreground")}>
{canonicalText(it.preview)}
</span>
</div>
{it.changed ? <div className="text-meta text-muted-foreground">有变化</div> : null}
</td>
<td className="px-3 py-2 align-top">{methodText(it.preview)}</td>
<td className="px-4 py-2 align-top">
<StatusBadge tone={v.tone}>{v.label}</StatusBadge>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}