prepare("SELECT settings FROM integrations WHERE user_id = ? AND provider = 'OUTLOOK'"); $stmtExisting->execute([$userId]); $existing = $stmtExisting->fetch(); $settings = json_decode($existing['settings'] ?? '{}', true) ?: []; $settings['sync_interval_seconds'] = $syncInterval; $stmtUp = $db->prepare("UPDATE integrations SET settings = ? WHERE user_id = ? AND provider = 'OUTLOOK'"); $stmtUp->execute([json_encode($settings), $userId]); $message = "Uw Microsoft Outlook synchronisatievoorkeur is succesvol opgeslagen."; $messageType = 'success'; } // 3. Jira Opslaan & Testen elseif ($action === 'save_jira') { $companyDomain = jira_get_company_domain(); $rawDomain = trim($_POST['jira_domain'] ?? ''); $jiraDomain = !empty($rawDomain) ? jira_normalize_domain($rawDomain) : $companyDomain; $jiraEmail = trim($_POST['jira_email'] ?? ''); $jiraToken = trim($_POST['jira_api_token'] ?? ''); // Haal bestaande instellingen op $stmtExisting = $db->prepare("SELECT * FROM integrations WHERE user_id = ? AND provider = 'JIRA'"); $stmtExisting->execute([$userId]); $existing = $stmtExisting->fetch(); $existingSettings = json_decode($existing['settings'] ?? '{}', true) ?: []; if (($jiraToken === '' || $jiraToken === '••••••••••••••••') && !empty($existingSettings['jira_api_token']) && $existingSettings['jira_api_token'] !== '••••••••••••••••') { $jiraToken = $existingSettings['jira_api_token']; } $accountName = $existingSettings['account_name'] ?? ''; $accountId = $existingSettings['account_id'] ?? ''; if (!empty($jiraDomain) && !empty($jiraEmail) && !empty($jiraToken)) { $testRes = jira_test_connection($jiraDomain, $jiraEmail, $jiraToken); if (!$testRes['success']) { $message = "Jira Verbindingsfout: " . $testRes['error']; $messageType = 'error'; } else { $accountName = $testRes['user']['displayName'] ?? 'Jira Gebruiker'; $accountId = $testRes['user']['accountId'] ?? ''; $message = "Verbinding met Jira geslaagd! Ingelogd als: {$accountName}"; $messageType = 'success'; } } else { $message = "Jira instellingen opgeslagen."; $messageType = 'success'; } $newSettings = [ 'jira_domain' => $jiraDomain, 'jira_email' => $jiraEmail, 'jira_api_token' => $jiraToken, 'account_name' => $accountName, 'account_id' => $accountId, ]; $stmt = $db->prepare(" INSERT INTO integrations (user_id, provider, is_enabled, is_demo_mode, settings, last_sync_at) VALUES (?, 'JIRA', 1, 0, ?, NOW()) ON DUPLICATE KEY UPDATE is_demo_mode = 0, settings = VALUES(settings), last_sync_at = NOW() "); $stmt->execute([$userId, json_encode($newSettings)]); unset($_SESSION["jira_issues_user_{$userId}"]); } // 4. Jira ontkoppelen elseif ($action === 'disconnect_jira') { jira_disconnect($userId); header('Location: /profile.php?success=' . urlencode('Atlassian Jira is succesvol ontkoppeld.')); exit; } // 5. Notificatievoorkeuren opslaan elseif ($action === 'save_notifications') { $settings = [ 'enabled' => isset($_POST['notif_enabled']) ? 1 : 0, 'lead_time_minutes' => (int)($_POST['lead_time_minutes'] ?? 5), 'repeat_count' => (int)($_POST['repeat_count'] ?? 2), 'repeat_interval_minutes' => (int)($_POST['repeat_interval_minutes'] ?? 2), 'sound_enabled' => isset($_POST['sound_enabled']) ? 1 : 0, ]; update_user_notification_settings($userId, $settings); $message = "Uw persoonlijke notificatievoorkeuren zijn succesvol opgeslagen."; $messageType = 'success'; } // 6. Profielnaam bijwerken elseif ($action === 'update_profile') { $name = trim($_POST['name'] ?? ''); if (strlen($name) < 2) { $message = "Voer een geldige naam in van minimaal 2 tekens."; $messageType = 'error'; } else { $stmt = $db->prepare("UPDATE users SET name = ? WHERE id = ?"); $stmt->execute([$name, $userId]); $_SESSION['user_name'] = $name; $user['name'] = $name; $message = "Uw profielnaam is succesvol bijgewerkt."; $messageType = 'success'; } } // 7. Wachtwoord wijzigen elseif ($action === 'change_password') { $currentPassword = $_POST['current_password'] ?? ''; $newPassword = $_POST['new_password'] ?? ''; $confirmPassword = $_POST['confirm_password'] ?? ''; $stmtU = $db->prepare("SELECT password_hash FROM users WHERE id = ?"); $stmtU->execute([$userId]); $storedHash = $stmtU->fetchColumn(); if (!password_verify($currentPassword, $storedHash)) { $message = "Uw huidige wachtwoord is niet correct ingevoerd."; $messageType = 'error'; } elseif (strlen($newPassword) < 8) { $message = "Het nieuwe wachtwoord moet minimaal 8 tekens lang zijn."; $messageType = 'error'; } elseif ($newPassword !== $confirmPassword) { $message = "Het nieuwe wachtwoord en de bevestiging komen niet overeen."; $messageType = 'error'; } else { $newHash = password_hash($newPassword, PASSWORD_DEFAULT); $stmtUp = $db->prepare("UPDATE users SET password_hash = ? WHERE id = ?"); $stmtUp->execute([$newHash, $userId]); $message = "Uw wachtwoord is succesvol gewijzigd."; $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 $stmtUser = $db->prepare("SELECT * FROM users WHERE id = ?"); $stmtUser->execute([$userId]); $userProfile = $stmtUser->fetch(); // Outlook status ophalen $stmtOutlook = $db->prepare("SELECT * FROM integrations WHERE user_id = ? AND provider = 'OUTLOOK'"); $stmtOutlook->execute([$userId]); $outlookRow = $stmtOutlook->fetch(); $isOutlookConnected = !empty($outlookRow['access_token']) && empty($outlookRow['is_demo_mode']); $outlookSettings = json_decode($outlookRow['settings'] ?? '{}', true) ?: []; // Jira status ophalen $stmtJira = $db->prepare("SELECT * FROM integrations WHERE user_id = ? AND provider = 'JIRA'"); $stmtJira->execute([$userId]); $jiraRow = $stmtJira->fetch(); $jiraSettings = json_decode($jiraRow['settings'] ?? '{}', true) ?: []; $isJiraConnected = !empty($jiraSettings['jira_api_token']); $companyJiraDomain = jira_get_company_domain(); $activeJiraDomain = !empty($jiraSettings['jira_domain']) ? $jiraSettings['jira_domain'] : $companyJiraDomain; // Centrale Azure App configuratie status $appConfig = microsoft_get_app_config(); // Notificatie-instellingen $notifSettings = get_user_notification_settings($userId); // Thema ophalen $userTheme = get_user_theme($userId); $pageTitle = 'Mijn Profiel & Koppelingen — Fociz'; require_once __DIR__ . '/includes/header.php'; ?>
Avatar

Beheerder Collega 2FA Beveiligd

• Lid sinds

Weergave & Thema

Actief:

Kies uw gewenste uiterlijk: rustig donker grafiet, kraakhelder licht of synchroniseer met uw apparaat.

Profielfoto & Avatar

Kies een mini-avatar uit de 24 stijlvolle karakters of upload een eigen afbeelding.

Kies een Karakter (24 Flitsende Avatars)

Klik om direct toe te passen
'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); ?>

Eigen Foto Uploaden

JPG, PNG, WebP of GIF (max. 4MB)

Mijn Microsoft 365 Agenda

Live Verbonden Niet Gekoppeld

Synchroniseer uw agenda-afspraken automatisch met uw dagplanning

Gekoppeld Microsoft Account
Microsoft Teams Koppeling Automatische Meeting Links Vergaderlinks in uw agenda worden direct klikbaar in uw dagplanning

Bepaalt hoe vaak het dagplanningscherm in de achtergrond controleert op gewijzigde of verwijderde Outlook afspraken.

Uw agenda synchroniseert live. Afspraken van vandaag verschijnen direct in uw Dagplanning.
Naar Dagplanning →

Verbind uw Microsoft Outlook Agenda

Krijg uw dagelijkse afspraken automatisch te zien in Fociz en ontvang herinneringen vóórdat uw vergaderingen beginnen.

U wordt veilig doorgestuurd naar Microsoft om in te loggen
Microsoft 365 koppeling is nog niet geconfigureerd door de beheerder. Stel Azure in via Systeembeheer → Vraag uw beheerder om dit in te schakelen.

Mijn Atlassian Jira Koppeling

Verbonden Niet Gekoppeld

Importeer uw toegewezen Jira issues direct naar uw dagelijkse takenlijst

Standaard ingevuld door beheerder indien beschikbaar
API Token Aanmaken
Verbonden als: Verbinding wordt automatisch gevalideerd bij het opslaan

Mijn Meldingen & Agenda Herinneringen

Krijg realtime meldingen vanuit uw browser zodra een afspraak nadert

Toestemming van Browser Vereist Klik op de knop om pushmeldingen in te schakelen voor Fociz.
Meldingen Actief Automatisch waarschuwen bij naderende afspraken
Subtiel Geluidssignaal Speel een zachte chime af bij binnenkomst van de herinnering

Tweestapsverificatie (2FA) is Actief

Beveiligd

Uw Fociz account is optimaal beveiligd met een Authenticator app (TOTP) voor maximale privacy- en dataveiligheid.

Verplicht & Actief

Persoonlijke Gegevens

E-mailadres is gekoppeld aan uw account en 2FA.

Wachtwoord Wijzigen