Files
Pivot/templates/admin_rechten.html
T
2026-10-14 13:34:37 +02:00

202 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}{{ u.Gebruikersnaam }} – rechten{% endblock %}
{% block page_title %}Gebruiker: {{ u.Gebruikersnaam }}{% endblock %}
{% block extra_css %}
<style>
.terug { margin-bottom: 14px; display: inline-block; }
.rechten-layout { display: grid; grid-template-columns: minmax(240px, 320px) 1fr; gap: 20px; align-items: start; }
.scholen-paneel { border: 1px solid var(--border); border-radius: var(--radius-lg, 12px); overflow: hidden;
position: sticky; top: 12px; }
.scholen-paneel .zoek { padding: 10px; border-bottom: 1px solid var(--border); background: var(--surface-muted); }
.scholen-paneel .zoek input[type=search] { width: 100%; }
.scholen-paneel .zoek label { font-size: .85rem; margin-top: 8px; display: flex; gap: 6px; align-items: center; font-weight: 400; }
.scholen-lijst { list-style: none; margin: 0; padding: 0; max-height: 62vh; overflow-y: auto; }
.scholen-lijst a { display: flex; justify-content: space-between; gap: 8px; padding: 9px 12px; text-decoration: none;
color: inherit; border-bottom: 1px solid var(--border); font-size: .92rem; }
.scholen-lijst a:hover { background: var(--primary-light); }
.scholen-lijst a.actief { background: var(--primary-light); border-left: 3px solid var(--primary-color); font-weight: 700; }
.scholen-lijst a.leeg { color: var(--text-muted, #64748b); }
.scholen-lijst .teller { white-space: nowrap; font-size: .8rem; font-weight: 600; color: var(--primary-color); }
.scholen-lijst a.leeg .teller { color: var(--text-muted, #94a3b8); font-weight: 400; }
.scholen-lijst .geen { padding: 12px; color: var(--text-muted, #64748b); font-size: .9rem; }
.school-select { display: none; margin-bottom: 14px; }
.cat { border: 1px solid var(--border); border-radius: 10px; margin-bottom: 12px; }
.cat-kop { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px;
background: var(--surface-muted); border-bottom: 1px solid var(--border); border-radius: 10px 10px 0 0; }
.cat-kop strong { color: var(--primary-color); font-size: .92rem; }
.cat-kop .knoppen button, .globaal button { padding: 2px 10px; font-size: 12px; }
.vinkjes { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 2px 16px; padding: 8px 12px; }
.vinkjes label { display: flex; gap: 8px; align-items: center; font-weight: 400; padding: 5px 0; cursor: pointer; margin: 0; }
.vinkjes input { width: 17px; height: 17px; flex: none; }
.globaal { display: flex; gap: 6px; align-items: center; }
details.ook { border: 1px dashed var(--border); border-radius: 10px; padding: 10px 12px; margin: 14px 0; }
details.ook summary { cursor: pointer; font-weight: 600; }
.ook-lijst { max-height: 260px; overflow-y: auto; margin-top: 8px; columns: 2 260px; }
.ook-lijst label { display: flex; gap: 8px; align-items: center; font-weight: 400; margin: 0; padding: 3px 0; break-inside: avoid; }
.ook-lijst input, details.ook .alle input { width: auto; }
@media (max-width: 760px) {
.rechten-layout { grid-template-columns: 1fr; }
.scholen-paneel { display: none; }
.school-select { display: block; }
}
</style>
{% endblock %}
{% block content %}
<a class="terug" href="{{ url_for('admin.settings') }}">← Alle gebruikers</a>
<div class="card">
<div class="page-head">
<h2>🔐 Rechten van {{ u.Gebruikersnaam }}</h2>
<a class="btn btn-sm btn-light" href="{{ url_for('admin.gebruiker', gid=u.Gebruiker_ID) }}">👤 Account</a>
</div>
{% if u.Veiligheidsgroep == ADMIN %}
<div class="alert alert-info">{{ u.Gebruikersnaam }} is <strong>administrator</strong> en heeft daardoor altijd alle rechten in alle scholen.
De vinkjes hieronder gelden pas als de rol ooit "Gebruiker" wordt.</div>
{% endif %}
{% if not scholen %}
<p class="muted">Je mag in geen enkele school rechten instellen.</p>
{% else %}
<div class="rechten-layout">
{# ---------- Scholen ---------- #}
<div class="scholen-paneel">
<div class="zoek">
<input type="search" id="zoekSchool" placeholder="🔍 Zoek school… ({{ scholen|length }})" oninput="filterScholen()">
<label><input type="checkbox" id="enkelMet" onchange="filterScholen()" style="width:auto"> Enkel scholen met rechten</label>
</div>
<ul class="scholen-lijst" id="scholenLijst">
{% for s in scholen %}
{% set n = aantallen.get(s.id, 0) %}
<li data-naam="{{ s.naam|lower }}" data-n="{{ n }}">
<a href="{{ url_for('admin.gebruiker_rechten', gid=u.Gebruiker_ID, school=s.id) }}"
class="{{ 'actief' if gekozen and s.id == gekozen.id else '' }} {{ 'leeg' if not n else '' }}">
<span>{{ s.naam }}{% if not s.actief %} <span class="badge badge-warning">inactief</span>{% endif %}</span>
<span class="teller">{{ n }}/{{ totaal }}</span>
</a>
</li>
{% endfor %}
<li class="geen" id="geenScholen" style="display:none">Geen scholen gevonden.</li>
</ul>
</div>
{# ---------- Rechten van de gekozen school ---------- #}
<div>
<select class="school-select" onchange="location.href=this.value" aria-label="School">
{% for s in scholen %}
<option value="{{ url_for('admin.gebruiker_rechten', gid=u.Gebruiker_ID, school=s.id) }}"
{% if gekozen and s.id == gekozen.id %}selected{% endif %}>{{ s.naam }} ({{ aantallen.get(s.id, 0) }}/{{ totaal }})</option>
{% endfor %}
</select>
{% if gekozen %}
<form method="POST" action="{{ url_for('admin.gebruiker_rechten', gid=u.Gebruiker_ID) }}" id="rechtenForm"
onsubmit="return bevestig()">
<input type="hidden" name="school_id" value="{{ gekozen.id }}">
<div class="page-head" style="margin-bottom:10px">
<h3 style="margin:0">🏫 {{ gekozen.naam }}</h3>
<div class="globaal">
<span class="muted small" id="teller"></span>
<button type="button" class="btn-light" onclick="zet(null, true)">alles</button>
<button type="button" class="btn-light" onclick="zet(null, false)">niets</button>
</div>
</div>
<p class="muted small" style="margin-top:0">Zonder vinkje in deze school kan {{ u.Gebruikersnaam }} er niet inloggen.</p>
{% for cat, items in categorieen.items() %}
<div class="cat">
<div class="cat-kop">
<strong>{{ cat }}</strong>
<span class="knoppen">
<button type="button" class="btn-light" onclick="zet('{{ loop.index }}', true)">alles</button>
<button type="button" class="btn-light" onclick="zet('{{ loop.index }}', false)">niets</button>
</span>
</div>
<div class="vinkjes">
{% set ci = loop.index %}
{% for code, naam in items %}
<label><input type="checkbox" name="r|{{ code }}" value="1" data-cat="{{ ci }}" onchange="tel()"
{% if code in huidig %}checked{% endif %}> {{ naam }}</label>
{% endfor %}
</div>
</div>
{% endfor %}
{% if scholen|length > 1 %}
<details class="ook">
<summary>📋 Deze rechten ook toepassen op andere scholen…</summary>
<p class="field-hint">De aangevinkte scholen krijgen exact dezelfde rechten als {{ gekozen.naam }}. Wat {{ u.Gebruikersnaam }} daar nu mag, wordt overschreven.</p>
<label class="alle" style="font-weight:600;display:flex;gap:8px;align-items:center">
<input type="checkbox" name="ook_alle" value="1" id="ookAlle" onchange="ookAlleWissel()"> Alle {{ scholen|length }} scholen</label>
<input type="search" placeholder="🔍 Zoek school…" oninput="filterOok(this.value)" style="margin-top:8px">
<div class="ook-lijst" id="ookLijst">
{% for s in scholen if s.id != gekozen.id %}
<label data-naam="{{ s.naam|lower }}"><input type="checkbox" name="ook" value="{{ s.id }}"> {{ s.naam }}
<span class="muted small">({{ aantallen.get(s.id, 0) }})</span></label>
{% endfor %}
</div>
</details>
{% endif %}
<button type="submit" class="btn-success">💾 Rechten opslaan</button>
</form>
{% endif %}
</div>
</div>
{% endif %}
</div>
{% endblock %}
{% block scripts %}
<script>
function vinkjes(cat) {
var sel = '#rechtenForm .vinkjes input' + (cat ? '[data-cat="' + cat + '"]' : '');
return document.querySelectorAll(sel);
}
function zet(cat, aan) { vinkjes(cat).forEach(function (cb) { cb.checked = aan; }); tel(); }
function tel() {
var t = document.getElementById('teller'); if (!t) return;
var alle = vinkjes(null), n = 0;
alle.forEach(function (cb) { if (cb.checked) n++; });
t.textContent = n + ' van ' + alle.length + ' aangevinkt';
}
function filterScholen() {
var q = document.getElementById('zoekSchool').value.trim().toLowerCase();
var enkel = document.getElementById('enkelMet').checked, zichtbaar = 0;
document.querySelectorAll('#scholenLijst li[data-naam]').forEach(function (li) {
var ok = li.dataset.naam.indexOf(q) !== -1 && (!enkel || li.dataset.n !== '0');
li.style.display = ok ? '' : 'none'; if (ok) zichtbaar++;
});
document.getElementById('geenScholen').style.display = zichtbaar ? 'none' : '';
}
function filterOok(q) {
q = q.trim().toLowerCase();
document.querySelectorAll('#ookLijst label').forEach(function (l) {
l.style.display = l.dataset.naam.indexOf(q) !== -1 ? '' : 'none';
});
}
function ookAlleWissel() {
var aan = document.getElementById('ookAlle').checked;
document.querySelectorAll('#ookLijst input').forEach(function (cb) { cb.checked = aan; cb.disabled = aan; });
}
function bevestig() {
var alle = document.getElementById('ookAlle');
var n = (alle && alle.checked) ? {{ scholen|length - 1 }} : document.querySelectorAll('#ookLijst input:checked').length;
if (!n) { if (typeof showLoader === 'function') showLoader(); return true; }
var ok = confirm('Dezelfde rechten ook instellen in ' + n + ' andere school/scholen? Wat daar nu aangevinkt is, wordt overschreven.');
if (ok && typeof showLoader === 'function') showLoader();
return ok;
}
tel();
// gekozen school in beeld scrollen
var actief = document.querySelector('#scholenLijst a.actief');
if (actief) { var l = document.getElementById('scholenLijst'); l.scrollTop = actief.parentNode.offsetTop - l.clientHeight / 2; }
</script>
{% endblock %}