"use client"; import { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { adminGet, adminSend, type AdminSemester } from "@/lib/admin-api"; export default function AdminSemestersPage() { const { t } = useTranslation(); const [semesters, setSemesters] = useState([]); const [loading, setLoading] = useState(true); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const [notice, setNotice] = useState(null); const [year, setYear] = useState(new Date().getFullYear()); const [type, setType] = useState<"winter" | "summer">("winter"); const [expandedId, setExpandedId] = useState(null); const refresh = useCallback(async () => { setLoading(true); setError(null); try { setSemesters(await adminGet("/api/admin/semesters")); } catch (e) { setError(e instanceof Error ? e.message : String(e)); } finally { setLoading(false); } }, []); useEffect(() => { void refresh(); }, [refresh]); async function create() { setBusy(true); setError(null); setNotice(null); try { const result = await adminSend("/api/admin/semesters", "POST", { Year: year, Type: type }); setNotice(result.message ?? null); await refresh(); } catch (e) { setError(e instanceof Error ? e.message : String(e)); } finally { setBusy(false); } } return (

{t("admin_semesters")}

{t("admin_semesters_intro")}

{error && (
{error}
)} {notice && (
{notice}
)}

{t("admin_new_semester")}

{t("admin_open_semesters")}

{loading ? ( ) : semesters.length === 0 ? ( ) : ( semesters.map((s) => { const uncovered = s.uncoveredSubjects.length; return ( <> {expandedId === s.id && uncovered > 0 && ( )} ); }) )}
{t("semester")} {t("admin_enrolments")} {t("admin_coverage")} {t("actions")}
{t("loading")}
{t("admin_no_semesters")}
{s.name} {s.enrolmentCount} {uncovered === 0 ? ( {t("admin_fully_covered")} ) : ( {t("admin_uncovered_count", { count: uncovered })} )} {uncovered > 0 && ( )}

{t("admin_uncovered_hint")}

    {s.uncoveredSubjects.map((u) => (
  • {u.code} — {u.name}
  • ))}
); }