- Reorganize admin into admin/theme/default/ (views + assets) - Rename GuideNav to Navigation plugin (essential, protected) - Plugin assets support (SCSS/CSS) loaded after theme CSS - User roles: Admin, Content Manager, BI Manager, Site Admin - Role-based access control (RBAC) for admin routes and sidebar - Guide restructure: sub-topics in separate folders with sidebar nav - Dynamic breadcrumb for homepage and subdirectories - Fix theme path traversal (../../ -> ../) in admin.php - Fix CodeMirror mode load order (xml -> css -> js -> htmlmixed -> php) - Fix editor-toolbar.js null checks for plugin edit pages - Layout select from theme.json with live frontmatter update - Footer sticky at bottom of viewport (min-height: 100vh) - Breadcrumb color fix (var(--nav-font) -> var(--header-bg)) - Remove language switcher from guide pages - Update README.md and README.en.md - Bump version to 2.5.1
138 lines
8.1 KiB
Twig
138 lines
8.1 KiB
Twig
{% extends "layouts/admin.twig" %}
|
|
|
|
{% block title %}Gebruikers - CodePress Admin{% endblock %}
|
|
|
|
{% block content %}
|
|
<h2 class="mb-4"><i class="bi bi-people"></i> Gebruikers</h2>
|
|
|
|
<div class="row g-4">
|
|
<div class="col-md-7">
|
|
<div class="card shadow-sm">
|
|
<div class="card-header">
|
|
<i class="bi bi-list"></i> Gebruikers
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<table class="table table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Gebruikersnaam</th>
|
|
<th>Rol</th>
|
|
<th>Aangemaakt</th>
|
|
<th>Acties</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for username, data in users %}
|
|
<tr>
|
|
<td>
|
|
<i class="bi bi-person-circle"></i>
|
|
{{ username }}
|
|
{% if username == user.username %}
|
|
<span class="badge bg-info">Jij</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-{{ data.role == 'admin' ? 'danger' : (data.role == 'content-manager' ? 'primary' : (data.role == 'bi-manager' ? 'success' : 'warning')) }}">
|
|
{{ data.role_label|default(data.role) }}
|
|
</span>
|
|
</td>
|
|
<td class="text-muted">{{ data.created|default('Onbekend') }}</td>
|
|
<td>
|
|
{% if username != user.username %}
|
|
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#roleModal-{{ username }}">
|
|
<i class="bi bi-person-gear"></i> Rol
|
|
</button>
|
|
<form method="POST" action="/admin/users" class="d-inline" onsubmit="return confirm('Weet je zeker dat je gebruiker {{ username }} wilt verwijderen?')">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<input type="hidden" name="action" value="delete">
|
|
<input type="hidden" name="delete_username" value="{{ username }}">
|
|
<button type="submit" class="btn btn-sm btn-outline-danger">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</form>
|
|
|
|
<!-- Role change modal -->
|
|
<div class="modal fade" id="roleModal-{{ username }}" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form method="POST" action="/admin/users">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<input type="hidden" name="action" value="change_role">
|
|
<input type="hidden" name="role_username" value="{{ username }}">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title"><i class="bi bi-person-gear"></i> Rol wijzigen: {{ username }}</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">Huidige rol</label>
|
|
<p><span class="badge bg-secondary">{{ data.role_label|default(data.role) }}</span></p>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="new_role-{{ username }}" class="form-label">Nieuwe rol</label>
|
|
<select class="form-select" id="new_role-{{ username }}" name="new_role">
|
|
{% for roleKey, roleLabel in roles %}
|
|
<option value="{{ roleKey }}" {{ data.role == roleKey ? 'selected' : '' }}>{{ roleLabel }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuleren</button>
|
|
<button type="submit" class="btn btn-primary"><i class="bi bi-check-lg"></i> Wijzigen</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<span class="text-muted small">Eigen account</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="4" class="text-muted text-center py-4">Geen gebruikers gevonden.</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-5">
|
|
<div class="card shadow-sm">
|
|
<div class="card-header">
|
|
<i class="bi bi-plus-circle"></i> Nieuwe gebruiker
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="POST" action="/admin/users">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
|
<input type="hidden" name="action" value="add">
|
|
<div class="mb-3">
|
|
<label for="new_username" class="form-label">Gebruikersnaam</label>
|
|
<input type="text" class="form-control" id="new_username" name="new_username" required autofocus>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="new_password" class="form-label">Wachtwoord</label>
|
|
<input type="password" class="form-control" id="new_password" name="new_password" required>
|
|
<small class="form-text text-muted">Minimaal 8 tekens.</small>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="new_role" class="form-label">Rol</label>
|
|
<select class="form-select" id="new_role" name="new_role">
|
|
{% for roleKey, roleLabel in roles %}
|
|
<option value="{{ roleKey }}" {{ roleKey == 'content-manager' ? 'selected' : '' }}>{{ roleLabel }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary w-100">
|
|
<i class="bi bi-check-lg"></i> Gebruiker toevoegen
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %} |