diff --git a/README.md b/README.md
index ab3f850..558cd0d 100644
--- a/README.md
+++ b/README.md
@@ -56,13 +56,19 @@ In het bestand **`includes/env_badge.php`**:
- Voortgangsbalken (0 - 100%) en deadlines.
- Gekoppeld aan de oorspronkelijke brainstormkaarten en optioneel Jira Issue Keys (bijv. `FOC-101`).
-4. **Integraties Hub (`/integrations.php`)**:
- - **Microsoft Outlook**: Synchroniseert agenda-afspraken direct naar de dagplanning.
- - **Microsoft Teams**: Directe deelnamelinks naar online meetings en kanaalnotificaties.
- - **Atlassian Jira**: Issues synchroniseren en direct met één klik inplannen als dagtaak.
- - **Sandbox / Demo Modus**: Schakel met één vinkje tussen live productie en interactieve testdata.
+4. **Mijn Profiel & Persoonlijke Koppelingen (`/profile.php`)**:
+ - **Microsoft Outlook & Teams**: Koppel met 1 klik uw persoonlijke werkagenda voor dagelijkse afsprakensynchronisatie en directe Teams meeting links.
+ - **Atlassian Jira**: Koppel uw persoonlijke Atlassian API token om aan u toegewezen tickets in te zien en in te plannen.
+ - **Browser Push Meldingen**: Configureer persoonlijke waarschuwingen (vooraankondigingstijd, herhalingsfrequentie, audio chime en live test).
+ - **Account & Beveiliging**: Wachtwoord wijzigen en 2FA beveiligingsstatus.
-5. **Team & Invites Beheer (`/users.php` - Admin only)**:
+5. **Systeembeheer & Integraties Portaal (`/admin.php` - Admin only)**:
+ - Centrale Microsoft 365 Azure App Registratie (Client ID, Client Secret, Tenant ID, Admin Consent verlenen).
+ - Standaard Jira bedrijfsdomein voor alle teamleden.
+ - Systeem & Team Monitor (statistieken over actieve leden, agenda koppelingen en API-status).
+ - Extensibiliteit Hub voor toekomstige modules (AI Co-Pilot, werkdag standaarden).
+
+6. **Team & Invites Beheer (`/users.php` - Admin only)**:
- Genereer beveiligde uitnodigingslinks voor collega's met kopieerknop.
- Overzicht van actieve gebruikers, rollen en 2FA-status.
diff --git a/admin.php b/admin.php
new file mode 100644
index 0000000..3e2357a
--- /dev/null
+++ b/admin.php
@@ -0,0 +1,593 @@
+prepare("SELECT * FROM integrations WHERE user_id = ? AND provider = 'OUTLOOK'");
+ $stmtExisting->execute([$userId]);
+ $existing = $stmtExisting->fetch();
+ $existingSettings = json_decode($existing['settings'] ?? '{}', true) ?: [];
+
+ if (($clientSecret === '' || $clientSecret === '••••••••••••••••') && !empty($existingSettings['client_secret']) && $existingSettings['client_secret'] !== '••••••••••••••••') {
+ $clientSecret = $existingSettings['client_secret'];
+ }
+
+ $newSettings = array_merge($existingSettings, [
+ 'client_id' => $clientId,
+ 'client_secret' => $clientSecret,
+ 'tenant_id' => $tenantId,
+ ]);
+
+ $stmt = $db->prepare("
+ INSERT INTO integrations (user_id, provider, is_enabled, is_demo_mode, settings, last_sync_at)
+ VALUES (?, 'OUTLOOK', 1, ?, ?, NOW())
+ ON DUPLICATE KEY UPDATE
+ is_demo_mode = VALUES(is_demo_mode),
+ settings = VALUES(settings),
+ last_sync_at = NOW()
+ ");
+ $stmt->execute([$userId, $isDemo, json_encode($newSettings)]);
+
+ $message = "Centrale Microsoft 365 Azure App instellingen zijn succesvol opgeslagen.";
+ $messageType = 'success';
+ }
+
+ // 2. Centraal Jira Bedrijfsdomein opslaan
+ elseif ($action === 'save_jira_domain') {
+ $rawDomain = trim($_POST['jira_domain'] ?? '');
+ $companyDomain = !empty($rawDomain) ? jira_normalize_domain($rawDomain) : '';
+
+ $stmtExisting = $db->prepare("SELECT * FROM integrations WHERE user_id = ? AND provider = 'JIRA'");
+ $stmtExisting->execute([$userId]);
+ $existing = $stmtExisting->fetch();
+ $existingSettings = json_decode($existing['settings'] ?? '{}', true) ?: [];
+
+ $existingSettings['jira_domain'] = $companyDomain;
+
+ $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
+ settings = VALUES(settings),
+ last_sync_at = NOW()
+ ");
+ $stmt->execute([$userId, json_encode($existingSettings)]);
+
+ $message = "Standaard Atlassian Jira bedrijfsdomein is succesvol opgeslagen.";
+ $messageType = 'success';
+ }
+}
+
+// Haal actuele configuratie op
+$appConfig = microsoft_get_app_config();
+$companyJiraDomain = jira_get_company_domain();
+
+// Redirect URI
+$redirectUri = rtrim(APP_URL, '/') . '/auth/callback_microsoft.php';
+
+// Admin Consent URL
+$tenantForConsent = !empty($appConfig['tenant_id']) ? $appConfig['tenant_id'] : 'common';
+$adminConsentUrl = "https://login.microsoftonline.com/" . urlencode($tenantForConsent) . "/adminconsent?client_id=" . urlencode($appConfig['client_id']) . "&redirect_uri=" . urlencode($redirectUri);
+
+// Statistieken ophalen voor Systeem & Team Monitor
+$totalUsers = (int)$db->query("SELECT COUNT(*) FROM users")->fetchColumn();
+$totalAdmins = (int)$db->query("SELECT COUNT(*) FROM users WHERE role = 'ADMIN'")->fetchColumn();
+$totalMembers = $totalUsers - $totalAdmins;
+$pendingInvites = (int)$db->query("SELECT COUNT(*) FROM invites WHERE used_at IS NULL AND expires_at > NOW()")->fetchColumn();
+
+$outlookConnectedCount = (int)$db->query("SELECT COUNT(*) FROM integrations WHERE provider = 'OUTLOOK' AND access_token IS NOT NULL")->fetchColumn();
+$jiraConnectedCount = (int)$db->query("SELECT COUNT(*) FROM integrations WHERE provider = 'JIRA' AND settings LIKE '%jira_api_token%' AND settings NOT LIKE '%\"jira_api_token\":\"\"%'")->fetchColumn();
+
+// Haal recente gebruikers op voor snelle inspectie
+$recentUsers = $db->query("
+ SELECT u.id, u.name, u.email, u.role, u.created_at,
+ (SELECT COUNT(*) FROM integrations i WHERE i.user_id = u.id AND i.provider = 'OUTLOOK' AND i.access_token IS NOT NULL) as has_outlook,
+ (SELECT COUNT(*) FROM integrations i WHERE i.user_id = u.id AND i.provider = 'JIRA' AND i.settings LIKE '%jira_api_token%' AND i.settings NOT LIKE '%\"jira_api_token\":\"\"%') as has_jira
+ FROM users u
+ ORDER BY u.created_at DESC
+ LIMIT 6
+")->fetchAll();
+
+$pageTitle = 'Systeembeheer & Integraties — Fociz';
+require_once __DIR__ . '/includes/header.php';
+?>
+
+
+
+
+
+
+
+
+
+
+
+ Beheerderspaneel • Alleen toegankelijk voor Beheer
+
+
+ Systeembeheer & Integraties
+
+
+ Beheer hier de centrale organisatiekoppelingen zoals Microsoft 365 Azure App Registratie en Jira, inspecteer de teamstatus en configureer toekomstige modules.
+
+ Azure Portal: Ga naar portal.azure.com → Microsoft Entra ID → App registrations → New registration. Kies "Accounts in any organizational directory and personal Microsoft accounts" (of alleen uw organisatie).
+
+
+
+
+ 2
+
+ Redirect URI: Kies platform Web en vul exact in: = htmlspecialchars($redirectUri) ?>.
+
+
+
+
+ 3
+
+ API Permissions: Ga naar API permissions → Add a permission → Microsoft Graph → Delegated permissions → Vink aan: User.Read en Calendars.ReadWrite.
+
+
+
+
+ 4
+
+ Beheerdersgoedkeuring (Admin Consent): Klik op "Grant admin consent for [Uw Organisatie]". Er verschijnt direct een groen vinkje bij alle regels. Hiermee hoeven individuele collega's geen beheerder meer te vragen!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Atlassian Jira Organisatie-instellingen
+
+
+ Actief
+
+
+
+ Optioneel
+
+
+
+
Standaard Jira Cloud domein voor het hele team
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Toekomstige Modules & Extensies
+
Voorbereid architectuurkader voor nieuwe bedrijfssystemen
- = $isAdmin
- ? 'Beheer centrale organisatie-integraties en koppel uw persoonlijke Outlook agenda en Jira tickets.'
- : 'Koppel uw persoonlijke Microsoft 365 Outlook agenda en Atlassian Jira tickets om direct uw dagplanning in Fociz te vullen.' ?>
-
- Laatste Sync:
- = htmlspecialchars($configs['OUTLOOK']['last_sync_at'] ?? 'Zojuist') ?>
-
-
-
-
-
-
-
-
-
- Centrale Beheerdersinstellingen
- Deze Azure App gegevens gelden voor alle collega's in de organisatie. Gewone gebruikers zien deze technische details niet en hoeven alleen op 'Koppelen' te klikken.
-
6. Cruciaal voor organisaties: Klik direct boven de tabel met machtigingen op de knop "Beheerdersgoedkeuring verlenen voor [Organisatie]" (Grant admin consent) en bevestig met 'Ja'. Hiermee voorkomt u de melding "Beheerdersgoedkeuring vereist".
- Configuratie vereist door beheerder
-
- Uw beheerder heeft de Microsoft 365 integratie nog niet geconfigureerd voor uw organisatie. Vraag uw beheerder om de Azure App gegevens in te stellen.
-
-
-
-
-
-
-
- Gereed voor Koppeling
-
- Uw beheerder heeft Microsoft 365 klaargezet voor uw organisatie. Koppel uw persoonlijke werkagenda om al uw meetings en Teams-afspraken automatisch in uw dagplanning te laden.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Inbegrepen bij Outlook
-
-
-
-
-
Microsoft Teams
-
- Detecteert Teams vergaderingen automatisch vanuit uw Outlook agenda en toont directe 'Deelnemen' knoppen.
-
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mijn Meldingen & Agenda Herinneringen
+
Krijg realtime meldingen vanuit uw browser zodra een afspraak nadert
+
+
+
+
+
+
+
+
+
+ Browser Pushberichten zijn Actief
+ Uw browser heeft toestemming om bureaubladmeldingen weer te geven.
+
+
+
+
+
+
+
+
+
+ Toestemming van Browser Vereist
+ Klik op de knop om pushmeldingen in te schakelen voor Fociz.
+
+
+
+
+
+
+
+ Meldingen zijn momenteel geblokkeerd in uw browser. Klik links in de adresbalk op het slotje/site-instellingen en zet "Meldingen" op "Toestaan".
+