/* ============================================================ ZENITH — Admin: Marking backlog Institute-wide view of every active script and its claim state. Admin can reassign a script to any teacher (which clears prior marks so the new marker starts fresh) or force-release it. ============================================================ */ function AdminBacklog() { const { lang } = useApp(); const t = (en, si) => tx(lang, en, si); const D = window.ZDATA.admin || {}; const rows = D.backlog || []; const teachers = D.teachers || []; const [, force] = useState(0); const [q, setQ] = useState(""); const [status, setStatus] = useState("all"); const [busy, setBusy] = useState(null); const [picks, setPicks] = useState({}); // attemptId -> chosen teacher accountId const refresh = async () => { await window.ZDATA_load("admin"); force(x => x + 1); }; const reassign = async r => { const teacherAccountId = picks[r.attemptId]; if (!teacherAccountId) return; setBusy(r.attemptId); try { await window.ZAPI.reassignScript(r.attemptId, teacherAccountId); await refresh(); } catch (e) { console.error("reassign failed", e); } finally { setBusy(null); } }; const release = async r => { const reason = window.prompt(t("Reason for removing this script from the teacher's marking list:", "ගුරුවරයාගේ ලකුණු ලැයිස්තුවෙන් මෙම පත්‍රය ඉවත් කිරීමට හේතුව:")); if (!reason || !reason.trim()) return; setBusy(r.attemptId); try { await window.ZAPI.releaseBacklog(r.attemptId, reason.trim()); await refresh(); } catch (e) { console.error("release failed", e); } finally { setBusy(null); } }; const counts = { available: 0, claimed: 0, completed: 0 }; rows.forEach(r => { counts[r.status] = (counts[r.status] || 0) + 1; }); const tone = s => ({ completed: "green", claimed: "amber", available: "grey" }[s] || "grey"); const label = s => s === "completed" ? t("Completed", "සම්පූර්ණයි") : s === "claimed" ? t("Claimed", "ලබාගෙන") : t("Available", "ලබාගත හැකි"); const needle = q.trim().toLowerCase(); const filtered = rows.filter(r => (status === "all" || r.status === status) && (!needle || r.sysId.toLowerCase().includes(needle) || (r.paper || "").toLowerCase().includes(needle) || (r.teacherName || "").toLowerCase().includes(needle)) ); const selStyle = { border: "1.5px solid var(--border)", borderRadius: "var(--r-sm)", padding: "7px 26px 7px 10px", fontSize: 13, outline: "none", fontFamily: "var(--font)", background: "#fff", appearance: "none", minWidth: 150 }; return (

{t("Marking list", "ලකුණු කිරීමේ ලැයිස්තුව")}

{t("Every active script and who owns it. Reassign to balance load — reassigning clears any marks entered so far.", "සෑම ක්‍රියාකාරී පත්‍රයක්ම සහ එය අයිති කවුරුන්ද. බර සමතුලනය කිරීමට නැවත පවරන්න — නැවත පැවරීම ඇතුළත් කළ ලකුණු ඉවත් කරයි.")}

{rows.length === 0 ? (

{t("No active scripts in the marking list.", "ලකුණු ලැයිස්තුවේ ක්‍රියාකාරී පත්‍ර නැත.")}

) : (
setQ(e.target.value)} placeholder={t("Search ID, paper, or teacher…", "හැඳුනුම, පත්‍රය, හෝ ගුරු සොයන්න…")} style={{ width: "100%", border: "1.5px solid var(--border)", borderRadius: "var(--r-sm)", padding: "9px 12px 9px 34px", fontSize: 13.5, outline: "none", fontFamily: "var(--font)" }} />
{[["all", t("All", "සියල්ල")], ["available", t("Available", "ලබාගත හැකි")], ["claimed", t("Claimed", "ලබාගෙන")], ["completed", t("Completed", "සම්පූර්ණයි")]].map(f => ( ))}
{filtered.map(r => ( ))}
{t("System ID", "පද්ධති හැඳුනුම")} {t("Paper", "පත්‍රය")} {t("Progress", "ප්‍රගතිය")} {t("Assigned to", "පවරා ඇත")} {t("Status", "තත්ත්වය")} {t("Reassign", "නැවත පවරන්න")}
{r.sysId} {r.paper} {r.releaseReason && r.status === "available" &&
{t("Returned:", "ආපසු:")} {r.releaseReason}
}
{r.marked}/{r.total || 6}
{r.teacherName ?
{r.teacherName}
: {t("— unassigned", "— පවරා නැත")}}
{label(r.status)}
reassign(r)}> {t("Assign", "පවරන්න")} {r.status !== "available" && ( )}
)}
); } window.AdminBacklog = AdminBacklog;