From 958ace1536acbe1287be618631c3131a6aa5b864 Mon Sep 17 00:00:00 2001 From: bes-r <27369668+bes-r@users.noreply.github.com> Date: Sat, 4 Jul 2026 23:23:58 +0200 Subject: [PATCH] Improve schedule UI clarity --- frontend/src/App.jsx | 27 ++++++++++++--- frontend/src/pages.jsx | 49 ++++++++++++++------------ frontend/src/styles.css | 76 ++++++++++++++++++++++++++--------------- 3 files changed, 100 insertions(+), 52 deletions(-) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 34d44dd..2fdfd5f 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -23,6 +23,22 @@ const GROEP_ICON = { Rooster: "calendar", Organisatie: "users", Overzicht: "cloc const GROEPSINDELING_PADEN = new Set(["/groepsindeling", "/structuur", "/leerplein", "/groepen", "/subgroepen"]); const GROEPSINDELING_ITEM = { label: "Groepsindeling", path: "/groepsindeling", icon: "layers", order: 24, group: "Organisatie" }; const normaliseerPad = (path) => (GROEPSINDELING_PADEN.has(path) ? "/groepsindeling" : path); +const ROLE_NAV = { + roostermaker: new Set(["/rooster", "/perioderooster", "/roostermaker", "/vervanging", "/afwezigheid", "/auto-rooster", "/vak-wizard"]), + directie: null, + zorgcoordinator: new Set(["/rooster", "/groepsindeling", "/personen", "/afwezigheid", "/stage", "/uren", "/portaal"]), + stagebegeleider: new Set(["/rooster", "/stage", "/afwezigheid", "/portaal"]), + medewerker: new Set(["/rooster", "/groepsindeling", "/afwezigheid", "/stage", "/uren", "/portaal"]), + kijker: new Set(["/rooster", "/uren", "/portaal"]), + ouder: new Set(["/portaal", "/ouderrooster"]), + leerling: new Set(["/portaal", "/leerlingrooster"]), +}; +function magMenuZien(user, item) { + if (user.is_staff || user.role === "beheerder" || user.role === "directie") return true; + const allowed = ROLE_NAV[user.role]; + if (!allowed) return true; + return allowed.has(normaliseerPad(item.path)); +} // Koppel een menu-pad aan een echt scherm. Onbekende paden tonen een // placeholder (worden in een latere fase ingevuld). @@ -261,16 +277,19 @@ function Shell({ user, onLogout }) { if (isBeheerder) { voegToe({ label: "Modulebeheer", path: "/modules", icon: "gear", order: 9999, group: "Instellingen" }); } - const items = [...perPad.values()]; + const items = [...perPad.values()].filter((item) => magMenuZien(user, item)); items.sort((a, b) => a.order - b.order); return { tabs: items.filter((i) => i.group !== "Instellingen"), instellingenTabs: items.filter((i) => i.group === "Instellingen"), alleItems: items, }; - }, [modules, user.is_staff, user.role]); + }, [modules, user]); - const activePad = normaliseerPad(active); + const eerstePad = alleItems[0]?.path || "/rooster"; + const activePad = normaliseerPad( + [...alleItems].some((item) => normaliseerPad(item.path) === normaliseerPad(active)) ? active : eerstePad + ); const Page = PAGES[activePad]; // Groepeer de hoofdtabs: groepen met meerdere items worden een dropdown, @@ -391,7 +410,7 @@ function Shell({ user, onLogout }) { -
+
{error &&
⚠ {error}
} {loading ? (

Laden…

diff --git a/frontend/src/pages.jsx b/frontend/src/pages.jsx index 2db0958..81a1528 100644 --- a/frontend/src/pages.jsx +++ b/frontend/src/pages.jsx @@ -2087,6 +2087,8 @@ export function RoosterScherm({ mode }) { const setWeergave = (v) => { setWeergaveState(v); try { localStorage.setItem("rw_weergave", v); } catch { /* niet beschikbaar */ } }; const [vakkleurVlak, setVakkleurState] = useState(() => { try { return localStorage.getItem("rw_vakkleur") === "vlak"; } catch { return false; } }); const setVakkleur = (v) => { setVakkleurState(v); try { localStorage.setItem("rw_vakkleur", v ? "vlak" : "streep"); } catch { /* niet beschikbaar */ } }; + const [detailsOpen, setDetailsOpenState] = useState(() => { try { return localStorage.getItem("rw_rooster_details") === "1"; } catch { return false; } }); + const setDetailsOpen = (v) => { setDetailsOpenState(v); try { localStorage.setItem("rw_rooster_details", v ? "1" : "0"); } catch { /* niet beschikbaar */ } }; // Printopties const [printOpen, setPrintOpen] = useState(false); const [printPending, setPrintPending] = useState(false); @@ -2409,7 +2411,7 @@ export function RoosterScherm({ mode }) { {edit && } {edit && } - {(b.locatie_naam || b.lokaal_naam || b.begeleiders_namen.length > 0) && ( + {(edit || detailsOpen) && (b.locatie_naam || b.lokaal_naam || b.begeleiders_namen.length > 0) && (
{b.locatie_naam && 📍 {b.locatie_naam}} {b.lokaal_naam && 🚪 {b.lokaal_naam}} @@ -2420,7 +2422,7 @@ export function RoosterScherm({ mode }) { )}
)} - {stageNoot(b)} + {(edit || detailsOpen) && stageNoot(b)} {kal &&
Vervalt — {kal.type_label}
} {!kal && uit && uit.vervalt &&
Vervalt {uit.opmerking ? `(${uit.opmerking})` : ""}{edit && }
} {!kal && uit && !uit.vervalt && uit.vervanger_naam &&
Vervanger: {uit.vervanger_naam}
} @@ -2533,7 +2535,7 @@ export function RoosterScherm({ mode }) { } return ( -
+
@@ -2541,18 +2543,19 @@ export function RoosterScherm({ mode }) { {(schooljaren.find((j) => String(j.id) === String(schooljaar)) || {}).naam || ""}{schooljaar ? " · " : ""}{schooljaar ? weekTitel(maandag) : ""} · afgedrukt {fmtDM(new Date())}
-
-

{edit ? "Roostermaker" : "Rooster"}

+
+
+

{edit ? "Roostermaker" : "Rooster"}

+
+ {schooljaar ? `${weekTitel(maandag)} · ${zichtbareBlokken.length} blokken zichtbaar` : "Kies een schooljaar"} + {conflictInfo.meldingen.length > 0 ? ` · ${conflictInfo.meldingen.length} conflicten` : ""} +
+
-

- {edit - ? "Sleep een blok naar een ander tijdslot om het te verplaatsen. Vrije dagen, afwezigheid en uitzonderingen worden meegenomen." - : "Bekijk het weekrooster. Vrije dagen, afwezigheid en uitzonderingen zijn verwerkt."} -

-
+