75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
"use client";
|
||
|
||
import { AlertTriangle, CheckCircle2, CircleDashed } from "lucide-react";
|
||
|
||
import { Badge } from "@/components/ui/Badge";
|
||
import type { PaceReport } from "@/lib/review/sse";
|
||
import { BeatMap } from "./BeatMap";
|
||
|
||
interface PacePanelProps {
|
||
pace: PaceReport | null;
|
||
incomplete: boolean;
|
||
}
|
||
|
||
// 节奏报告区(UX §6.4 ④):节拍图 ▁▃▅ + 注水段列表 + 章末钩子徽标。只读建议。
|
||
export function PacePanel({ pace, incomplete }: PacePanelProps) {
|
||
return (
|
||
<section className="mb-4">
|
||
<h2 className="text-xs font-semibold uppercase tracking-wide text-ink-soft">
|
||
节奏 (pace-checker)
|
||
</h2>
|
||
{incomplete ? (
|
||
<Badge variant="warning" className="mt-1">
|
||
<CircleDashed className="h-3 w-3" aria-hidden="true" />
|
||
未完成
|
||
</Badge>
|
||
) : pace === null ? (
|
||
<p className="mt-1 text-xs text-ink-soft">无节奏报告。</p>
|
||
) : (
|
||
<div className="mt-2 space-y-2 text-xs">
|
||
<div>
|
||
<p className="mb-1 text-ink-soft">爽点节拍图</p>
|
||
<BeatMap beatMap={pace.beat_map} />
|
||
</div>
|
||
|
||
<p>
|
||
章末钩子:
|
||
{pace.hook ? (
|
||
<Badge variant="success">
|
||
<CheckCircle2 className="h-3 w-3" aria-hidden="true" />
|
||
有
|
||
</Badge>
|
||
) : (
|
||
<Badge variant="warning">
|
||
<AlertTriangle className="h-3 w-3" aria-hidden="true" />
|
||
无(建议补悬念)
|
||
</Badge>
|
||
)}
|
||
</p>
|
||
|
||
{pace.water.length > 0 ? (
|
||
<div>
|
||
<Badge variant="warning">
|
||
<AlertTriangle className="h-3 w-3" aria-hidden="true" />
|
||
注水段
|
||
</Badge>
|
||
<ul className="mt-1 space-y-1">
|
||
{pace.water.map((w, i) => (
|
||
<li key={i} className="text-ink-soft">
|
||
{w.where}:{w.reason}
|
||
</li>
|
||
))}
|
||
</ul>
|
||
</div>
|
||
) : (
|
||
<Badge variant="success">
|
||
<CheckCircle2 className="h-3 w-3" aria-hidden="true" />
|
||
无明显注水
|
||
</Badge>
|
||
)}
|
||
</div>
|
||
)}
|
||
</section>
|
||
);
|
||
}
|