"use client"; import React from "react"; import { Box, Button, Checkbox, Chip, CircularProgress, Collapse, FormControlLabel, Stack, TextField, Typography, alpha, useTheme, } from "@mui/material"; import type { Theme } from "@mui/material/styles"; import CheckCircleRounded from "@mui/icons-material/CheckCircleRounded"; import EditNoteRounded from "@mui/icons-material/EditNoteRounded"; import HelpOutlineRounded from "@mui/icons-material/HelpOutlineRounded"; import RadioButtonUncheckedRounded from "@mui/icons-material/RadioButtonUncheckedRounded"; import type { Message } from "./GlobalChatbox.types"; const getQuestionStatusLabel = ( status: NonNullable[number]["status"], ) => { if (status === "answered") return "已回答"; if (status === "rejected") return "已跳过"; if (status === "error") return "提交失败"; if (status === "submitting") return "提交中"; return "等待回答"; }; const getQuestionStatusColor = ( status: NonNullable[number]["status"], theme: Theme, ) => { if (status === "answered") return theme.palette.success.main; if (status === "rejected") return theme.palette.text.secondary; if (status === "error") return theme.palette.error.main; return "#0288d1"; }; const QuestionRequestCard = ({ questionRequest, onReply, onReject, }: { questionRequest: NonNullable[number]; onReply: (requestId: string, answers: string[][]) => void; onReject: (requestId: string) => void; }) => { const theme = useTheme(); const isEditable = questionRequest.status === "pending" || questionRequest.status === "error"; const isSubmitting = questionRequest.status === "submitting"; const statusColor = getQuestionStatusColor(questionRequest.status, theme); const [selected, setSelected] = React.useState>({}); const [customSelected, setCustomSelected] = React.useState>({}); const [custom, setCustom] = React.useState>({}); const answers = React.useMemo( () => questionRequest.questions.map((question, index) => { const selectedAnswers = selected[index] ?? []; const isCustomSelected = customSelected[index] === true || (question.custom !== false && question.options.length === 0); const customAnswer = custom[index]?.trim(); return isCustomSelected && customAnswer ? [...selectedAnswers, customAnswer] : selectedAnswers; }), [custom, customSelected, questionRequest.questions, selected], ); const canSubmit = isEditable && questionRequest.questions.length > 0 && questionRequest.questions.every((_, index) => { const answer = answers[index] ?? []; return answer.some((item) => item.trim().length > 0); }); const answerSummary = (questionRequest.answers ?? []) .map((answer) => answer.join("、")) .filter(Boolean) .join(";"); return ( 需要补充信息 {questionRequest.questions.map((question, index) => { const selectedAnswers = selected[index] ?? []; const isCustomEnabled = question.custom !== false; const isCustomSelected = customSelected[index] === true || (isCustomEnabled && question.options.length === 0); const setQuestionAnswers = (nextAnswers: string[]) => { setSelected((current) => ({ ...current, [index]: nextAnswers, })); }; const setQuestionCustomSelected = (checked: boolean) => { setCustomSelected((current) => ({ ...current, [index]: checked, })); }; return ( {question.header || `问题 ${index + 1}`} {question.question} {question.options.length ? ( {question.options.map((option) => { const checked = selectedAnswers.includes(option.label); if (question.multiple) { return ( { if (event.target.checked) { setQuestionAnswers([...selectedAnswers, option.label]); } else { setQuestionAnswers( selectedAnswers.filter((item) => item !== option.label), ); } }} /> } label={ {option.label} {option.description ? ( {option.description} ) : null} } sx={{ alignItems: "flex-start", m: 0 }} /> ); } return ( ); })} {isCustomEnabled ? ( question.multiple ? ( setQuestionCustomSelected(event.target.checked) } sx={{ p: 0.5, color: alpha("#0288d1", 0.55), "&.Mui-checked": { color: "#0288d1" }, }} /> } label={ 自定义回答 } sx={{ alignItems: "center", minHeight: 38, m: 0, px: 0.75, py: 0.25, borderRadius: 2, border: `1px solid ${ isCustomSelected ? "#0288d1" : alpha("#0288d1", 0.18) }`, bgcolor: isCustomSelected ? alpha("#0288d1", 0.1) : alpha("#fff", 0.45), transition: "background-color 0.18s ease, border-color 0.18s ease", "&:hover": { bgcolor: isCustomSelected ? alpha("#0288d1", 0.13) : alpha("#0288d1", 0.07), }, "& .MuiFormControlLabel-label": { color: isCustomSelected ? "#0277bd" : "text.primary", }, }} /> ) : ( ) ) : null} ) : null} setCustom((current) => ({ ...current, [index]: event.target.value, })) } placeholder="输入自定义回答" InputProps={{ disableUnderline: true, sx: { alignItems: "flex-start", fontSize: "0.88rem", lineHeight: 1.55, fontWeight: 500, color: "text.primary", "& textarea::placeholder": { color: alpha(theme.palette.text.primary, 0.38), opacity: 1, }, }, }} /> ); })} {questionRequest.status === "answered" ? ( 已回答{answerSummary ? `:${answerSummary}` : ""} ) : null} {questionRequest.status === "rejected" ? ( 已跳过 ) : null} {questionRequest.error ? ( {questionRequest.error} ) : null} {isEditable || isSubmitting ? ( ) : null} ); }; export const QuestionRequestGroup = ({ questions, onReply, onReject, }: { questions: NonNullable; onReply: (requestId: string, answers: string[][]) => void; onReject: (requestId: string) => void; }) => ( {questions.map((question) => ( ))} );