duoqi-admin/src/components/question/StatusTransitionDialog.tsx
Wang Zhuoxuan a5025e633e feat: 完善题目状态流转 UI(Phase 1b)
- 新建 StatusTransitionDialog 确认对话框,显示流转方向和操作说明
- 状态列增加快速操作按钮(主流转),下拉菜单保留全部流转路径
- 新增 TRANSITION_LABELS 常量定义各状态的流转动作标签
2026-04-07 23:20:16 +08:00

75 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog"
import { StatusBadge } from "@/components/question/StatusBadge"
import { TRANSITION_LABELS } from "@/lib/constants"
import type { Question, QuestionStatus } from "@/types/question"
interface StatusTransitionDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
question: Question | null
targetStatus: QuestionStatus | null
onConfirm: () => void
}
export function StatusTransitionDialog({
open,
onOpenChange,
question,
targetStatus,
onConfirm,
}: StatusTransitionDialogProps) {
if (!question || !targetStatus) return null
const label = TRANSITION_LABELS[targetStatus]
const description = getDescription(question.status, targetStatus)
return (
<AlertDialog open={open} onOpenChange={onOpenChange}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{label.title}</AlertDialogTitle>
<AlertDialogDescription asChild>
<div className="space-y-3">
<p>{description}</p>
<div className="flex items-center gap-2">
<StatusBadge status={question.status} />
<span className="text-muted-foreground"></span>
<StatusBadge status={targetStatus} />
</div>
<p className="text-xs text-muted-foreground">
{question.stem.length > 40 ? question.stem.slice(0, 40) + "..." : question.stem}
</p>
</div>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction onClick={onConfirm}>
{label.action}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)
}
function getDescription(from: QuestionStatus, to: QuestionStatus): string {
const descriptions: Record<string, string> = {
"draft→reviewing": "提交后题目将进入审核队列,等待审核通过后才能发布。",
"reviewing→published": "审核通过后题目将对所有用户可见,请确认题目内容无误。",
"reviewing→draft": "将题目退回草稿状态,可以继续修改后重新提交。",
"published→archived": "下架后题目将对用户不可见,但数据会保留。可随时恢复为草稿。",
"archived→draft": "恢复为草稿后可以重新编辑并提交审核。",
}
return descriptions[`${from}${to}`] ?? `确定要将题目状态从「${from}」改为「${to}」吗?`
}