Files
Pivot/templates/smartschool_beheer.html
T
2026-10-14 12:29:29 +02:00

181 lines
7.8 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 %}Smartschool beheer{% endblock %}
{% block page_title %}Smartschool beheer{% endblock %}
{% block main_class %}medium{% endblock %}
{% block extra_css %}
<style>
#coAccountModal { z-index: 3000; }
#passwordModal { z-index: 4000; } /* reset-venster altijd bovenop de co-accountlijst */
</style>
{% endblock %}
{% block content %}
<div class="card">
<div class="page-head"><h2>🏫 Wachtwoord &amp; info</h2></div>
<form class="search-bar" method="POST" action="{{ url_for('/ss.smartschool') }}" onsubmit="showLoader()">
<input type="text" name="query" placeholder="Zoek op naam, voornaam, gebruikersnaam of internnummer..." value="{{ query or '' }}">
<button type="submit" class="btn-search">🔍 Zoeken</button>
</form>
{% if results %}
<div class="table-wrap">
<table>
<thead>
<tr>
<th>Internnummer</th>
<th>Naam</th>
<th>Gebruikersnaam</th>
<th class="actions">Acties</th>
</tr>
</thead>
<tbody>
{% for user in results %}
<tr>
<td><strong>{{ user.internnummer }}</strong></td>
<td>{{ user.voornaam }} {{ user.naam }}</td>
<td>{{ user.gebruikersnaam }}</td>
<td class="actions">
<button type="button" class="btn-danger btn-sm" onclick="openResetModal('{{ user.internnummer }}', '{{ user.voornaam }} {{ user.naam }}', 0)">🔑 Reset WW</button>
<button type="button" class="btn-secondary btn-sm" onclick="viewCoAccounts('{{ user.gebruikersnaam }}')">👪 Co-accounts</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% elif query %}
<p class="muted">Geen resultaten gevonden voor "{{ query }}".</p>
<p class="muted small">Op een deel van een naam zoekt PIVOT in de leerlingenlijst. Staat die nog leeg,
haal dan eerst de leerlingen op via Leerlingen › Informat &amp; SS sync, of zoek op het volledige internnummer of de gebruikersnaam.</p>
{% endif %}
</div>
{% endblock %}
{% block modals %}
<div id="passwordModal" class="modal-overlay">
<div class="modal-content">
<span class="close" onclick="closeModal('passwordModal')">&times;</span>
<h3>Wachtwoord reset</h3>
<p id="displayUser" style="font-weight:600; color: var(--primary-color);"></p>
<div class="field">
<label for="modalPasswordInput">Nieuw wachtwoord</label>
<div class="input-group">
<input type="text" id="modalPasswordInput" placeholder="Nieuw wachtwoord">
<button type="button" class="btn-light" title="Willekeurig genereren" onclick="generateRandomPass()">🎲</button>
</div>
</div>
<label class="check-box">
<input type="checkbox" id="pdfCheckbox"> PDF genereren voor deze persoon
</label>
<div class="modal-footer">
<button type="button" class="btn-ghost" onclick="closeModal('passwordModal')">Annuleren</button>
<button type="button" onclick="submitPasswordReset()">Bevestig reset</button>
</div>
</div>
</div>
<div id="coAccountModal" class="modal-overlay">
<div class="modal-content wide">
<span class="close" onclick="closeModal('coAccountModal')">&times;</span>
<h3>Gekoppelde co-accounts</h3>
<div id="coAccountList"></div>
<div class="modal-footer">
<button type="button" onclick="closeModal('coAccountModal')">Sluiten</button>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
let currentTargetUser = "";
let currentResetType = 0;
let currentTargetName = "";
function closeModal(id) { document.getElementById(id).style.display = 'none'; }
function openResetModal(identifier, fullname, accType = 0) {
currentTargetUser = identifier;
currentResetType = accType;
currentTargetName = fullname;
document.getElementById('displayUser').innerText = fullname + (accType === 0 ? " (Leerling)" : " (Co-account)");
document.getElementById('modalPasswordInput').value = "";
document.getElementById('pdfCheckbox').checked = false;
document.getElementById('passwordModal').style.display = 'flex';
}
function generateRandomPass() {
const chars = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789";
let pass = "";
for (let i = 0; i < 10; i++) pass += chars.charAt(Math.floor(Math.random() * chars.length));
document.getElementById('modalPasswordInput').value = pass;
}
function submitPasswordReset() {
const newPass = document.getElementById('modalPasswordInput').value;
const genPdf = document.getElementById('pdfCheckbox').checked;
if (!newPass) return alert("Geen wachtwoord ingevuld!");
showLoader();
fetch("{{ url_for('/ss.smartschool_reset') }}", {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: `username=${encodeURIComponent(currentTargetUser)}&new_password=${encodeURIComponent(newPass)}&account_type=${currentResetType}&generate_pdf=${genPdf}&display_name=${encodeURIComponent(currentTargetName)}`
})
.then(res => {
const contentType = res.headers.get("content-type");
if (contentType && contentType.includes("application/pdf")) {
return res.blob().then(blob => ({ type: 'pdf', data: blob }));
}
return res.json().then(data => ({ type: 'json', data: data }));
})
.then(result => {
hideLoader();
if (result.type === 'pdf') {
const url = window.URL.createObjectURL(result.data);
const a = document.createElement('a');
a.href = url;
a.download = `Account_${currentTargetName}.pdf`;
document.body.appendChild(a);
a.click();
closeModal('passwordModal');
} else if (result.data.status === "success") {
alert("Wachtwoord succesvol aangepast!");
closeModal('passwordModal');
} else {
alert("Fout: " + result.data.message);
}
}).catch(() => { hideLoader(); alert("Fout bij verbinding."); });
}
function viewCoAccounts(username) {
showLoader();
fetch("{{ url_for('/ss.smartschool_coaccounts') }}", {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: `username=${encodeURIComponent(username)}`
})
.then(res => res.json())
.then(data => {
hideLoader();
let html = '<div class="table-wrap"><table><thead><tr><th>Relatie</th><th>Naam</th><th class="actions">Actie</th></tr></thead><tbody>';
data.accounts.forEach(acc => {
const fullName = `${acc.voornaam} ${acc.naam}`;
html += `<tr>
<td>${acc.type}</td>
<td>${fullName}</td>
<td class="actions"><button type="button" class="btn-danger btn-sm" onclick="openResetModal('${acc.parent_internnummer}', '${fullName}', ${acc.index})">🔑 Reset</button></td>
</tr>`;
});
html += '</tbody></table></div>';
document.getElementById('coAccountList').innerHTML = html;
document.getElementById('coAccountModal').style.display = 'flex';
})
.catch(() => { hideLoader(); alert("Fout bij ophalen co-accounts."); });
}
</script>
{% endblock %}