feat: made stuff
This commit is contained in:
@@ -8,6 +8,8 @@ type Student = {
|
||||
};
|
||||
type Promo = { id: string; annee: string };
|
||||
type Module = { id: string; nom: string };
|
||||
type Mobilite = { id: number; duree: number; status: string };
|
||||
type Stage = { id: number; duree: number };
|
||||
|
||||
type Props = { numEtud: number };
|
||||
|
||||
@@ -25,6 +27,8 @@ export default function EditStudents({ numEtud }: Props) {
|
||||
const [student, setStudent] = useState<Student | null>(null);
|
||||
const [promos, setPromos] = useState<Promo[]>([]);
|
||||
const [_modules, setModules] = useState<Module[]>([]);
|
||||
const [mobWeeks, setMobWeeks] = useState(0);
|
||||
const [stageWeeks, setStageWeeks] = useState(0);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [saveMsg, setSaveMsg] = useState<string | null>(null);
|
||||
@@ -38,10 +42,12 @@ export default function EditStudents({ numEtud }: Props) {
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
try {
|
||||
const [sRes, pRes, mRes] = await Promise.all([
|
||||
const [sRes, pRes, mRes, mobRes, stRes] = await Promise.all([
|
||||
fetch(`/students/api/students/${numEtud}`),
|
||||
fetch("/students/api/promotions"),
|
||||
fetch("/admin/api/modules"),
|
||||
fetch("/notes/api/modules"),
|
||||
fetch(`/mobility/api/mobilites?numEtud=${numEtud}`),
|
||||
fetch(`/stages/api/stages?numEtud=${numEtud}`),
|
||||
]);
|
||||
if (!sRes.ok) throw new Error("Élève introuvable");
|
||||
const s: Student = await sRes.json();
|
||||
@@ -51,6 +57,19 @@ export default function EditStudents({ numEtud }: Props) {
|
||||
setIdPromo(s.idPromo);
|
||||
if (pRes.ok) setPromos(await pRes.json());
|
||||
if (mRes.ok) setModules(await mRes.json());
|
||||
if (mobRes.ok) {
|
||||
const mobs: Mobilite[] = await mobRes.json();
|
||||
setMobWeeks(
|
||||
mobs.filter((m) => m.status === "validated").reduce(
|
||||
(s, m) => s + m.duree,
|
||||
0,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (stRes.ok) {
|
||||
const stages: Stage[] = await stRes.json();
|
||||
setStageWeeks(stages.reduce((s, st) => s + st.duree, 0));
|
||||
}
|
||||
} catch (e) {
|
||||
setError(e instanceof Error ? e.message : "Erreur");
|
||||
} finally {
|
||||
@@ -207,30 +226,69 @@ export default function EditStudents({ numEtud }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Section 2: Spécialisations */}
|
||||
{/* Section 2: Notes */}
|
||||
<div class="edit-section">
|
||||
<p class="edit-section-title">Spécialisations</p>
|
||||
<p
|
||||
class="state-empty"
|
||||
style="padding: 1rem 0; text-align: left"
|
||||
>
|
||||
Fonctionnalité non disponible (endpoint non implémenté).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Section 3: Notes lecture seule */}
|
||||
<div class="edit-section">
|
||||
<p class="edit-section-title">Notes (lecture seule)</p>
|
||||
<p class="edit-section-title">Notes</p>
|
||||
<div style="display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap">
|
||||
<span class="col-dim" style="font-size: 0.82rem">
|
||||
Voir le récap complet des notes et moyennes de cet étudiant →
|
||||
Récap complet des notes et moyennes
|
||||
</span>
|
||||
<a
|
||||
class="btn btn-secondary"
|
||||
href={`/notes/recap/${numEtud}`}
|
||||
f-client-nav={false}
|
||||
>
|
||||
Récap notes
|
||||
Voir les notes
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Section 3: Mobilités */}
|
||||
<div class="edit-section">
|
||||
<p class="edit-section-title">Mobilités</p>
|
||||
<div style="display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap">
|
||||
<span style="display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap">
|
||||
<span
|
||||
style={{
|
||||
fontFamily: "monospace",
|
||||
fontWeight: "var(--font-weight-bold)",
|
||||
color: mobWeeks >= 12 ? "#22c55e" : "#dc2626",
|
||||
}}
|
||||
>
|
||||
{mobWeeks}/12 semaines validées
|
||||
</span>
|
||||
</span>
|
||||
<a
|
||||
class="btn btn-secondary"
|
||||
href={`/mobility/overview/${numEtud}`}
|
||||
f-client-nav={false}
|
||||
>
|
||||
Consulter
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Section 4: Stages */}
|
||||
<div class="edit-section">
|
||||
<p class="edit-section-title">Stages</p>
|
||||
<div style="display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap">
|
||||
<span style="display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap">
|
||||
<span
|
||||
style={{
|
||||
fontFamily: "monospace",
|
||||
fontWeight: "var(--font-weight-bold)",
|
||||
color: stageWeeks >= 40 ? "#22c55e" : "#dc2626",
|
||||
}}
|
||||
>
|
||||
{stageWeeks}/40 semaines
|
||||
</span>
|
||||
</span>
|
||||
<a
|
||||
class="btn btn-secondary"
|
||||
href={`/stages/overview/${numEtud}`}
|
||||
f-client-nav={false}
|
||||
>
|
||||
Consulter
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user