feat: improve app ui and project metadata
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { ArrowRight, CheckCircle2, ListTree } from "lucide-react";
|
||||
|
||||
import { Button } from "@/components/ui/Button";
|
||||
import { StatusNote } from "@/components/ui/StatusNote";
|
||||
import type { AcceptResponse } from "@/lib/api/types";
|
||||
import { buildAcceptPreview } from "@/lib/review/accept-preview";
|
||||
import { ThinkingIndicator } from "@/components/ThinkingIndicator";
|
||||
import { buttonClass } from "@/lib/ui/variants";
|
||||
|
||||
interface AcceptPanelProps {
|
||||
projectId: string;
|
||||
@@ -42,40 +46,50 @@ export function AcceptPanel({
|
||||
if (result) {
|
||||
return (
|
||||
<div className="rounded border border-pass/50 bg-panel p-4">
|
||||
<h3 className="mb-2 text-sm font-semibold text-pass">本章已验收</h3>
|
||||
<ul className="space-y-1 text-xs text-ink-soft">
|
||||
<li>
|
||||
晋升版次:
|
||||
<span className="font-mono text-ink">v{result.accepted_version}</span>
|
||||
</li>
|
||||
<li>
|
||||
章节摘要:{result.digest_added ? "已新增一行" : "未变更"}
|
||||
</li>
|
||||
<li>
|
||||
裁决写回:
|
||||
<span className="font-mono text-ink">
|
||||
<StatusNote variant="success" title="本章已验收">
|
||||
<p className="text-sm leading-6">
|
||||
终稿已晋升为正式版本,章节摘要和裁决留痕已按验收事务写回。
|
||||
</p>
|
||||
</StatusNote>
|
||||
<dl className="mt-3 grid grid-cols-3 gap-2 text-center">
|
||||
<div className="rounded border border-line bg-bg/60 p-2">
|
||||
<dt className="text-[11px] text-ink-soft">版次</dt>
|
||||
<dd className="mt-1 font-mono text-sm text-ink">
|
||||
v{result.accepted_version}
|
||||
</dd>
|
||||
</div>
|
||||
<div className="rounded border border-line bg-bg/60 p-2">
|
||||
<dt className="text-[11px] text-ink-soft">摘要</dt>
|
||||
<dd className="mt-1 text-sm text-ink">
|
||||
{result.digest_added ? "已新增" : "未变更"}
|
||||
</dd>
|
||||
</div>
|
||||
<div className="rounded border border-line bg-bg/60 p-2">
|
||||
<dt className="text-[11px] text-ink-soft">裁决</dt>
|
||||
<dd className="mt-1 font-mono text-sm text-ink">
|
||||
{result.decisions_recorded}
|
||||
</span>{" "}
|
||||
条
|
||||
</li>
|
||||
{result.review_id ? (
|
||||
<li className="truncate">
|
||||
留痕:<span className="font-mono">{result.review_id}</span>
|
||||
</li>
|
||||
) : null}
|
||||
</ul>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
{result.review_id ? (
|
||||
<p className="mt-2 truncate text-[11px] text-ink-soft">
|
||||
留痕:<span className="font-mono">{result.review_id}</span>
|
||||
</p>
|
||||
) : null}
|
||||
{/* 验收闭环 → 写下一章入口(修「验收后无路可走」的断点)。 */}
|
||||
<div className="mt-3 flex flex-wrap items-center gap-2">
|
||||
<Link
|
||||
href={`/projects/${projectId}/write?chapter=${chapterNo + 1}`}
|
||||
className="rounded bg-cinnabar px-4 py-2 text-sm text-panel hover:opacity-90"
|
||||
className={buttonClass({ variant: "primary" })}
|
||||
>
|
||||
→ 写第 {chapterNo + 1} 章
|
||||
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
||||
写第 {chapterNo + 1} 章
|
||||
</Link>
|
||||
<Link
|
||||
href={`/projects/${projectId}/outline`}
|
||||
className="rounded border border-line px-4 py-2 text-sm text-ink hover:border-cinnabar hover:text-cinnabar"
|
||||
className={buttonClass({ variant: "secondary" })}
|
||||
>
|
||||
<ListTree className="h-4 w-4" aria-hidden="true" />
|
||||
返回大纲
|
||||
</Link>
|
||||
</div>
|
||||
@@ -84,20 +98,24 @@ export function AcceptPanel({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rounded border border-line bg-panel p-4">
|
||||
<div
|
||||
className={`rounded border bg-panel p-4 ${
|
||||
blocked ? "border-conflict/35" : "border-line"
|
||||
}`}
|
||||
>
|
||||
{blocked ? (
|
||||
<p className="mb-2 text-xs text-conflict" role="status">
|
||||
<StatusNote className="mb-3" variant="danger" role="status">
|
||||
尚有 {unresolvedCount} 项冲突未裁决,处理完才能验收。
|
||||
</p>
|
||||
</StatusNote>
|
||||
) : (
|
||||
<>
|
||||
<p className="mb-2 text-xs text-ink-soft">
|
||||
<StatusNote className="mb-3" variant={reviewed ? "success" : "info"}>
|
||||
{conflictCount === 0
|
||||
? reviewed
|
||||
? "无冲突,可直接验收。"
|
||||
: "尚未审稿——建议先点「重新审稿」确认本章无冲突,再验收。"
|
||||
: "全部冲突已裁决,可验收本章。"}
|
||||
</p>
|
||||
</StatusNote>
|
||||
{/* R3:验收前「本次将更新」清单(预期,落库口径以验收回执为准)。 */}
|
||||
<div className="mb-3 rounded border border-line/70 bg-bg/50 p-3">
|
||||
<h4 className="mb-1.5 text-xs font-semibold text-ink">
|
||||
@@ -122,19 +140,22 @@ export function AcceptPanel({
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
<Button
|
||||
onClick={onAccept}
|
||||
disabled={blocked || accepting}
|
||||
aria-disabled={blocked || accepting}
|
||||
className="w-full rounded bg-cinnabar px-4 py-2 text-sm text-panel hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40"
|
||||
variant="primary"
|
||||
className="w-full"
|
||||
>
|
||||
{accepting ? (
|
||||
<ThinkingIndicator label="验收中" className="justify-center" />
|
||||
) : (
|
||||
"全部处理完 → 验收本章"
|
||||
<>
|
||||
<CheckCircle2 className="h-4 w-4" aria-hidden="true" />
|
||||
全部处理完,验收本章
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user