"use client"; import { useState } from "react"; import { X } from "lucide-react"; import { REPLY_QUALITY_NOTE_MAX, REPLY_QUALITY_REASON_LABELS, REPLY_QUALITY_REASONS } from "@/lib/reply-quality-labels"; import { notifyError, notifySuccess } from "@/lib/notify"; import { saveReplyQualityReason } from "@/lib/reply-ratings"; const REASONS = REPLY_QUALITY_REASONS.map((key) => [key, REPLY_QUALITY_REASON_LABELS[key]] as const); /** * 不满意原因 after a 👎 (compliance round 2026-09-30). Everything here is * optional: the 👎 and the turn's snapshot are already saved when this opens; * closing it keeps them. One line says the turn is sent for review. The thanks * (or a failure) is a toast; the panel closes itself on success (2026-09-30). */ export function ReplyDownReason({ feedbackKey, onClose }: Readonly<{ feedbackKey: string; onClose: () => void }>) { const [picked, setPicked] = useState>(() => new Set()); const [note, setNote] = useState(""); const [state, setState] = useState<"idle" | "sending" | "failed">("idle"); async function submit() { if (state === "sending") return; setState("sending"); const ok = await saveReplyQualityReason(feedbackKey, REASONS.map(([key]) => key).filter((key) => picked.has(key)), note); if (ok) { notifySuccess("已收到,谢谢。"); onClose(); return; } setState("failed"); notifyError("没能提交,再试一次。"); } return (
哪里不满意?可以不选
{REASONS.map(([key, label]) => ( ))}
setNote(event.target.value)} />
会把这一轮对话发给我们排查
); }