import { useState } from "react"; import { useParams } from "react-router-dom"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Checkbox } from "@/components/ui/checkbox"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { useIeltsValidation, useSubmitExaminerReview } from "@/hooks/queries/useAiCourse"; import type { ExaminerReviewItem } from "@/types"; import { CheckCircle2, XCircle } from "lucide-react"; import { toast } from "sonner"; export default function AiIeltsValidation() { const { courseId: cid } = useParams<{ courseId: string }>(); const courseId = Number(cid); const { data, isLoading, refetch } = useIeltsValidation(Number.isFinite(courseId) ? courseId : undefined); const submitReview = useSubmitExaminerReview(); const [preview, setPreview] = useState(null); const [notes, setNotes] = useState(""); const [checklist, setChecklist] = useState({ topic_accuracy: true, difficulty_appropriate: true, ielts_aligned: true, culturally_sensitive: true, }); const layer1 = data?.layer1_checks ?? []; const layer2 = data?.layer2_items ?? []; const send = (approved: boolean) => { if (!preview) return; submitReview.mutate({ logId: preview.id, action: approved ? "approve" : "reject", examiner_notes: approved ? undefined : notes, }, { onSuccess: () => { toast.success(approved ? "Approved." : "Rejected with notes."); setPreview(null); setNotes(""); refetch(); }, onError: (e) => toast.error(e instanceof Error ? e.message : "Failed"), }); }; if (isLoading) { return
Loading validation…
; } return (

IELTS content validation

Layer 1 automation · Layer 2 examiner queue

Layer 1 — Automated checks Format, calibration, answer keys
Check Status Detail {layer1.map((c) => ( {c.name} {c.status === "pass" ? ( ) : ( )} {c.status} {c.detail} ))}
Layer 2 — Examiner review queue Approve or reject with structured notes
Skill Content type Target band Status Action {layer2.map((item) => ( {item.skill} {item.content_type} {item.target_band} {item.status} ))}
!o && setPreview(null)}> Content preview {preview && (

Skill: {preview.skill} ·{" "} Type: {preview.content_type} ·{" "} Band: {preview.target_band}

Full content preview loads here from the authoring pipeline.
{( [ ["topic_accuracy", "Accuracy"], ["difficulty_appropriate", "Difficulty"], ["ielts_aligned", "IELTS alignment"], ["culturally_sensitive", "Cultural sensitivity"], ] as const ).map(([key, label]) => (
setChecklist((prev) => ({ ...prev, [key]: !!c }))} />
))}