feat(profile): update avatar selection with category filters and enhanced UI

- Replaced standard avatar titles with more engaging names.
- Added category filter buttons for avatars: Fun & Emojis, Cyber & Bots, Modern Personas, Adventurer & Heroes.
- Refactored avatar loading logic to use an array of avatar presets with associated categories and names.
- Enhanced button styles for better user interaction feedback.
- Implemented JavaScript function to filter displayed avatars based on selected category.
This commit is contained in:
2026-09-10 13:27:36 +02:00
parent 47b0d38084
commit 03c7fb3067
25 changed files with 99 additions and 522 deletions
+75 -9
View File
@@ -535,26 +535,71 @@ require_once __DIR__ . '/includes/header.php';
<div class="grid grid-cols-1 lg:grid-cols-12 gap-6">
<!-- Linker kolom: 24 Standaard Preset Avatars (8 cols) -->
<div class="lg:col-span-8 space-y-3">
<div class="flex items-center justify-between">
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-2">
<h3 class="text-xs font-bold text-slate-800 dark:text-slate-200 flex items-center space-x-1.5">
<i data-lucide="sparkles" class="w-3.5 h-3.5 text-indigo-500"></i>
<span>Kies een Karakter (24 Mini Avatars)</span>
<span>Kies een Karakter (24 Flitsende Avatars)</span>
</h3>
<span class="text-[11px] text-slate-400 dark:text-slate-500">Klik om direct toe te passen</span>
</div>
<!-- Categorie Filter Pills -->
<div class="flex flex-wrap items-center gap-1.5 pt-1">
<button type="button" onclick="filterAvatarCategory('all')" id="avCatBtn-all" class="av-cat-btn px-2.5 py-1 rounded-lg text-[11px] font-bold transition cursor-pointer bg-indigo-600 text-white shadow-xs">
Alle (24)
</button>
<button type="button" onclick="filterAvatarCategory('emoji')" id="avCatBtn-emoji" class="av-cat-btn px-2.5 py-1 rounded-lg text-[11px] font-semibold transition cursor-pointer bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300">
⚡ Fun & Emojis (6)
</button>
<button type="button" onclick="filterAvatarCategory('bots')" id="avCatBtn-bots" class="av-cat-btn px-2.5 py-1 rounded-lg text-[11px] font-semibold transition cursor-pointer bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300">
🤖 Cyber & Bots (6)
</button>
<button type="button" onclick="filterAvatarCategory('personas')" id="avCatBtn-personas" class="av-cat-btn px-2.5 py-1 rounded-lg text-[11px] font-semibold transition cursor-pointer bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300">
✨ Moderne Personas (6)
</button>
<button type="button" onclick="filterAvatarCategory('heroes')" id="avCatBtn-heroes" class="av-cat-btn px-2.5 py-1 rounded-lg text-[11px] font-semibold transition cursor-pointer bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300">
🎯 Adventurer & Heroes (6)
</button>
</div>
<div class="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-3 p-4 rounded-2xl bg-slate-50 dark:bg-[#0c0f17] border border-slate-200 dark:border-slate-800">
<?php
for ($i = 1; $i <= 24; $i++):
$numStr = sprintf("%02d", $i);
$avatarPath = "/assets/avatars/avatar-{$numStr}.svg";
$avatarPresets = [
['file' => 'avatar-01.svg', 'cat' => 'emoji', 'name' => 'Cool Star (Zonnebril)'],
['file' => 'avatar-02.svg', 'cat' => 'emoji', 'name' => 'Party Champion'],
['file' => 'avatar-03.svg', 'cat' => 'emoji', 'name' => 'Celebration Vibe'],
['file' => 'avatar-04.svg', 'cat' => 'emoji', 'name' => 'Laser Eyes Energy'],
['file' => 'avatar-05.svg', 'cat' => 'emoji', 'name' => 'Sunny Smiles'],
['file' => 'avatar-06.svg', 'cat' => 'emoji', 'name' => 'Fire Heart'],
['file' => 'avatar-07.svg', 'cat' => 'bots', 'name' => 'Cyber Tron'],
['file' => 'avatar-08.svg', 'cat' => 'bots', 'name' => 'Aero Bot'],
['file' => 'avatar-09.svg', 'cat' => 'bots', 'name' => 'Neon Volt'],
['file' => 'avatar-10.svg', 'cat' => 'bots', 'name' => 'Pixel Pulse'],
['file' => 'avatar-11.svg', 'cat' => 'bots', 'name' => 'Quantum AI'],
['file' => 'avatar-12.svg', 'cat' => 'bots', 'name' => 'Robo Racer'],
['file' => 'avatar-13.svg', 'cat' => 'personas', 'name' => 'Alex (Hipster)'],
['file' => 'avatar-14.svg', 'cat' => 'personas', 'name' => 'Maya (Tech Lead)'],
['file' => 'avatar-15.svg', 'cat' => 'personas', 'name' => 'Lucas (Designer)'],
['file' => 'avatar-16.svg', 'cat' => 'personas', 'name' => 'Elena (Developer)'],
['file' => 'avatar-17.svg', 'cat' => 'personas', 'name' => 'Sam (Creative)'],
['file' => 'avatar-18.svg', 'cat' => 'personas', 'name' => 'Zoe (Founder)'],
['file' => 'avatar-19.svg', 'cat' => 'heroes', 'name' => 'Jack (Adventurer)'],
['file' => 'avatar-20.svg', 'cat' => 'heroes', 'name' => 'Luna (Heroine)'],
['file' => 'avatar-21.svg', 'cat' => 'heroes', 'name' => 'Oliver (Explorer)'],
['file' => 'avatar-22.svg', 'cat' => 'heroes', 'name' => 'Mia (Rebel)'],
['file' => 'avatar-23.svg', 'cat' => 'heroes', 'name' => 'Leo (Cosmic)'],
['file' => 'avatar-24.svg', 'cat' => 'heroes', 'name' => 'Nova (Cyberpunk)'],
];
foreach ($avatarPresets as $av):
$avatarPath = "/assets/avatars/{$av['file']}";
$isSelected = ($userProfile['avatar_url'] === $avatarPath);
?>
<form method="POST" action="/profile.php" class="relative group">
<form method="POST" action="/profile.php" class="relative group avatar-item" data-category="<?= $av['cat'] ?>">
<input type="hidden" name="action" value="select_preset_avatar">
<input type="hidden" name="avatar_preset" value="<?= $avatarPath ?>">
<button type="submit" class="w-full aspect-square rounded-2xl p-1 transition transform hover:scale-105 active:scale-95 focus:outline-none cursor-pointer <?= $isSelected ? 'ring-2 ring-indigo-600 dark:ring-indigo-400 bg-indigo-50 dark:bg-indigo-950/40 shadow-sm' : 'hover:bg-white dark:hover:bg-slate-800 border border-transparent' ?>" title="Kies Avatar <?= $numStr ?>">
<img src="<?= $avatarPath ?>" alt="Avatar <?= $numStr ?>" class="w-full h-full rounded-xl object-contain pointer-events-none">
<button type="submit" class="w-full aspect-square rounded-2xl p-1 transition-all duration-200 transform hover:scale-110 active:scale-95 hover:shadow-lg hover:shadow-indigo-500/25 focus:outline-none cursor-pointer <?= $isSelected ? 'ring-2 ring-indigo-600 dark:ring-indigo-400 bg-indigo-50 dark:bg-indigo-950/40 shadow-sm' : 'hover:bg-white dark:hover:bg-slate-800 border border-transparent' ?>" title="<?= htmlspecialchars($av['name']) ?>">
<img src="<?= $avatarPath ?>" alt="<?= htmlspecialchars($av['name']) ?>" class="w-full h-full rounded-xl object-contain pointer-events-none drop-shadow-xs">
<?php if ($isSelected): ?>
<span class="absolute -top-1 -right-1 w-5 h-5 rounded-full bg-indigo-600 text-white flex items-center justify-center shadow-xs border-2 border-white dark:border-[#0c0f17]">
<i data-lucide="check" class="w-3 h-3 stroke-[3]"></i>
@@ -562,7 +607,7 @@ require_once __DIR__ . '/includes/header.php';
<?php endif; ?>
</button>
</form>
<?php endfor; ?>
<?php endforeach; ?>
</div>
</div>
@@ -1100,6 +1145,27 @@ function previewUploadAvatar(input) {
}
}
function filterAvatarCategory(category) {
const items = document.querySelectorAll('.avatar-item');
items.forEach(el => {
const cat = el.getAttribute('data-category');
if (category === 'all' || cat === category) {
el.classList.remove('hidden');
} else {
el.classList.add('hidden');
}
});
const btns = document.querySelectorAll('.av-cat-btn');
btns.forEach(btn => {
btn.className = 'av-cat-btn px-2.5 py-1 rounded-lg text-[11px] font-semibold transition cursor-pointer bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300';
});
const activeBtn = document.getElementById('avCatBtn-' + category);
if (activeBtn) {
activeBtn.className = 'av-cat-btn px-2.5 py-1 rounded-lg text-[11px] font-bold transition cursor-pointer bg-indigo-600 text-white shadow-xs';
}
}
// Sync banner status met browser permissie & activeer actuele thema kaart
document.addEventListener('DOMContentLoaded', () => {
// Initialiseer geselecteerde thema-kaart