Files
GEOAgentArticleOptimizer/src/components/cases/human-copy-case-detail.tsx
T
2026-07-08 13:59:26 +08:00

142 lines
4.4 KiB
TypeScript

"use client";
import type {
HumanCopyCaseInputPayload,
HumanCopyResultVersionPayload,
OptimizationResultVersion,
} from "../../lib/cases/types";
interface HumanCopyCaseDetailProps {
input: unknown;
version: OptimizationResultVersion | null;
}
const intensityLabels: Record<string, string> = {
light: "轻微整理",
medium: "适度润色",
conversational: "更口语自然",
};
export function HumanCopyCaseDetail({
input,
version,
}: HumanCopyCaseDetailProps) {
const payload = isHumanCopyInput(input) ? input : null;
const result = isHumanCopyResult(version?.payload) ? version.payload : null;
return (
<>
<section className="panel stack">
<div className="panel-heading">原始文案</div>
{payload ? (
<>
<pre className="copy-result">{payload.source_text}</pre>
<div className="case-meta-grid">
<MetaItem label="优化目标" value={payload.goal} />
<MetaItem
label="修改强度"
value={intensityLabels[payload.intensity] ?? payload.intensity}
/>
<MetaItem
label="发布目标"
value={payload.publish_target || "未指定"}
/>
<MetaItem
label="补充要求"
value={payload.user_instructions || "无"}
/>
</div>
</>
) : (
<p className="empty-panel">没有保存输入。</p>
)}
</section>
<section className="panel stack">
<div className="panel-heading">优化后文案</div>
{result ? (
<>
<pre className="copy-result">{result.optimized_text}</pre>
<section className="stack">
<h3>改动说明</h3>
{result.change_notes.length > 0 ? (
<ul className="qa-list">
{result.change_notes.map((note, index) => (
<li className="qa-item" key={`${note.original}-${index}`}>
<p>{note.reason}</p>
<small>原句:{note.original}</small>
<small>改后:{note.revised}</small>
{note.revertible ? <em>这处可还原。</em> : null}
</li>
))}
</ul>
) : (
<p className="empty-panel">没有改动说明。</p>
)}
</section>
<section className="stack">
<h3>AI 味检查</h3>
{result.ai_taste_checks.length > 0 ? (
<ul className="qa-list">
{result.ai_taste_checks.map((check) => (
<li className="qa-item" key={check.rule_id}>
<div className="qa-title-row">
<strong>{check.rule_id}</strong>
<span className={`status-pill ${check.status}`}>
{check.status}
</span>
</div>
<small>{check.evidence}</small>
{check.suggestion ? <small>{check.suggestion}</small> : null}
</li>
))}
</ul>
) : (
<p className="empty-panel">没有 AI 味检查记录。</p>
)}
</section>
{result.warnings.length > 0 ? (
<ul className="calibration-observations">
{result.warnings.map((warning) => (
<li key={warning}>{warning}</li>
))}
</ul>
) : null}
</>
) : (
<p className="empty-panel">
{version?.error_summary ?? "当前版本没有优化结果。"}
</p>
)}
</section>
</>
);
}
function MetaItem({ label, value }: { label: string; value: string }) {
return (
<div>
<span>{label}</span>
<strong>{value}</strong>
</div>
);
}
function isHumanCopyInput(value: unknown): value is HumanCopyCaseInputPayload {
return (
value !== null &&
typeof value === "object" &&
"source_text" in value &&
"goal" in value
);
}
function isHumanCopyResult(value: unknown): value is HumanCopyResultVersionPayload {
return (
value !== null &&
typeof value === "object" &&
"optimized_text" in value &&
"change_notes" in value
);
}