import { useEffect, useState } from "preact/hooks"; type Student = { numEtud: number; nom: string; prenom: string; idPromo: string; }; type Promo = { id: string; annee: string }; type Module = { id: string; nom: string }; type Props = { numEtud: number }; function anneeLabel(idPromo: string): string { const m = idPromo.match(/^(\d+)A/); if (!m) return ""; const n = m[1]; if (n === "3") return "3ème année"; if (n === "4") return "4ème année"; if (n === "5") return "5ème année"; return `${n}ème année`; } export default function EditStudents({ numEtud }: Props) { const [student, setStudent] = useState(null); const [promos, setPromos] = useState([]); const [_modules, setModules] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [saveMsg, setSaveMsg] = useState(null); const [saving, setSaving] = useState(false); // Edit form state const [nom, setNom] = useState(""); const [prenom, setPrenom] = useState(""); const [idPromo, setIdPromo] = useState(""); useEffect(() => { async function load() { try { const [sRes, pRes, mRes] = await Promise.all([ fetch(`/students/api/students/${numEtud}`), fetch("/students/api/promotions"), fetch("/admin/api/modules"), ]); if (!sRes.ok) throw new Error("Élève introuvable"); const s: Student = await sRes.json(); setStudent(s); setNom(s.nom); setPrenom(s.prenom); setIdPromo(s.idPromo); if (pRes.ok) setPromos(await pRes.json()); if (mRes.ok) setModules(await mRes.json()); } catch (e) { setError(e instanceof Error ? e.message : "Erreur"); } finally { setLoading(false); } } load(); }, [numEtud]); async function saveInfos() { if (!student) return; setSaving(true); setSaveMsg(null); try { const res = await fetch(`/students/api/students/${numEtud}`, { method: "PUT", headers: { "content-type": "application/json" }, body: JSON.stringify({ nom: nom.trim(), prenom: prenom.trim(), idPromo, }), }); if (!res.ok) throw new Error("Modification échouée"); const updated: Student = await res.json(); setStudent(updated); setSaveMsg("Informations enregistrées."); } catch (e) { setError(e instanceof Error ? e.message : "Erreur"); } finally { setSaving(false); } } async function deleteStudent() { if (!confirm(`Supprimer définitivement l'élève #${numEtud} ?`)) return; try { const res = await fetch(`/students/api/students/${numEtud}`, { method: "DELETE", }); if (!res.ok) throw new Error("Suppression échouée"); globalThis.location.href = "/students/consult"; } catch (e) { setError(e instanceof Error ? e.message : "Erreur"); } } if (loading) { return (

Chargement…

); } if (error && !student) { return (

{error}

); } if (!student) return null; return (
← Retour à la liste

Édition – {student.prenom} {student.nom}

{/* Info bar */}
{student.numEtud} {student.idPromo} {anneeLabel(student.idPromo)}
{error &&

{error}

} {saveMsg && (

{saveMsg}

)} {/* Section 1: Informations générales */}

Informations générales

PUT /students/{"{numEtud}"}

setNom((e.target as HTMLInputElement).value)} />
setPrenom((e.target as HTMLInputElement).value)} />
{/* Section 2: Spécialisations */}

Spécialisations

GET·POST·DELETE /spe5a – plusieurs modules possibles

Fonctionnalité non disponible (endpoint non implémenté).

{/* Section 3: Notes lecture seule */}

Notes (lecture seule)

GET /students/{"{numEtud}"}/notes – voir récap complet

Voir le récap complet des notes et moyennes de cet étudiant → Récap notes
); }