Files

127 lines
5.6 KiB
TypeScript

"use client";
import { Ban, CheckCircle2, PauseCircle, Pencil, RotateCw } from "lucide-react";
import { api, formatDateTime } from "@/lib/api";
import type { StandardQAItem } from "@/lib/types";
import RiskBadge from "./RiskBadge";
import StatusBadge from "./StatusBadge";
export default function StandardQATable({ items, onChanged }: { items: StandardQAItem[]; onChanged: () => void }) {
async function action(id: number, path: string) {
try {
await api.post(`/standard-qa/${id}/${path}`, {});
onChanged();
} catch (error) {
alert(error instanceof Error ? error.message : "操作失败");
}
}
async function edit(item: StandardQAItem) {
const standardQuestion = window.prompt("标准问题", item.standard_question);
if (standardQuestion === null) return;
const standardAnswer = window.prompt("标准回答", item.standard_answer);
if (standardAnswer === null) return;
await api.patch(`/standard-qa/${item.id}`, {
standard_question: standardQuestion,
standard_answer: standardAnswer
});
onChanged();
}
return (
<div className="table-wrap rounded-md border border-line bg-white">
<table className="min-w-[1350px] w-full border-collapse text-left text-sm">
<thead className="bg-panel text-xs uppercase text-slate-500">
<tr>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
<th className="px-4 py-3"></th>
</tr>
</thead>
<tbody>
{items.map((item) => (
<tr key={item.id} className="border-t border-line align-top">
<td className="max-w-sm px-4 py-3 font-medium text-ink">{item.standard_question}</td>
<td className="max-w-md whitespace-pre-wrap px-4 py-3">{item.standard_answer}</td>
<td className="px-4 py-3">{item.similar_questions.join("、") || "-"}</td>
<td className="px-4 py-3">{item.primary_topic}</td>
<td className="px-4 py-3">{item.problem_tags.join("、") || "-"}</td>
<td className="px-4 py-3">{item.course_stage}</td>
<td className="px-4 py-3">{item.audience_tags.join("、") || "-"}</td>
<td className="max-w-xs px-4 py-3">{item.answer_boundary ?? "-"}</td>
<td className="px-4 py-3">{item.forbidden_expressions.join("、") || "-"}</td>
<td className="px-4 py-3">
QA #{item.source_raw_qa_id}
<br />
#{item.session_id}
</td>
<td className="space-y-2 px-4 py-3">
<StatusBadge status={item.audit_status} />
<StatusBadge status={item.call_status} />
<RiskBadge level={item.risk_level} />
</td>
<td className="px-4 py-3">{formatDateTime(item.updated_at)}</td>
<td className="px-4 py-3">
<div className="flex flex-wrap gap-2">
<button
onClick={() => edit(item)}
className="inline-flex h-8 items-center gap-1 rounded-md border border-line px-2 text-xs hover:bg-slate-50"
>
<Pencil className="h-3.5 w-3.5" aria-hidden />
</button>
<button
onClick={() => action(item.id, "mark-callable")}
className="inline-flex h-8 items-center gap-1 rounded-md border border-emerald-200 px-2 text-xs text-emerald-700 hover:bg-emerald-50"
>
<CheckCircle2 className="h-3.5 w-3.5" aria-hidden />
</button>
<button
onClick={() => action(item.id, "mark-not-callable")}
className="inline-flex h-8 items-center gap-1 rounded-md border border-line px-2 text-xs hover:bg-slate-50"
>
<PauseCircle className="h-3.5 w-3.5" aria-hidden />
</button>
<button
onClick={() => action(item.id, "need-review")}
className="inline-flex h-8 items-center gap-1 rounded-md border border-line px-2 text-xs hover:bg-slate-50"
>
<RotateCw className="h-3.5 w-3.5" aria-hidden />
</button>
<button
onClick={() => action(item.id, "disable")}
className="inline-flex h-8 items-center gap-1 rounded-md border border-rose-200 px-2 text-xs text-rose-700 hover:bg-rose-50"
>
<Ban className="h-3.5 w-3.5" aria-hidden />
</button>
</div>
</td>
</tr>
))}
{items.length === 0 ? (
<tr>
<td className="px-4 py-8 text-center text-slate-500" colSpan={13}>
</td>
</tr>
) : null}
</tbody>
</table>
</div>
);
}