From edddf40c7ff13b1356524227217037c8ef2fcaa6 Mon Sep 17 00:00:00 2001 From: bes-r <27369668+bes-r@users.noreply.github.com> Date: Mon, 15 Jun 2026 23:32:32 +0200 Subject: [PATCH] Stage-uitbreidingen: stagelocaties, omvang per dag/dagdeel/blok, leerling uit klas op stage, conflictregel theorievak; herstel afgekapte frontend-bestanden --- ROADMAP.md | 5 +++- frontend/src/App.jsx | 65 +++++++++++++++++++++-------------------- frontend/src/pages.jsx | 32 ++++++++++++++++++-- frontend/src/styles.css | 4 +-- 4 files changed, 68 insertions(+), 38 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 15ad094..906a1ac 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -38,7 +38,10 @@ volgt. ## Vakken -- [ ] Per vak **automatisch een passend icoon** genereren of laten selecteren. +- [x] Per vak **automatisch een passend icoon** (afgeleid van de naam) — getoond + in het rooster en bij Activiteiten/vakken. + - [ ] Optioneel: een icoon handmatig kunnen kiezen/overschrijven (vereist een + `icoon`-veld op Activiteit + migratie). ## Stage-module — uitbreidingen diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 49976d4..24cb734 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -183,6 +183,38 @@ function Shell({ user, onLogout }) { ); } + // Instellingen-cog: staat in de bovenbalk (buiten de scrollende tabbalk, + // anders knipt overflow het uitklapmenu weg). + const cogMenu = instellingenTabs.length > 0 ? ( +
setCogOpen(false)}> + +
+ {instellingenTabs.map((it) => { + const pad = normaliseerPad(it.path); + return ( + + ); + })} +
+
+ ) : null; + return (
@@ -194,42 +226,11 @@ function Shell({ user, onLogout }) {
{user.username} + {cogMenu}
diff --git a/frontend/src/pages.jsx b/frontend/src/pages.jsx index f0094a5..1504e78 100644 --- a/frontend/src/pages.jsx +++ b/frontend/src/pages.jsx @@ -16,6 +16,30 @@ const ROLLEN = [ // Korte aanduiding van een medewerkersrol (compact in de roostervakjes). const ROL_AFK = { leerkracht: "LK", praktijkondersteuner: "PO", klassenondersteuner: "KO" }; + +// Automatisch een passend icoon bij een vak/activiteit op basis van de naam. +const VAK_ICONEN = [ + [/reken|wiskund|getal/i, "🔢"], + [/taal|lees|spell|begrijpend|nederlands|woordenschat/i, "📖"], + [/engels|frans|duits|spaans/i, "🗣️"], + [/gym|beweg|sport|zwem|motoriek/i, "🤸"], + [/muziek|zang/i, "🎵"], + [/teken|kunst|knutsel|creatief|handvaardig|drama/i, "🎨"], + [/pauze|speel|buiten/i, "☕"], + [/eten|lunch|fruit/i, "🍎"], + [/natuur|biolog|wereld|aardrijk|geschied/i, "🌍"], + [/koken|huishoud/i, "🍳"], + [/techniek|bouw|hout/i, "🔧"], + [/computer|digit|ict|programmeer|media/i, "💻"], + [/therap|logop|fysio|sova|sociale|gedrag/i, "💬"], + [/stage|werk|prakt/i, "🧑‍🏭"], + [/kring|start|dag|inloop/i, "⭕"], +]; +function vakIcoon(naam) { + if (!naam) return "📚"; + for (const [re, icon] of VAK_ICONEN) if (re.test(naam)) return icon; + return "📚"; +} const BOVENGROEP_LABEL = "Bovenliggende groep"; const BOVENGROEP_LABEL_LC = "bovenliggende groep"; const BOVENGROEP_LABEL_MV = "Bovenliggende groepen"; @@ -62,7 +86,7 @@ function Foutmelding({ msg }) { /* ----------------------- Generieke eenvoudige catalogus ------------------- */ // Voor lijsten met alleen naam + omschrijving (Functies, Activiteiten, Locaties). -function CatalogusPage({ titel, uitleg, resource, kleur = false, telKolom, metTheorievak = false }) { +function CatalogusPage({ titel, uitleg, resource, kleur = false, telKolom, metTheorievak = false, metIcoon = false }) { const { items, error, loading, reload, setError } = useList(resource); const leeg = { naam: "", omschrijving: "", @@ -143,6 +167,7 @@ function CatalogusPage({ titel, uitleg, resource, kleur = false, telKolom, metTh {kleur && } + {metIcoon && {vakIcoon(it.naam)} } {it.naam} {it.omschrijving || "—"} @@ -183,6 +208,7 @@ export function ActiviteitenPage() { resource="activiteiten" kleur metTheorievak + metIcoon /> ); } @@ -1874,7 +1900,7 @@ export function RoosterScherm({ mode }) { >
{edit && startDrag(e, b)} onClick={(e) => e.stopPropagation()} title="Sleep naar ander tijdslot">⠿} - {b.activiteit_naam} + {vakIcoon(b.activiteit_naam)} {b.activiteit_naam} {edit && } {edit && }
@@ -1907,7 +1933,7 @@ export function RoosterScherm({ mode }) { >
{edit && startDrag(e, b)} onClick={(e) => e.stopPropagation()} title="Sleep naar ander tijdslot">⠿} - {b.activiteit_naam} + {vakIcoon(b.activiteit_naam)} {b.activiteit_naam} {edit && } {edit && }
diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 02403d5..4cccfd4 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -26,10 +26,10 @@ body { margin: 0; font-family: system-ui, "Segoe UI", Roboto, sans-serif; color: .top-tabs-settings { display: flex; align-items: center; gap: 6px; margin-left: auto; padding-left: 10px; border-left: 1px solid var(--line); } /* Instellingen als cog-menu (popover via hover of klik) */ -.cog-menu { position: relative; margin-left: auto; } +.cog-menu { position: relative; } .cog-btn { display: inline-flex; align-items: center; min-height: 38px; background: transparent; border: 0; border-radius: 8px; padding: 0 10px; font-size: 18px; cursor: pointer; color: var(--muted); } .cog-btn:hover { background: var(--bg); color: var(--ink); } -.cog-dropdown { display: none; position: absolute; right: 0; top: 100%; margin-top: 4px; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.15); min-width: 200px; padding: 6px; z-index: 50; } +.cog-dropdown { display: none; position: absolute; right: 0; top: 100%; margin-top: 4px; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.15); min-width: 200px; padding: 6px; z-index: 60; } .cog-menu:hover .cog-dropdown, .cog-menu.open .cog-dropdown { display: block; } .cog-item { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; background: transparent; border: 0; border-radius: 8px; padding: 9px 10px; cursor: pointer; font: inherit; color: var(--ink); } .cog-item:hover { background: var(--bg); }