Roostermaker: rol begeleider zichtbaar (LK/PO/KO) en sneltoetsen (N/pijltjes/T/Esc)
This commit is contained in:
parent
e1ada6d702
commit
5adddb03c1
3 changed files with 32 additions and 7 deletions
|
|
@ -15,10 +15,10 @@ volgt.
|
|||
- [x] Vanuit de Roostermaker (tab **Indeling**) direct **subgroepen aanmaken**
|
||||
onder een hoofdgroep, met verantwoordelijke(n) — kolomsgewijs overzicht
|
||||
van subgroepen, vakken en wie verantwoordelijk is.
|
||||
- [ ] **Sneltoetsen** voor veelgebruikte acties (bv. nieuw blok, kopiëren,
|
||||
verwijderen, week vooruit/terug, opslaan).
|
||||
- [ ] **Rol van een begeleider beter zichtbaar** in de roostermaker (bv. functie/
|
||||
rol tonen bij de begeleider in een blok en bij het toewijzen).
|
||||
- [x] **Sneltoetsen** in de Roostermaker: N (nieuw blok), ←/→ (week terug/vooruit),
|
||||
T (deze week), Esc (paneel/sluiten); met hint.
|
||||
- [x] **Rol van een begeleider zichtbaar** in de Roostermaker: afkorting (LK/PO/KO)
|
||||
bij de begeleider in een blok en de volledige rol bij het toewijzen.
|
||||
- [ ] **Vereenvoudigd vak/blok toevoegen** — bijvoorbeeld een **stap-voor-stap
|
||||
wizard** die meeschuift (activiteit → doelgroep → personeel → tijd), in
|
||||
plaats van één groot formulier.
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ const ROLLEN = [
|
|||
{ value: "klassenondersteuner", label: "Klassenondersteuner" },
|
||||
];
|
||||
|
||||
// Korte aanduiding van een medewerkersrol (compact in de roostervakjes).
|
||||
const ROL_AFK = { leerkracht: "LK", praktijkondersteuner: "PO", klassenondersteuner: "KO" };
|
||||
|
||||
const WEEKDAGEN = [
|
||||
{ value: 0, label: "Maandag" },
|
||||
{ value: 1, label: "Dinsdag" },
|
||||
|
|
@ -1315,7 +1318,7 @@ function BlokBewerker({ blok, ctx, onSluit, onKlaar }) {
|
|||
<div className="leden-keuze">
|
||||
<div className="muted small">Begeleiders:</div>
|
||||
<div className="chips">
|
||||
{medewerkers.map((m) => <button type="button" key={m.id} className={f.begeleiders.includes(m.id) ? "chip on" : "chip"} onClick={() => toggleBeg(m.id)}>{m.volledige_naam}</button>)}
|
||||
{medewerkers.map((m) => <button type="button" key={m.id} className={f.begeleiders.includes(m.id) ? "chip on" : "chip"} onClick={() => toggleBeg(m.id)}>{m.volledige_naam}{m.rol_label ? ` · ${m.rol_label}` : ""}</button>)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row"><input placeholder="Opmerking" value={f.opmerkingen} onChange={(e) => setF({ ...f, opmerkingen: e.target.value })} /></div>
|
||||
|
|
@ -1540,6 +1543,23 @@ export function RoosterScherm({ mode }) {
|
|||
return () => { window.removeEventListener("pointermove", move); window.removeEventListener("pointerup", up); };
|
||||
}, []);
|
||||
|
||||
// Sneltoetsen (alleen in de Roostermaker).
|
||||
useEffect(() => {
|
||||
if (!edit) return;
|
||||
function onKey(e) {
|
||||
const t = e.target;
|
||||
const typing = t && (t.tagName === "INPUT" || t.tagName === "SELECT" || t.tagName === "TEXTAREA" || t.isContentEditable);
|
||||
if (e.key === "Escape") { setBewerkBlok(null); setToonForm(false); return; }
|
||||
if (typing) return;
|
||||
if (e.key === "n" || e.key === "N") { setTab("week"); setToonForm((v) => !v); }
|
||||
else if (e.key === "ArrowLeft") { setMaandag((m) => plusDagen(m, -7)); }
|
||||
else if (e.key === "ArrowRight") { setMaandag((m) => plusDagen(m, 7)); }
|
||||
else if (e.key === "t" || e.key === "T") { setMaandag(maandagVan(new Date())); }
|
||||
}
|
||||
window.addEventListener("keydown", onKey);
|
||||
return () => window.removeEventListener("keydown", onKey);
|
||||
}, [edit]);
|
||||
|
||||
function startDrag(e, blok) {
|
||||
e.preventDefault();
|
||||
dragRef.current = blok;
|
||||
|
|
@ -1581,6 +1601,7 @@ export function RoosterScherm({ mode }) {
|
|||
const uitzOp = (blokId, iso) => uitzonderingen.find((u) => u.roosterblok === blokId && u.datum === iso);
|
||||
// Op id vergelijken, niet op naam: twee personen kunnen dezelfde naam hebben.
|
||||
const persoonAfwezig = (id, iso) => afwezig.some((a) => a.persoon === id && a.start_datum <= iso && a.eind_datum >= iso);
|
||||
const rolAfk = (id) => { const m = medewerkers.find((x) => x.id === id); return m ? (ROL_AFK[m.rol] || "") : ""; };
|
||||
|
||||
return (
|
||||
<section className="rooster-scherm">
|
||||
|
|
@ -1642,6 +1663,9 @@ export function RoosterScherm({ mode }) {
|
|||
<button className={tab === "instellingen" ? "tab on" : "tab"} onClick={() => setTab("instellingen")}>Instellingen</button>
|
||||
</div>
|
||||
)}
|
||||
{edit && tab === "week" && (
|
||||
<p className="muted small no-print sneltoets-hint">Sneltoetsen: <b>N</b> nieuw blok · <b>←</b>/<b>→</b> week · <b>T</b> deze week · <b>Esc</b> sluiten</p>
|
||||
)}
|
||||
|
||||
{edit && schooljaar && tab === "week" && toonForm && (
|
||||
<form className="form-card no-print" onSubmit={opslaan}>
|
||||
|
|
@ -1673,7 +1697,7 @@ export function RoosterScherm({ mode }) {
|
|||
<div className="leden-keuze">
|
||||
<div className="muted small">Begeleiders:</div>
|
||||
<div className="chips">
|
||||
{medewerkers.map((m) => <button type="button" key={m.id} className={form.begeleiders.includes(m.id) ? "chip on" : "chip"} onClick={() => toggleBegeleider(m.id)}>{m.volledige_naam}</button>)}
|
||||
{medewerkers.map((m) => <button type="button" key={m.id} className={form.begeleiders.includes(m.id) ? "chip on" : "chip"} onClick={() => toggleBegeleider(m.id)}>{m.volledige_naam}{m.rol_label ? ` · ${m.rol_label}` : ""}</button>)}
|
||||
{medewerkers.length === 0 && <span className="muted small">Nog geen medewerkers.</span>}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1731,7 +1755,7 @@ export function RoosterScherm({ mode }) {
|
|||
{b.locatie_naam && <div className="small">📍 {b.locatie_naam}</div>}
|
||||
{b.begeleiders_namen.length > 0 && (
|
||||
<div className="small muted">👤 {b.begeleiders_namen.map((x, idx) => (
|
||||
<span key={x.id} className={persoonAfwezig(x.id, iso) ? "afwezig" : ""}>{idx > 0 ? ", " : ""}{x.naam}</span>
|
||||
<span key={x.id} className={persoonAfwezig(x.id, iso) ? "afwezig" : ""}>{idx > 0 ? ", " : ""}{x.naam}{rolAfk(x.id) ? ` (${rolAfk(x.id)})` : ""}</span>
|
||||
))}</div>
|
||||
)}
|
||||
{kal && <div className="small rb-status">Vervalt — {kal.type_label}</div>}
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ input[type="color"] { padding: 2px; width: 44px; min-width: 44px; height: 38px;
|
|||
.drag-ghost { position: fixed; z-index: 1000; pointer-events: none; background: var(--brand); color: #fff; padding: 6px 12px; border-radius: 8px; font-size: 13px; font-weight: 600; box-shadow: 0 6px 18px rgba(0,0,0,.25); }
|
||||
|
||||
.dag-actie { display: block; margin-top: 4px; font-size: 11px; }
|
||||
.sneltoets-hint { margin: -4px 0 12px; }
|
||||
|
||||
/* --- Groepsindeling --- */
|
||||
.indeling { margin-top: 12px; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue