feat(ui): complete look and feel refactor with dark and light mode support

This commit is contained in:
2026-09-09 12:03:48 +02:00
parent bc1537be0c
commit 62af7b0017
12 changed files with 1059 additions and 632 deletions
+51 -51
View File
@@ -65,43 +65,44 @@ $invites = $db->query("
ORDER BY i.created_at DESC
")->fetchAll();
$pageTitle = 'Team & Uitnodigingen — Fociz';
require_once __DIR__ . '/includes/header.php';
?>
<div class="space-y-6">
<div class="space-y-6 max-w-7xl mx-auto pb-12">
<!-- Header -->
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-6 shadow-xl">
<div class="flex items-center space-x-2 text-emerald-400 text-xs font-semibold uppercase tracking-wider mb-1">
<div class="bg-white dark:bg-slate-900/80 border border-slate-200 dark:border-slate-800 rounded-3xl p-6 sm:p-7 shadow-sm dark:shadow-xl transition">
<div class="flex items-center space-x-2 text-emerald-600 dark:text-emerald-400 text-xs font-bold uppercase tracking-wider mb-1">
<i data-lucide="shield" class="w-4 h-4"></i>
<span>Beheerderspaneel</span>
</div>
<h1 class="text-2xl sm:text-3xl font-black text-white tracking-tight">
<h1 class="text-2xl sm:text-3xl font-black text-slate-900 dark:text-white tracking-tight">
Team & Uitnodigingen
</h1>
<p class="text-slate-400 text-xs sm:text-sm mt-1">
<p class="text-slate-500 dark:text-slate-400 text-xs sm:text-sm mt-1">
Fociz is strikt afgesloten: nieuwe collega's kunnen enkel toegang krijgen na het ontvangen van een uitnodigingslink en verplichte 2FA-activatie.
</p>
</div>
<?php if ($error): ?>
<div class="p-4 rounded-xl bg-red-500/10 border border-red-500/30 text-red-400 text-xs font-semibold flex items-center space-x-2">
<div class="p-4 rounded-2xl bg-red-500/10 border border-red-500/30 text-red-700 dark:text-red-400 text-xs font-semibold flex items-center space-x-2">
<i data-lucide="alert-triangle" class="w-4 h-4"></i>
<span><?= htmlspecialchars($error) ?></span>
</div>
<?php endif; ?>
<?php if ($message && $generatedLink): ?>
<div class="p-5 rounded-2xl bg-emerald-950/40 border border-emerald-500/40 text-white space-y-2 shadow-xl">
<div class="flex items-center space-x-2 text-emerald-400 font-bold text-xs">
<div class="p-5 rounded-3xl bg-emerald-50 dark:bg-emerald-950/40 border border-emerald-300 dark:border-emerald-500/40 text-slate-900 dark:text-white space-y-2 shadow-sm dark:shadow-xl transition">
<div class="flex items-center space-x-2 text-emerald-700 dark:text-emerald-400 font-bold text-xs">
<i data-lucide="check-circle-2" class="w-4 h-4"></i>
<span><?= htmlspecialchars($message) ?></span>
</div>
<p class="text-xs text-slate-300">
<p class="text-xs text-slate-600 dark:text-slate-300">
Kopieer onderstaande beveiligde registratielink en stuur deze naar de collega:
</p>
<div class="flex items-center space-x-2 bg-slate-950 p-2.5 rounded-xl border border-slate-800">
<input type="text" readonly id="inviteLinkInput" value="<?= htmlspecialchars($generatedLink) ?>" class="bg-transparent text-emerald-300 font-mono text-xs flex-1 outline-none">
<button onclick="copyInviteLink()" class="px-3 py-1.5 bg-emerald-500 hover:bg-emerald-600 text-slate-950 font-bold text-xs rounded-lg transition flex items-center space-x-1">
<div class="flex items-center space-x-2 bg-white dark:bg-slate-950 p-2.5 rounded-2xl border border-emerald-200 dark:border-slate-800">
<input type="text" readonly id="inviteLinkInput" value="<?= htmlspecialchars($generatedLink) ?>" class="bg-transparent text-emerald-700 dark:text-emerald-300 font-mono text-xs flex-1 outline-none">
<button onclick="copyInviteLink()" class="px-3 py-1.5 bg-emerald-500 hover:bg-emerald-600 text-slate-950 font-bold text-xs rounded-xl transition flex items-center space-x-1 cursor-pointer">
<i data-lucide="copy" class="w-3.5 h-3.5"></i>
<span id="copyBtnText">Kopiëren</span>
</button>
@@ -110,9 +111,9 @@ require_once __DIR__ . '/includes/header.php';
<?php endif; ?>
<!-- Uitnodiging Genereren Kaart -->
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-6 shadow-xl">
<h3 class="text-base font-bold text-white mb-4 flex items-center space-x-2">
<i data-lucide="user-plus" class="w-5 h-5 text-emerald-400"></i>
<div class="bg-white dark:bg-slate-900/80 border border-slate-200 dark:border-slate-800 rounded-3xl p-6 sm:p-7 shadow-sm dark:shadow-xl transition">
<h3 class="text-base font-bold text-slate-900 dark:text-white mb-4 flex items-center space-x-2">
<i data-lucide="user-plus" class="w-5 h-5 text-emerald-600 dark:text-emerald-400"></i>
<span>Nieuwe Collega Uitnodigen</span>
</h3>
@@ -120,20 +121,20 @@ require_once __DIR__ . '/includes/header.php';
<input type="hidden" name="action" value="create_invite">
<div class="md:col-span-6">
<label class="block text-xs font-medium text-slate-300 mb-1">E-mailadres van collega</label>
<input type="email" name="email" required placeholder="collega@bedrijf.nl" class="w-full bg-slate-950 border border-slate-800 rounded-xl px-4 py-2.5 text-white placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-emerald-500 text-xs">
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">E-mailadres van collega</label>
<input type="email" name="email" required placeholder="collega@bedrijf.nl" class="w-full bg-slate-50 dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl px-4 py-2.5 text-slate-900 dark:text-white placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-emerald-500 text-xs">
</div>
<div class="md:col-span-3">
<label class="block text-xs font-medium text-slate-300 mb-1">Rol</label>
<select name="role" class="w-full bg-slate-950 border border-slate-800 rounded-xl px-3 py-2.5 text-white text-xs focus:outline-none">
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Rol</label>
<select name="role" class="w-full bg-slate-50 dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2.5 text-slate-900 dark:text-white text-xs focus:outline-none">
<option value="MEMBER">Collega (Standaard)</option>
<option value="ADMIN">Mede-beheerder</option>
</select>
</div>
<div class="md:col-span-3">
<button type="submit" class="w-full bg-emerald-500 hover:bg-emerald-600 text-slate-950 font-bold py-2.5 px-4 rounded-xl text-xs transition shadow-lg shadow-emerald-500/20 flex items-center justify-center space-x-2">
<button type="submit" class="w-full bg-emerald-500 hover:bg-emerald-600 text-slate-950 font-bold py-2.5 px-4 rounded-xl text-xs transition shadow-lg shadow-emerald-500/20 flex items-center justify-center space-x-2 cursor-pointer">
<i data-lucide="link" class="w-4 h-4"></i>
<span>Genereer Link</span>
</button>
@@ -142,17 +143,17 @@ require_once __DIR__ . '/includes/header.php';
</div>
<!-- Actieve Gebruikers Tabel -->
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-6 shadow-xl space-y-4">
<div class="flex items-center justify-between pb-3 border-b border-slate-800">
<h3 class="text-sm font-bold text-white uppercase tracking-wider flex items-center space-x-2">
<i data-lucide="users" class="w-4 h-4 text-emerald-400"></i>
<div class="bg-white dark:bg-slate-900/80 border border-slate-200 dark:border-slate-800 rounded-3xl p-6 sm:p-7 shadow-sm dark:shadow-xl space-y-4 transition">
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800">
<h3 class="text-sm font-bold text-slate-900 dark:text-white uppercase tracking-wider flex items-center space-x-2">
<i data-lucide="users" class="w-4 h-4 text-emerald-600 dark:text-emerald-400"></i>
<span>Geregistreerde Teamleden (<?= count($users) ?>)</span>
</h3>
</div>
<div class="overflow-x-auto">
<table class="w-full text-left text-xs text-slate-300">
<thead class="bg-slate-950/60 text-slate-400 uppercase text-[10px] tracking-wider border-b border-slate-800">
<table class="w-full text-left text-xs text-slate-700 dark:text-slate-300">
<thead class="bg-slate-50 dark:bg-slate-950/60 text-slate-500 dark:text-slate-400 uppercase text-[10px] tracking-wider border-b border-slate-200 dark:border-slate-800">
<tr>
<th class="p-3">Naam & E-mail</th>
<th class="p-3">Rol</th>
@@ -161,34 +162,34 @@ require_once __DIR__ . '/includes/header.php';
<th class="p-3 text-right">Acties</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-800/60">
<tbody class="divide-y divide-slate-100 dark:divide-slate-800/60">
<?php foreach ($users as $u): ?>
<tr class="hover:bg-slate-800/30 transition">
<tr class="hover:bg-slate-50 dark:hover:bg-slate-800/30 transition">
<td class="p-3">
<div class="font-bold text-white"><?= htmlspecialchars($u['name']) ?></div>
<div class="text-[11px] text-slate-400 font-mono"><?= htmlspecialchars($u['email']) ?></div>
<div class="font-bold text-slate-900 dark:text-white"><?= htmlspecialchars($u['name']) ?></div>
<div class="text-[11px] text-slate-500 dark:text-slate-400 font-mono"><?= htmlspecialchars($u['email']) ?></div>
</td>
<td class="p-3">
<span class="px-2 py-0.5 rounded text-[10px] font-bold <?= $u['role'] === 'ADMIN' ? 'bg-emerald-500/20 text-emerald-400 border border-emerald-500/30' : 'bg-slate-800 text-slate-300' ?>">
<span class="px-2 py-0.5 rounded text-[10px] font-bold <?= $u['role'] === 'ADMIN' ? 'bg-emerald-500/15 text-emerald-700 dark:text-emerald-400 border border-emerald-500/30' : 'bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300' ?>">
<?= $u['role'] === 'ADMIN' ? 'Beheerder' : 'Collega' ?>
</span>
</td>
<td class="p-3">
<span class="px-2 py-0.5 rounded-full bg-emerald-500/10 text-emerald-400 border border-emerald-500/20 text-[10px] font-medium flex items-center space-x-1 w-max">
<span class="px-2 py-0.5 rounded-full bg-emerald-500/10 text-emerald-700 dark:text-emerald-400 border border-emerald-500/20 text-[10px] font-medium flex items-center space-x-1 w-max">
<i data-lucide="shield-check" class="w-3 h-3"></i>
<span>2FA Actief</span>
</span>
</td>
<td class="p-3 text-slate-400">
<td class="p-3 text-slate-500 dark:text-slate-400">
<?= date('d-m-Y', strtotime($u['created_at'])) ?>
</td>
<td class="p-3 text-right">
<?php if ($u['id'] !== $adminUser['id']): ?>
<a href="/users.php?delete_user=<?= $u['id'] ?>" onclick="return confirm('Gebruiker verwijderen?')" class="text-slate-500 hover:text-red-400 transition p-1">
<a href="/users.php?delete_user=<?= $u['id'] ?>" onclick="return confirm('Gebruiker verwijderen?')" class="text-slate-400 hover:text-red-600 dark:text-slate-500 dark:hover:text-red-400 transition p-1 cursor-pointer">
<i data-lucide="trash-2" class="w-4 h-4 inline"></i>
</a>
<?php else: ?>
<span class="text-[10px] text-slate-600 font-medium">Uzelf</span>
<span class="text-[10px] text-slate-400 dark:text-slate-600 font-medium">Uzelf</span>
<?php endif; ?>
</td>
</tr>
@@ -199,17 +200,17 @@ require_once __DIR__ . '/includes/header.php';
</div>
<!-- Uitstaande Uitnodigingen Tabel -->
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-6 shadow-xl space-y-4">
<div class="flex items-center justify-between pb-3 border-b border-slate-800">
<h3 class="text-sm font-bold text-white uppercase tracking-wider flex items-center space-x-2">
<i data-lucide="mail" class="w-4 h-4 text-amber-400"></i>
<div class="bg-white dark:bg-slate-900/80 border border-slate-200 dark:border-slate-800 rounded-3xl p-6 sm:p-7 shadow-sm dark:shadow-xl space-y-4 transition">
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800">
<h3 class="text-sm font-bold text-slate-900 dark:text-white uppercase tracking-wider flex items-center space-x-2">
<i data-lucide="mail" class="w-4 h-4 text-amber-500"></i>
<span>Uitnodigingen Status (<?= count($invites) ?>)</span>
</h3>
</div>
<div class="overflow-x-auto">
<table class="w-full text-left text-xs text-slate-300">
<thead class="bg-slate-950/60 text-slate-400 uppercase text-[10px] tracking-wider border-b border-slate-800">
<table class="w-full text-left text-xs text-slate-700 dark:text-slate-300">
<thead class="bg-slate-50 dark:bg-slate-950/60 text-slate-500 dark:text-slate-400 uppercase text-[10px] tracking-wider border-b border-slate-200 dark:border-slate-800">
<tr>
<th class="p-3">Uitgenodigd E-mailadres</th>
<th class="p-3">Rol</th>
@@ -218,29 +219,29 @@ require_once __DIR__ . '/includes/header.php';
<th class="p-3 text-right">Actie</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-800/60">
<tbody class="divide-y divide-slate-100 dark:divide-slate-800/60">
<?php if (empty($invites)): ?>
<tr><td colspan="5" class="p-4 text-center text-slate-500">Nog geen uitnodigingen verstuurd.</td></tr>
<tr><td colspan="5" class="p-4 text-center text-slate-400 dark:text-slate-500">Nog geen uitnodigingen verstuurd.</td></tr>
<?php else: ?>
<?php foreach ($invites as $inv):
$isUsed = !empty($inv['used_at']);
$isExpired = strtotime($inv['expires_at']) < time();
?>
<tr class="hover:bg-slate-800/30 transition">
<td class="p-3 font-mono"><?= htmlspecialchars($inv['email']) ?></td>
<tr class="hover:bg-slate-50 dark:hover:bg-slate-800/30 transition">
<td class="p-3 font-mono text-slate-900 dark:text-white"><?= htmlspecialchars($inv['email']) ?></td>
<td class="p-3"><?= htmlspecialchars($inv['role']) ?></td>
<td class="p-3">
<?php if ($isUsed): ?>
<span class="px-2 py-0.5 rounded text-[10px] font-bold bg-emerald-500/20 text-emerald-400">Geaccepteerd</span>
<span class="px-2 py-0.5 rounded text-[10px] font-bold bg-emerald-500/15 text-emerald-700 dark:text-emerald-400 border border-emerald-500/30">Geaccepteerd</span>
<?php elseif ($isExpired): ?>
<span class="px-2 py-0.5 rounded text-[10px] font-bold bg-red-500/20 text-red-400">Verlopen</span>
<span class="px-2 py-0.5 rounded text-[10px] font-bold bg-red-500/15 text-red-700 dark:text-red-400 border border-red-500/30">Verlopen</span>
<?php else: ?>
<span class="px-2 py-0.5 rounded text-[10px] font-bold bg-amber-500/20 text-amber-400">In afwachting</span>
<span class="px-2 py-0.5 rounded text-[10px] font-bold bg-amber-500/15 text-amber-700 dark:text-amber-400 border border-amber-500/30">In afwachting</span>
<?php endif; ?>
</td>
<td class="p-3 text-slate-400"><?= date('d-m-Y H:i', strtotime($inv['expires_at'])) ?></td>
<td class="p-3 text-slate-500 dark:text-slate-400"><?= date('d-m-Y H:i', strtotime($inv['expires_at'])) ?></td>
<td class="p-3 text-right">
<a href="/users.php?delete_invite=<?= $inv['id'] ?>" onclick="return confirm('Uitnodiging intrekken?')" class="text-slate-500 hover:text-red-400 transition p-1">
<a href="/users.php?delete_invite=<?= $inv['id'] ?>" onclick="return confirm('Uitnodiging intrekken?')" class="text-slate-400 hover:text-red-600 dark:text-slate-500 dark:hover:text-red-400 transition p-1 cursor-pointer">
<i data-lucide="trash-2" class="w-4 h-4 inline"></i>
</a>
</td>
@@ -266,4 +267,3 @@ function copyInviteLink() {
</script>
<?php require_once __DIR__ . '/includes/footer.php'; ?>