/* ================================================================== Test picker modal — shown when user opens "Paper Evaluation" from sidebar ================================================================== */ const { Icon: TPIcon, StatusPill: TPStatusPill } = window.AppUI; const TestPickerModal = ({ open, onClose, onPick }) => { const [search, setSearch] = React.useState(""); const [classFilter, setClassFilter] = React.useState("All"); const [subjectFilter, setSubjectFilter] = React.useState("All"); if (!open) return null; // Only tests that can be evaluated — those with structured questions and uploaded scripts const candidates = window.APP.TESTS.filter(t => t.status === "grading" || t.status === "optimised" || t.status === "closed"); const filtered = candidates.filter(t => { if (classFilter !== "All" && t.className !== classFilter) return false; if (subjectFilter !== "All" && t.subject !== subjectFilter) return false; if (search && !t.title.toLowerCase().includes(search.toLowerCase()) && !t.id.toLowerCase().includes(search.toLowerCase())) return false; return true; }); const recent = filtered.slice(0, 3); const rest = filtered.slice(3); return (
e.stopPropagation()} style={{ background:"var(--bg-1)", border:"1px solid var(--line-strong)", borderRadius: 10, width: 780, maxWidth:"100%", maxHeight:"86vh", display:"flex", flexDirection:"column" }}>
Open Paper Evaluation
Pick a test to evaluate · only structured & uploaded tests are listed.
setSearch(e.target.value)} style={{ paddingLeft: 28, padding: "6px 10px 6px 28px", fontSize: 12.5 }}/>
{recent.length > 0 && ( <>
Recent · in active grading
{recent.map(t => )}
)} {rest.length > 0 && ( <>
All tests · {rest.length}
{rest.map(t => )}
)} {filtered.length === 0 && (
No matching tests. Try widening the filters or upload scripts to a test first.
)}
↑ ↓ to move · Enter to open · Esc to cancel {filtered.length} match{filtered.length === 1 ? "" : "es"}
); }; const TestPickerRow = ({ test, onPick, primary }) => { const pct = test.students ? Math.round(test.reviewed / test.students * 100) : 0; const pending = test.students - test.reviewed; return (
onPick(test)} onMouseEnter={(e) => { e.currentTarget.style.background = "var(--bg-2)"; e.currentTarget.style.borderColor = "var(--accent)"; }} onMouseLeave={(e) => { e.currentTarget.style.background = primary ? "var(--bg-2)" : "transparent"; e.currentTarget.style.borderColor = "var(--line)"; }} style={{ display:"grid", gridTemplateColumns:"60px 1fr 100px 110px 100px", gap: 12, alignItems:"center", padding: primary ? "12px 14px" : "10px 12px", background: primary ? "var(--bg-2)" : "transparent", border:"1px solid var(--line)", borderRadius: 6, cursor:"pointer", transition:"background 0.12s, border-color 0.12s", }}> {test.id}
{test.title}
{test.className} · {test.subject} · {test.chapter}
{test.reviewed}/{test.students} · {pending > 0 ? `${pending} pending` : "complete"}
); }; window.TestPickerModal = TestPickerModal;