Refactor code structure for improved readability and maintainability
This commit is contained in:
+193
-4
@@ -185,6 +185,86 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$messageType = 'success';
|
||||
}
|
||||
}
|
||||
|
||||
// 8. Standaard avatar kiezen uit bibliotheek
|
||||
elseif ($action === 'select_preset_avatar') {
|
||||
$preset = trim($_POST['avatar_preset'] ?? '');
|
||||
if (preg_match('/^\/assets\/avatars\/avatar-(0[1-9]|1[0-9]|2[0-4])\.svg$/', $preset)) {
|
||||
$stmtUp = $db->prepare("UPDATE users SET avatar_url = ? WHERE id = ?");
|
||||
$stmtUp->execute([$preset, $userId]);
|
||||
$_SESSION['user_avatar_url'] = $preset;
|
||||
$user['avatar_url'] = $preset;
|
||||
$message = "Uw avatar is succesvol bijgewerkt!";
|
||||
$messageType = 'success';
|
||||
} else {
|
||||
$message = "Ongeldige avatar geselecteerd.";
|
||||
$messageType = 'error';
|
||||
}
|
||||
}
|
||||
|
||||
// 9. Eigen profielfoto uploaden
|
||||
elseif ($action === 'upload_custom_avatar') {
|
||||
if (!isset($_FILES['avatar_file']) || $_FILES['avatar_file']['error'] !== UPLOAD_ERR_OK) {
|
||||
$message = "Selecteer een geldige afbeelding om te uploaden.";
|
||||
$messageType = 'error';
|
||||
} else {
|
||||
$file = $_FILES['avatar_file'];
|
||||
$maxSize = 4 * 1024 * 1024; // 4MB
|
||||
if ($file['size'] > $maxSize) {
|
||||
$message = "De afbeelding is te groot (maximaal 4MB toegestaan).";
|
||||
$messageType = 'error';
|
||||
} else {
|
||||
$allowedTypes = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
$mime = finfo_file($finfo, $file['tmp_name']);
|
||||
finfo_close($finfo);
|
||||
|
||||
if (!in_array($mime, $allowedTypes)) {
|
||||
$message = "Alleen JPG, PNG, WebP of GIF afbeeldingen zijn toegestaan.";
|
||||
$messageType = 'error';
|
||||
} else {
|
||||
$ext = match($mime) {
|
||||
'image/jpeg' => 'jpg',
|
||||
'image/png' => 'png',
|
||||
'image/webp' => 'webp',
|
||||
'image/gif' => 'gif',
|
||||
default => 'jpg'
|
||||
};
|
||||
|
||||
$uploadDir = __DIR__ . '/assets/uploads/avatars';
|
||||
if (!is_dir($uploadDir)) {
|
||||
@mkdir($uploadDir, 0755, true);
|
||||
}
|
||||
|
||||
$filename = "avatar_{$userId}_" . time() . "_" . bin2hex(random_bytes(4)) . ".{$ext}";
|
||||
$targetPath = $uploadDir . '/' . $filename;
|
||||
|
||||
if (move_uploaded_file($file['tmp_name'], $targetPath)) {
|
||||
$webPath = "/assets/uploads/avatars/{$filename}";
|
||||
$stmtUp = $db->prepare("UPDATE users SET avatar_url = ? WHERE id = ?");
|
||||
$stmtUp->execute([$webPath, $userId]);
|
||||
$_SESSION['user_avatar_url'] = $webPath;
|
||||
$user['avatar_url'] = $webPath;
|
||||
$message = "Uw profielfoto is succesvol geüpload en ingesteld!";
|
||||
$messageType = 'success';
|
||||
} else {
|
||||
$message = "Er is een fout opgetreden bij het verplaatsen van het geüploade bestand.";
|
||||
$messageType = 'error';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 10. Avatar verwijderen
|
||||
elseif ($action === 'remove_avatar') {
|
||||
$stmtUp = $db->prepare("UPDATE users SET avatar_url = NULL WHERE id = ?");
|
||||
$stmtUp->execute([$userId]);
|
||||
unset($_SESSION['user_avatar_url']);
|
||||
$user['avatar_url'] = null;
|
||||
$message = "Uw avatar is teruggezet naar de standaard weergave met uw initialen.";
|
||||
$messageType = 'success';
|
||||
}
|
||||
}
|
||||
|
||||
// Actuele gegevens ophalen
|
||||
@@ -228,10 +308,14 @@ require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
<div class="relative z-10 flex flex-col sm:flex-row sm:items-center justify-between gap-6">
|
||||
<div class="flex items-center space-x-4 sm:space-x-5">
|
||||
<div class="w-16 h-16 sm:w-20 sm:h-20 rounded-2xl bg-gradient-to-tr from-indigo-600 to-sky-500 p-0.5 shadow-sm flex-shrink-0">
|
||||
<div class="w-full h-full rounded-2xl bg-white dark:bg-[#0c0f17] flex items-center justify-center font-bold text-2xl sm:text-3xl text-indigo-600 dark:text-indigo-400 uppercase">
|
||||
<?= strtoupper(substr($userProfile['name'], 0, 1)) ?>
|
||||
</div>
|
||||
<div class="w-16 h-16 sm:w-20 sm:h-20 rounded-2xl bg-gradient-to-tr from-indigo-600 to-sky-500 p-0.5 shadow-sm flex-shrink-0 overflow-hidden">
|
||||
<?php if (!empty($userProfile['avatar_url'])): ?>
|
||||
<img src="<?= htmlspecialchars($userProfile['avatar_url']) ?>" alt="Avatar" class="w-full h-full rounded-2xl object-cover bg-white dark:bg-[#0c0f17]">
|
||||
<?php else: ?>
|
||||
<div class="w-full h-full rounded-2xl bg-white dark:bg-[#0c0f17] flex items-center justify-center font-bold text-2xl sm:text-3xl text-indigo-600 dark:text-indigo-400 uppercase">
|
||||
<?= strtoupper(substr($userProfile['name'], 0, 1)) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1">
|
||||
@@ -419,6 +503,100 @@ require_once __DIR__ . '/includes/header.php';
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sectie 0b: Profielfoto & Avatar Beheer -->
|
||||
<div class="fociz-card p-6 sm:p-7 space-y-6">
|
||||
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4 pb-6 border-b border-slate-100 dark:border-slate-800/80">
|
||||
<div class="flex items-center space-x-3.5">
|
||||
<div class="w-12 h-12 rounded-2xl bg-gradient-to-tr from-indigo-500 to-pink-500 p-0.5 shadow-xs flex-shrink-0 flex items-center justify-center text-white">
|
||||
<i data-lucide="smile" class="w-6 h-6"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<h2 class="text-base sm:text-lg font-bold text-slate-900 dark:text-white tracking-tight">Profielfoto & Avatar</h2>
|
||||
<span class="px-2.5 py-0.5 rounded-full <?= !empty($userProfile['avatar_url']) ? 'bg-teal-50 dark:bg-teal-500/10 border border-teal-200 dark:border-teal-500/20 text-teal-700 dark:text-teal-400' : 'bg-slate-100 dark:bg-slate-800 border border-slate-200 dark:border-slate-700 text-slate-600 dark:text-slate-400' ?> text-[10px] font-semibold">
|
||||
<?= !empty($userProfile['avatar_url']) ? 'Aangepaste Avatar Actief' : 'Standaard Initiaal-Badge' ?>
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-xs text-slate-500 dark:text-slate-400">Kies een mini-avatar uit de 24 stijlvolle karakters of upload een eigen afbeelding.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($userProfile['avatar_url'])): ?>
|
||||
<form method="POST" action="/profile.php" class="self-start sm:self-auto">
|
||||
<input type="hidden" name="action" value="remove_avatar">
|
||||
<button type="submit" onclick="return confirm('Avatar herstellen naar standaard initiaal-badge?')" class="inline-flex items-center space-x-1.5 px-3 py-1.5 rounded-xl text-xs font-semibold text-rose-600 dark:text-rose-400 bg-rose-50 dark:bg-rose-950/30 border border-rose-200 dark:border-rose-800/50 hover:bg-rose-100 dark:hover:bg-rose-900/50 transition cursor-pointer">
|
||||
<i data-lucide="rotate-ccw" class="w-3.5 h-3.5"></i>
|
||||
<span>Standaard Herstellen</span>
|
||||
</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<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">
|
||||
<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>
|
||||
</h3>
|
||||
<span class="text-[11px] text-slate-400 dark:text-slate-500">Klik om direct toe te passen</span>
|
||||
</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";
|
||||
$isSelected = ($userProfile['avatar_url'] === $avatarPath);
|
||||
?>
|
||||
<form method="POST" action="/profile.php" class="relative group">
|
||||
<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">
|
||||
<?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>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</button>
|
||||
</form>
|
||||
<?php endfor; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rechter kolom: Eigen Afbeelding Uploaden (4 cols) -->
|
||||
<div class="lg:col-span-4 space-y-3">
|
||||
<h3 class="text-xs font-bold text-slate-800 dark:text-slate-200 flex items-center space-x-1.5">
|
||||
<i data-lucide="upload-cloud" class="w-3.5 h-3.5 text-sky-500"></i>
|
||||
<span>Eigen Foto Uploaden</span>
|
||||
</h3>
|
||||
|
||||
<form method="POST" action="/profile.php" enctype="multipart/form-data" class="p-4 rounded-2xl bg-slate-50 dark:bg-[#0c0f17] border border-slate-200 dark:border-slate-800 space-y-4">
|
||||
<input type="hidden" name="action" value="upload_custom_avatar">
|
||||
|
||||
<div class="text-center p-5 border-2 border-dashed border-slate-300 dark:border-slate-700 rounded-xl hover:border-indigo-500 dark:hover:border-indigo-400 transition bg-white dark:bg-[#111622]">
|
||||
<div class="w-10 h-10 mx-auto mb-2 rounded-xl bg-indigo-50 dark:bg-indigo-950/40 text-indigo-600 dark:text-indigo-400 flex items-center justify-center">
|
||||
<i data-lucide="image" class="w-5 h-5"></i>
|
||||
</div>
|
||||
<label for="customAvatarFile" class="block text-xs font-semibold text-indigo-600 dark:text-indigo-400 hover:underline cursor-pointer mb-1">
|
||||
Klik om bestand te kiezen
|
||||
</label>
|
||||
<p class="text-[10px] text-slate-500 dark:text-slate-400">JPG, PNG, WebP of GIF (max. 4MB)</p>
|
||||
<input type="file" id="customAvatarFile" name="avatar_file" accept="image/png, image/jpeg, image/webp, image/gif" required class="hidden" onchange="previewUploadAvatar(this)">
|
||||
<div id="uploadFileName" class="mt-2 text-[11px] font-mono text-slate-700 dark:text-slate-300 truncate hidden"></div>
|
||||
</div>
|
||||
|
||||
<button type="submit" id="uploadAvatarBtn" class="w-full py-2.5 px-4 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-bold transition shadow-xs flex items-center justify-center space-x-2 cursor-pointer">
|
||||
<i data-lucide="upload" class="w-4 h-4"></i>
|
||||
<span>Foto Uploaden & Opslaan</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sectie 1: Mijn Microsoft 365 Outlook Agenda -->
|
||||
<div class="fociz-card p-6 sm:p-7">
|
||||
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4 pb-6 border-b border-slate-100 dark:border-slate-800/80">
|
||||
@@ -911,6 +1089,17 @@ function toggleJiraToken() {
|
||||
if (window.lucide) lucide.createIcons();
|
||||
}
|
||||
|
||||
function previewUploadAvatar(input) {
|
||||
if (input.files && input.files[0]) {
|
||||
const file = input.files[0];
|
||||
const nameEl = document.getElementById('uploadFileName');
|
||||
if (nameEl) {
|
||||
nameEl.textContent = '📄 ' + file.name + ' (' + Math.round(file.size / 1024) + ' KB)';
|
||||
nameEl.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sync banner status met browser permissie & activeer actuele thema kaart
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// Initialiseer geselecteerde thema-kaart
|
||||
|
||||
Reference in New Issue
Block a user