Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9de4c3b1d2 | |||
| 677126e7f6 | |||
| 333e9c2451 | |||
| ce7b2762df | |||
| d11f11c2c8 | |||
| 262a8f8b42 | |||
| 68c0d9fe60 | |||
| 2b94f3dd46 | |||
| 8dbd0b251f | |||
| a09d99ea88 | |||
| 434df2754c |
@@ -1,3 +0,0 @@
|
|||||||
# Zorg dat omgevingsspecifieke bestanden nooit worden overschreven bij merges tussen dev en main
|
|
||||||
|
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
|
|
||||||
<div class="space-y-8 max-w-7xl mx-auto pb-12">
|
<div class="space-y-8 max-w-7xl mx-auto pb-12">
|
||||||
<!-- Top Header Banner -->
|
<!-- Top Header Banner -->
|
||||||
<div class="relative overflow-hidden fociz-card p-6 sm:p-8">
|
<div class="relative overflow-hidden bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-6 sm:p-8 shadow-xs backdrop-blur-xl transition">
|
||||||
<div class="absolute -top-24 -right-24 w-80 h-80 bg-indigo-500/10 rounded-full blur-3xl pointer-events-none"></div>
|
<div class="absolute -top-24 -right-24 w-80 h-80 bg-indigo-500/10 rounded-full blur-3xl pointer-events-none"></div>
|
||||||
<div class="absolute -bottom-24 -left-24 w-80 h-80 bg-sky-500/10 rounded-full blur-3xl pointer-events-none"></div>
|
<div class="absolute -bottom-24 -left-24 w-80 h-80 bg-sky-500/10 rounded-full blur-3xl pointer-events-none"></div>
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
|
|
||||||
<!-- Stat kaarten rij -->
|
<!-- Stat kaarten rij -->
|
||||||
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4">
|
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
<div class="fociz-card p-5 flex items-center space-x-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-5 flex items-center space-x-4 shadow-xs transition">
|
||||||
<div class="w-12 h-12 rounded-xl bg-indigo-50 dark:bg-indigo-950/40 border border-indigo-200 dark:border-indigo-800/60 flex items-center justify-center text-indigo-600 dark:text-indigo-400 flex-shrink-0">
|
<div class="w-12 h-12 rounded-xl bg-indigo-50 dark:bg-indigo-950/40 border border-indigo-200 dark:border-indigo-800/60 flex items-center justify-center text-indigo-600 dark:text-indigo-400 flex-shrink-0">
|
||||||
<i data-lucide="users" class="w-6 h-6"></i>
|
<i data-lucide="users" class="w-6 h-6"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -228,7 +228,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="fociz-card p-5 flex items-center space-x-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-5 flex items-center space-x-4 shadow-xs transition">
|
||||||
<div class="w-12 h-12 rounded-xl bg-sky-50 dark:bg-sky-950/40 border border-sky-200 dark:border-sky-800/60 flex items-center justify-center text-sky-600 dark:text-sky-400 flex-shrink-0">
|
<div class="w-12 h-12 rounded-xl bg-sky-50 dark:bg-sky-950/40 border border-sky-200 dark:border-sky-800/60 flex items-center justify-center text-sky-600 dark:text-sky-400 flex-shrink-0">
|
||||||
<i data-lucide="calendar" class="w-6 h-6"></i>
|
<i data-lucide="calendar" class="w-6 h-6"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -239,7 +239,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="fociz-card p-5 flex items-center space-x-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-5 flex items-center space-x-4 shadow-xs transition">
|
||||||
<div class="w-12 h-12 rounded-xl bg-indigo-50 dark:bg-indigo-950/40 border border-indigo-200 dark:border-indigo-800/60 flex items-center justify-center text-indigo-600 dark:text-indigo-400 flex-shrink-0">
|
<div class="w-12 h-12 rounded-xl bg-indigo-50 dark:bg-indigo-950/40 border border-indigo-200 dark:border-indigo-800/60 flex items-center justify-center text-indigo-600 dark:text-indigo-400 flex-shrink-0">
|
||||||
<i data-lucide="check-square" class="w-6 h-6"></i>
|
<i data-lucide="check-square" class="w-6 h-6"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -250,7 +250,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="fociz-card p-5 flex items-center space-x-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-5 flex items-center space-x-4 shadow-xs transition">
|
||||||
<div class="w-12 h-12 rounded-xl bg-amber-50 dark:bg-amber-950/40 border border-amber-200 dark:border-amber-800/60 flex items-center justify-center text-amber-600 dark:text-amber-400 flex-shrink-0">
|
<div class="w-12 h-12 rounded-xl bg-amber-50 dark:bg-amber-950/40 border border-amber-200 dark:border-amber-800/60 flex items-center justify-center text-amber-600 dark:text-amber-400 flex-shrink-0">
|
||||||
<i data-lucide="mail" class="w-6 h-6"></i>
|
<i data-lucide="mail" class="w-6 h-6"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -269,7 +269,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
<div class="lg:col-span-8 space-y-8">
|
<div class="lg:col-span-8 space-y-8">
|
||||||
|
|
||||||
<!-- 1. Microsoft 365 Azure App Registratie -->
|
<!-- 1. Microsoft 365 Azure App Registratie -->
|
||||||
<div class="fociz-card p-6 sm:p-7">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-6 sm:p-7 shadow-xs transition">
|
||||||
<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 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="flex items-center space-x-3.5">
|
||||||
<div class="w-12 h-12 rounded-xl bg-sky-50 dark:bg-sky-950/40 border border-sky-200 dark:border-sky-800/60 flex items-center justify-center text-sky-600 dark:text-sky-400 font-bold shadow-xs">
|
<div class="w-12 h-12 rounded-xl bg-sky-50 dark:bg-sky-950/40 border border-sky-200 dark:border-sky-800/60 flex items-center justify-center text-sky-600 dark:text-sky-400 font-bold shadow-xs">
|
||||||
@@ -409,7 +409,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 2. Atlassian Jira Bedrijfsinstellingen -->
|
<!-- 2. Atlassian Jira Bedrijfsinstellingen -->
|
||||||
<div class="fociz-card p-6 sm:p-7">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-6 sm:p-7 shadow-xs transition">
|
||||||
<div class="flex items-center space-x-3.5 pb-6 border-b border-slate-100 dark:border-slate-800/80">
|
<div class="flex items-center space-x-3.5 pb-6 border-b border-slate-100 dark:border-slate-800/80">
|
||||||
<div class="w-12 h-12 rounded-xl bg-indigo-50 dark:bg-indigo-950/40 border border-indigo-200 dark:border-indigo-800/60 flex items-center justify-center text-indigo-600 dark:text-indigo-400 font-bold shadow-xs">
|
<div class="w-12 h-12 rounded-xl bg-indigo-50 dark:bg-indigo-950/40 border border-indigo-200 dark:border-indigo-800/60 flex items-center justify-center text-indigo-600 dark:text-indigo-400 font-bold shadow-xs">
|
||||||
<i data-lucide="trello" class="w-6 h-6"></i>
|
<i data-lucide="trello" class="w-6 h-6"></i>
|
||||||
@@ -453,7 +453,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 3. Organisatie Werkdag Standaarden (Release v1.4) -->
|
<!-- 3. Organisatie Werkdag Standaarden (Release v1.4) -->
|
||||||
<div class="fociz-card p-6 sm:p-7 space-y-6">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-6 sm:p-7 shadow-xs space-y-6 transition">
|
||||||
<div class="flex items-center justify-between pb-4 border-b border-slate-100 dark:border-slate-800/80">
|
<div class="flex items-center justify-between pb-4 border-b border-slate-100 dark:border-slate-800/80">
|
||||||
<div class="flex items-center space-x-3.5">
|
<div class="flex items-center space-x-3.5">
|
||||||
<div class="w-12 h-12 rounded-xl bg-indigo-50 dark:bg-indigo-950/40 border border-indigo-200 dark:border-indigo-800/60 flex items-center justify-center text-indigo-600 dark:text-indigo-400 font-bold shadow-xs">
|
<div class="w-12 h-12 rounded-xl bg-indigo-50 dark:bg-indigo-950/40 border border-indigo-200 dark:border-indigo-800/60 flex items-center justify-center text-indigo-600 dark:text-indigo-400 font-bold shadow-xs">
|
||||||
@@ -542,9 +542,13 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-medium text-slate-600 dark:text-slate-400 mb-1">Standaard tijdslot</label>
|
<label class="block text-[11px] font-medium text-slate-600 dark:text-slate-400 mb-1">Standaard tijdslot</label>
|
||||||
<select name="default_task_duration" class="w-full bg-white dark:bg-[#111622] border border-slate-300 dark:border-slate-700 rounded-xl px-3 py-1.5 text-xs text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
<select name="default_task_duration" class="w-full bg-white dark:bg-[#111622] border border-slate-300 dark:border-slate-700 rounded-xl px-3 py-1.5 text-xs text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
|
<<<<<<< HEAD
|
||||||
<option value="10" <?= $workdaySettings['default_task_duration'] == 10 ? 'selected' : '' ?>>10 minuten</option>
|
<option value="10" <?= $workdaySettings['default_task_duration'] == 10 ? 'selected' : '' ?>>10 minuten</option>
|
||||||
<option value="15" <?= $workdaySettings['default_task_duration'] == 15 ? 'selected' : '' ?>>15 minuten</option>
|
<option value="15" <?= $workdaySettings['default_task_duration'] == 15 ? 'selected' : '' ?>>15 minuten</option>
|
||||||
<option value="20" <?= $workdaySettings['default_task_duration'] == 20 ? 'selected' : '' ?>>20 minuten</option>
|
<option value="20" <?= $workdaySettings['default_task_duration'] == 20 ? 'selected' : '' ?>>20 minuten</option>
|
||||||
|
=======
|
||||||
|
<option value="15" <?= $workdaySettings['default_task_duration'] == 15 ? 'selected' : '' ?>>15 minuten</option>
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
<option value="30" <?= $workdaySettings['default_task_duration'] == 30 ? 'selected' : '' ?>>30 minuten (Standaard)</option>
|
<option value="30" <?= $workdaySettings['default_task_duration'] == 30 ? 'selected' : '' ?>>30 minuten (Standaard)</option>
|
||||||
<option value="45" <?= $workdaySettings['default_task_duration'] == 45 ? 'selected' : '' ?>>45 minuten</option>
|
<option value="45" <?= $workdaySettings['default_task_duration'] == 45 ? 'selected' : '' ?>>45 minuten</option>
|
||||||
<option value="60" <?= $workdaySettings['default_task_duration'] == 60 ? 'selected' : '' ?>>60 minuten (1 uur)</option>
|
<option value="60" <?= $workdaySettings['default_task_duration'] == 60 ? 'selected' : '' ?>>60 minuten (1 uur)</option>
|
||||||
@@ -565,7 +569,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 4. AI & Brainstorm Co-Pilot (Release v1.5) -->
|
<!-- 4. AI & Brainstorm Co-Pilot (Release v1.5) -->
|
||||||
<div class="fociz-card p-6 sm:p-7 space-y-6">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-6 sm:p-7 shadow-xs space-y-6 transition">
|
||||||
<div class="flex items-center justify-between pb-4 border-b border-slate-100 dark:border-slate-800/80">
|
<div class="flex items-center justify-between pb-4 border-b border-slate-100 dark:border-slate-800/80">
|
||||||
<div class="flex items-center space-x-3.5">
|
<div class="flex items-center space-x-3.5">
|
||||||
<div class="w-12 h-12 rounded-xl bg-amber-50 dark:bg-amber-950/40 border border-amber-200 dark:border-amber-800/60 flex items-center justify-center text-amber-600 dark:text-amber-400 font-bold shadow-xs">
|
<div class="w-12 h-12 rounded-xl bg-amber-50 dark:bg-amber-950/40 border border-amber-200 dark:border-amber-800/60 flex items-center justify-center text-amber-600 dark:text-amber-400 font-bold shadow-xs">
|
||||||
@@ -626,7 +630,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
<div class="lg:col-span-4 space-y-6">
|
<div class="lg:col-span-4 space-y-6">
|
||||||
|
|
||||||
<!-- Team Status Overzicht -->
|
<!-- Team Status Overzicht -->
|
||||||
<div class="fociz-card p-6 space-y-5">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-6 shadow-xs space-y-5 transition">
|
||||||
<div class="flex items-center justify-between pb-4 border-b border-slate-100 dark:border-slate-800/80">
|
<div class="flex items-center justify-between pb-4 border-b border-slate-100 dark:border-slate-800/80">
|
||||||
<div class="flex items-center space-x-2.5">
|
<div class="flex items-center space-x-2.5">
|
||||||
<i data-lucide="activity" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="activity" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
@@ -671,7 +675,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Systeem Gezondheid & Beveiliging -->
|
<!-- Systeem Gezondheid & Beveiliging -->
|
||||||
<div class="fociz-card p-6 space-y-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-6 shadow-xs space-y-4 transition">
|
||||||
<div class="flex items-center space-x-2 text-teal-600 dark:text-teal-400 text-xs font-semibold">
|
<div class="flex items-center space-x-2 text-teal-600 dark:text-teal-400 text-xs font-semibold">
|
||||||
<i data-lucide="shield-check" class="w-4 h-4"></i>
|
<i data-lucide="shield-check" class="w-4 h-4"></i>
|
||||||
<span>Systeem & Beveiliging</span>
|
<span>Systeem & Beveiliging</span>
|
||||||
|
|||||||
+57
-4
@@ -38,8 +38,13 @@ try {
|
|||||||
$title = trim($data['title'] ?? '');
|
$title = trim($data['title'] ?? '');
|
||||||
$priority = in_array($data['priority'] ?? '', ['P1', 'P2', 'P3']) ? $data['priority'] : 'P2';
|
$priority = in_array($data['priority'] ?? '', ['P1', 'P2', 'P3']) ? $data['priority'] : 'P2';
|
||||||
$timeBlockStart = !empty($data['time_block_start']) ? trim($data['time_block_start']) : null;
|
$timeBlockStart = !empty($data['time_block_start']) ? trim($data['time_block_start']) : null;
|
||||||
|
<<<<<<< HEAD
|
||||||
$timeBlockEnd = !empty($data['time_block_end']) ? trim($data['time_block_end']) : null;
|
$timeBlockEnd = !empty($data['time_block_end']) ? trim($data['time_block_end']) : null;
|
||||||
$durationMinutes = (int)($data['duration_minutes'] ?? 0);
|
$durationMinutes = (int)($data['duration_minutes'] ?? 0);
|
||||||
|
=======
|
||||||
|
$durationMinutes = (int)($data['duration_minutes'] ?? 30);
|
||||||
|
if ($durationMinutes <= 0) $durationMinutes = 30;
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
$date = !empty($data['date']) ? trim($data['date']) : $today;
|
$date = !empty($data['date']) ? trim($data['date']) : $today;
|
||||||
$syncOutlook = !empty($data['sync_to_outlook']);
|
$syncOutlook = !empty($data['sync_to_outlook']);
|
||||||
|
|
||||||
@@ -48,6 +53,7 @@ try {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
// Als zowel start- als eindtijd zijn opgegeven, bereken exact de minuten
|
// Als zowel start- als eindtijd zijn opgegeven, bereken exact de minuten
|
||||||
if (!empty($timeBlockStart) && !empty($timeBlockEnd)) {
|
if (!empty($timeBlockStart) && !empty($timeBlockEnd)) {
|
||||||
$t1 = strtotime("2000-01-01 {$timeBlockStart}");
|
$t1 = strtotime("2000-01-01 {$timeBlockStart}");
|
||||||
@@ -71,6 +77,9 @@ try {
|
|||||||
// negeer
|
// negeer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
// Haal of maak daily plan op
|
// Haal of maak daily plan op
|
||||||
$stmtPlan = $db->prepare("
|
$stmtPlan = $db->prepare("
|
||||||
INSERT INTO daily_plans (user_id, plan_date)
|
INSERT INTO daily_plans (user_id, plan_date)
|
||||||
@@ -83,6 +92,10 @@ try {
|
|||||||
$source = !empty($data['source']) ? substr(trim($data['source']), 0, 50) : 'FOCIZ';
|
$source = !empty($data['source']) ? substr(trim($data['source']), 0, 50) : 'FOCIZ';
|
||||||
$externalId = !empty($data['external_id']) ? substr(trim($data['external_id']), 0, 255) : null;
|
$externalId = !empty($data['external_id']) ? substr(trim($data['external_id']), 0, 255) : null;
|
||||||
$externalUrl = !empty($data['external_url']) ? trim($data['external_url']) : null;
|
$externalUrl = !empty($data['external_url']) ? trim($data['external_url']) : null;
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
$timeBlockEnd = null;
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
$outlookSyncError = null;
|
$outlookSyncError = null;
|
||||||
|
|
||||||
// Als synchronisatie naar Outlook gewenst is (of source is OUTLOOK) en nog geen extern ID heeft
|
// Als synchronisatie naar Outlook gewenst is (of source is OUTLOOK) en nog geen extern ID heeft
|
||||||
@@ -97,7 +110,10 @@ try {
|
|||||||
'description' => "Gepland via Fociz Dagplanning ({$priority})",
|
'description' => "Gepland via Fociz Dagplanning ({$priority})",
|
||||||
'date' => $date,
|
'date' => $date,
|
||||||
'start_time' => $timeBlockStart,
|
'start_time' => $timeBlockStart,
|
||||||
|
<<<<<<< HEAD
|
||||||
'end_time' => $timeBlockEnd,
|
'end_time' => $timeBlockEnd,
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
'duration_minutes' => $durationMinutes,
|
'duration_minutes' => $durationMinutes,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -106,11 +122,30 @@ try {
|
|||||||
$externalId = $msResult['event_id'];
|
$externalId = $msResult['event_id'];
|
||||||
$externalUrl = $msResult['web_link'] ?? 'https://outlook.office.com';
|
$externalUrl = $msResult['web_link'] ?? 'https://outlook.office.com';
|
||||||
$timeBlockStart = $msResult['start_time'] ?? $timeBlockStart;
|
$timeBlockStart = $msResult['start_time'] ?? $timeBlockStart;
|
||||||
|
<<<<<<< HEAD
|
||||||
$timeBlockEnd = $msResult['end_time'] ?? $timeBlockEnd;
|
$timeBlockEnd = $msResult['end_time'] ?? $timeBlockEnd;
|
||||||
|
=======
|
||||||
|
$timeBlockEnd = $msResult['end_time'] ?? null;
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
} else {
|
} else {
|
||||||
$outlookSyncError = $msResult['error'] ?? 'Kon afspraak niet aanmaken in Microsoft Outlook';
|
$outlookSyncError = $msResult['error'] ?? 'Kon afspraak niet aanmaken in Microsoft Outlook';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
// Bereken timeBlockEnd indien nog niet gezet maar wel starttijd bekend
|
||||||
|
if (!empty($timeBlockStart) && empty($timeBlockEnd)) {
|
||||||
|
try {
|
||||||
|
$dtEnd = new DateTime("{$date} {$timeBlockStart}:00", new DateTimeZone('Europe/Amsterdam'));
|
||||||
|
$dtEnd->modify("+{$durationMinutes} minutes");
|
||||||
|
$timeBlockEnd = $dtEnd->format('H:i');
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// negeer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
$stmt = $db->prepare("
|
$stmt = $db->prepare("
|
||||||
INSERT INTO tasks (user_id, daily_plan_id, title, priority, time_block_start, time_block_end, duration_minutes, status, source, external_id, external_url)
|
INSERT INTO tasks (user_id, daily_plan_id, title, priority, time_block_start, time_block_end, duration_minutes, status, source, external_id, external_url)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, 'TODO', ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, 'TODO', ?, ?, ?)
|
||||||
@@ -127,14 +162,13 @@ try {
|
|||||||
'time_block_start' => $timeBlockStart,
|
'time_block_start' => $timeBlockStart,
|
||||||
'time_block_end' => $timeBlockEnd,
|
'time_block_end' => $timeBlockEnd,
|
||||||
'duration_minutes' => $durationMinutes,
|
'duration_minutes' => $durationMinutes,
|
||||||
'is_completed' => 0,
|
<<<<<<< HEAD
|
||||||
'status' => 'TODO',
|
|
||||||
'source' => $source,
|
'source' => $source,
|
||||||
'external_id' => $externalId,
|
'external_id' => $externalId,
|
||||||
'external_url' => $externalUrl,
|
'external_url' => $externalUrl
|
||||||
],
|
],
|
||||||
'outlook_synced' => ($source === 'OUTLOOK' && !empty($externalId)),
|
'outlook_synced' => ($source === 'OUTLOOK' && !empty($externalId)),
|
||||||
'outlook_error' => $outlookSyncError,
|
'outlook_error' => $outlookSyncError
|
||||||
]);
|
]);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@@ -214,6 +248,16 @@ try {
|
|||||||
'time_block_start' => $timeBlockStart,
|
'time_block_start' => $timeBlockStart,
|
||||||
'time_block_end' => $timeBlockEnd,
|
'time_block_end' => $timeBlockEnd,
|
||||||
'duration_minutes' => $durationMinutes
|
'duration_minutes' => $durationMinutes
|
||||||
|
=======
|
||||||
|
'is_completed' => 0,
|
||||||
|
'status' => 'TODO',
|
||||||
|
'source' => $source,
|
||||||
|
'external_id' => $externalId,
|
||||||
|
'external_url' => $externalUrl,
|
||||||
|
],
|
||||||
|
'outlook_synced' => ($source === 'OUTLOOK' && !empty($externalId)),
|
||||||
|
'outlook_error' => $outlookSyncError,
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
]);
|
]);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@@ -256,7 +300,10 @@ try {
|
|||||||
|
|
||||||
$planDate = $task['plan_date'] ?: $today;
|
$planDate = $task['plan_date'] ?: $today;
|
||||||
$startTime = !empty($task['time_block_start']) ? $task['time_block_start'] : ($data['time_block_start'] ?? '09:00');
|
$startTime = !empty($task['time_block_start']) ? $task['time_block_start'] : ($data['time_block_start'] ?? '09:00');
|
||||||
|
<<<<<<< HEAD
|
||||||
$endTime = !empty($task['time_block_end']) ? $task['time_block_end'] : null;
|
$endTime = !empty($task['time_block_end']) ? $task['time_block_end'] : null;
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
$duration = (int)($task['duration_minutes'] ?: 30);
|
$duration = (int)($task['duration_minutes'] ?: 30);
|
||||||
|
|
||||||
$msResult = microsoft_create_event($user['id'], [
|
$msResult = microsoft_create_event($user['id'], [
|
||||||
@@ -264,7 +311,10 @@ try {
|
|||||||
'description' => "Gepland via Fociz Dagplanning (" . $task['priority'] . ")",
|
'description' => "Gepland via Fociz Dagplanning (" . $task['priority'] . ")",
|
||||||
'date' => $planDate,
|
'date' => $planDate,
|
||||||
'start_time' => $startTime,
|
'start_time' => $startTime,
|
||||||
|
<<<<<<< HEAD
|
||||||
'end_time' => $endTime,
|
'end_time' => $endTime,
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
'duration_minutes' => $duration,
|
'duration_minutes' => $duration,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -344,6 +394,7 @@ try {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
// 6. Realtime Outlook synchronisatie & controle op gewijzigde/gewiste items
|
// 6. Realtime Outlook synchronisatie & controle op gewijzigde/gewiste items
|
||||||
if ($action === 'check_outlook_sync') {
|
if ($action === 'check_outlook_sync') {
|
||||||
$rawInput = file_get_contents('php://input');
|
$rawInput = file_get_contents('php://input');
|
||||||
@@ -452,6 +503,8 @@ try {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
echo json_encode(['error' => 'Onbekende actie']);
|
echo json_encode(['error' => 'Onbekende actie']);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
http_response_code(500);
|
http_response_code(500);
|
||||||
|
|||||||
@@ -254,10 +254,6 @@
|
|||||||
isFetchingEvents = true;
|
isFetchingEvents = true;
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/notifications.php?action=get_events', { cache: 'no-store' });
|
const res = await fetch('/api/notifications.php?action=get_events', { cache: 'no-store' });
|
||||||
if (res.status === 401) {
|
|
||||||
window.location.href = '/auth/login.php?expired=1';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data && data.success) {
|
if (data && data.success) {
|
||||||
|
|||||||
@@ -27,9 +27,7 @@ if (empty($_SESSION['user_id']) && $stateUserId) {
|
|||||||
$_SESSION['user_email'] = $recoveredUser['email'];
|
$_SESSION['user_email'] = $recoveredUser['email'];
|
||||||
$_SESSION['user_role'] = $recoveredUser['role'];
|
$_SESSION['user_role'] = $recoveredUser['role'];
|
||||||
$_SESSION['is_2fa_verified'] = true;
|
$_SESSION['is_2fa_verified'] = true;
|
||||||
$_SESSION['auth_date'] = date('Y-m-d');
|
issue_remember_token((int)$recoveredUser['id']);
|
||||||
$_SESSION['session_expires_at'] = strtotime('today 23:59:59');
|
|
||||||
clear_remember_cookie();
|
|
||||||
}
|
}
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
// Foutafhandeling
|
// Foutafhandeling
|
||||||
|
|||||||
+2
-4
@@ -75,15 +75,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
|
|
||||||
$db->commit();
|
$db->commit();
|
||||||
|
|
||||||
// Start dagsessie (geldig tot 23:59:59)
|
// Start sessie
|
||||||
$_SESSION['user_id'] = $newUserId;
|
$_SESSION['user_id'] = $newUserId;
|
||||||
$_SESSION['user_name'] = $name;
|
$_SESSION['user_name'] = $name;
|
||||||
$_SESSION['user_email'] = $invite['email'];
|
$_SESSION['user_email'] = $invite['email'];
|
||||||
$_SESSION['user_role'] = $invite['role'];
|
$_SESSION['user_role'] = $invite['role'];
|
||||||
$_SESSION['is_2fa_verified'] = true;
|
$_SESSION['is_2fa_verified'] = true;
|
||||||
$_SESSION['auth_date'] = date('Y-m-d');
|
issue_remember_token($newUserId);
|
||||||
$_SESSION['session_expires_at'] = strtotime('today 23:59:59');
|
|
||||||
clear_remember_cookie();
|
|
||||||
unset($_SESSION['invite_totp_secret']);
|
unset($_SESSION['invite_totp_secret']);
|
||||||
|
|
||||||
header('Location: /planner.php');
|
header('Location: /planner.php');
|
||||||
|
|||||||
+3
-16
@@ -20,10 +20,6 @@ if ($currentUser) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$error = null;
|
$error = null;
|
||||||
$infoMessage = null;
|
|
||||||
if (isset($_GET['expired'])) {
|
|
||||||
$infoMessage = "Uw dagsessie is om 23:59 beëindigd. Log opnieuw in om een nieuwe werkdag te starten.";
|
|
||||||
}
|
|
||||||
$step = isset($_SESSION['pending_2fa_user_id']) ? 2 : 1;
|
$step = isset($_SESSION['pending_2fa_user_id']) ? 2 : 1;
|
||||||
|
|
||||||
// Terug naar stap 1
|
// Terug naar stap 1
|
||||||
@@ -99,17 +95,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($isValid) {
|
if ($isValid) {
|
||||||
// Volledige login succesvol (geldig tot 23:59:59 van vandaag)
|
// Volledige login succesvol
|
||||||
$_SESSION['user_id'] = $user['id'];
|
$_SESSION['user_id'] = $user['id'];
|
||||||
$_SESSION['user_name'] = $user['name'];
|
$_SESSION['user_name'] = $user['name'];
|
||||||
$_SESSION['user_email'] = $user['email'];
|
$_SESSION['user_email'] = $user['email'];
|
||||||
$_SESSION['user_role'] = $user['role'];
|
$_SESSION['user_role'] = $user['role'];
|
||||||
$_SESSION['is_2fa_verified'] = true;
|
$_SESSION['is_2fa_verified'] = true;
|
||||||
$_SESSION['auth_date'] = date('Y-m-d');
|
|
||||||
$_SESSION['session_expires_at'] = strtotime('today 23:59:59');
|
|
||||||
|
|
||||||
// Zorg dat er geen persistente remember cookies worden gebruikt
|
// Activeer persistente remember token (30 dagen blijf ingelogd)
|
||||||
clear_remember_cookie();
|
issue_remember_token((int)$user['id']);
|
||||||
|
|
||||||
unset($_SESSION['pending_2fa_user_id'], $_SESSION['pending_2fa_user_email'], $_SESSION['pending_2fa_user_name']);
|
unset($_SESSION['pending_2fa_user_id'], $_SESSION['pending_2fa_user_email'], $_SESSION['pending_2fa_user_name']);
|
||||||
|
|
||||||
@@ -184,13 +178,6 @@ $pageTitle = "Fociz — Inloggen";
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($infoMessage): ?>
|
|
||||||
<div class="mb-6 p-4 rounded-2xl bg-sky-500/10 border border-sky-500/30 flex items-start space-x-3 text-sky-800 dark:text-sky-300 text-xs sm:text-sm">
|
|
||||||
<i data-lucide="info" class="w-5 h-5 flex-shrink-0 mt-0.5 text-sky-600 dark:text-sky-400"></i>
|
|
||||||
<span><?= htmlspecialchars($infoMessage) ?></span>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<?php if ($error): ?>
|
<?php if ($error): ?>
|
||||||
<div class="mb-6 p-4 rounded-2xl bg-red-500/10 border border-red-500/30 flex items-start space-x-3 text-red-700 dark:text-red-400 text-sm">
|
<div class="mb-6 p-4 rounded-2xl bg-red-500/10 border border-red-500/30 flex items-start space-x-3 text-red-700 dark:text-red-400 text-sm">
|
||||||
<i data-lucide="alert-triangle" class="w-5 h-5 flex-shrink-0 mt-0.5"></i>
|
<i data-lucide="alert-triangle" class="w-5 h-5 flex-shrink-0 mt-0.5"></i>
|
||||||
|
|||||||
+2
-4
@@ -62,15 +62,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
|
|
||||||
$adminId = (int)$db->lastInsertId();
|
$adminId = (int)$db->lastInsertId();
|
||||||
|
|
||||||
// Automatische dagsessie starten (geldig tot 23:59:59)
|
// Automatische sessie starten
|
||||||
$_SESSION['user_id'] = $adminId;
|
$_SESSION['user_id'] = $adminId;
|
||||||
$_SESSION['user_name'] = $name;
|
$_SESSION['user_name'] = $name;
|
||||||
$_SESSION['user_email'] = $email;
|
$_SESSION['user_email'] = $email;
|
||||||
$_SESSION['user_role'] = 'ADMIN';
|
$_SESSION['user_role'] = 'ADMIN';
|
||||||
$_SESSION['is_2fa_verified'] = true;
|
$_SESSION['is_2fa_verified'] = true;
|
||||||
$_SESSION['auth_date'] = date('Y-m-d');
|
issue_remember_token($adminId);
|
||||||
$_SESSION['session_expires_at'] = strtotime('today 23:59:59');
|
|
||||||
clear_remember_cookie();
|
|
||||||
unset($_SESSION['setup_totp_secret']);
|
unset($_SESSION['setup_totp_secret']);
|
||||||
|
|
||||||
$success = true;
|
$success = true;
|
||||||
|
|||||||
+25
-25
@@ -42,21 +42,21 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
|
|
||||||
<div class="space-y-6 max-w-7xl mx-auto">
|
<div class="space-y-6 max-w-7xl mx-auto">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="fociz-card p-6 sm:p-7 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4 bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-6 sm:p-7 shadow-xs transition">
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center space-x-2 text-indigo-600 dark:text-indigo-400 text-xs font-bold uppercase tracking-wider mb-1">
|
<div class="flex items-center space-x-2 text-indigo-600 dark:text-indigo-400 text-xs font-semibold uppercase tracking-wider mb-1">
|
||||||
<i data-lucide="lightbulb" class="w-4 h-4"></i>
|
<i data-lucide="lightbulb" class="w-4 h-4"></i>
|
||||||
<span>Creatie & Innovatie</span>
|
<span>Creatie & Innovatie</span>
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-2xl sm:text-3xl font-black text-slate-900 dark:text-white tracking-tight">
|
<h1 class="text-2xl sm:text-3xl font-bold text-slate-900 dark:text-white tracking-tight">
|
||||||
Brainstorm Sessies
|
Brainstorm Sessies
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-slate-500 dark:text-slate-400 text-xs sm:text-sm mt-1 max-w-2xl">
|
<p class="text-slate-500 dark:text-slate-400 text-xs sm:text-sm mt-1">
|
||||||
Brainstorm met collega's, verzamel ideeën en knelpunten, en transformeer ze direct tot een werkbare roadmap.
|
Brainstorm met collega's, verzamel ideeën en knelpunten, en transformeer ze direct tot een werkbare roadmap.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onclick="document.getElementById('newSessionModal').classList.remove('hidden')" class="flex items-center space-x-2 px-4 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-bold transition shadow-xs flex-shrink-0 cursor-pointer">
|
<button onclick="document.getElementById('newSessionModal').classList.remove('hidden')" class="flex items-center space-x-2 px-4 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-semibold transition shadow-xs flex-shrink-0 cursor-pointer">
|
||||||
<i data-lucide="plus" class="w-4 h-4"></i>
|
<i data-lucide="plus" class="w-4 h-4"></i>
|
||||||
<span>Nieuwe Sessie Starten</span>
|
<span>Nieuwe Sessie Starten</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -71,25 +71,25 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
<!-- Grid met sessies -->
|
<!-- Grid met sessies -->
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
|
||||||
<?php if (empty($sessions)): ?>
|
<?php if (empty($sessions)): ?>
|
||||||
<div class="col-span-full fociz-card p-12 text-center shadow-xs">
|
<div class="col-span-full bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-12 text-center shadow-xs">
|
||||||
<i data-lucide="lightbulb" class="w-12 h-12 text-slate-300 dark:text-slate-700 mx-auto mb-3"></i>
|
<i data-lucide="lightbulb" class="w-12 h-12 text-slate-300 dark:text-slate-700 mx-auto mb-3"></i>
|
||||||
<h3 class="text-base font-bold text-slate-900 dark:text-white">Nog geen brainstormsessies gestart</h3>
|
<h3 class="text-base font-semibold text-slate-900 dark:text-white">Nog geen brainstormsessies gestart</h3>
|
||||||
<p class="text-xs text-slate-500 dark:text-slate-400 mt-1 max-w-sm mx-auto">
|
<p class="text-xs text-slate-500 dark:text-slate-400 mt-1 max-w-sm mx-auto">
|
||||||
Start uw eerste brainstormsessie om ideeën te verzamelen en ze met één klik om te vormen naar planningsitems.
|
Start uw eerste brainstormsessie om ideeën te verzamelen en ze met één klik om te vormen naar planningsitems.
|
||||||
</p>
|
</p>
|
||||||
<button onclick="document.getElementById('newSessionModal').classList.remove('hidden')" class="mt-4 px-4 py-2 bg-indigo-600 hover:bg-indigo-500 text-white font-bold rounded-xl text-xs transition cursor-pointer shadow-xs">
|
<button onclick="document.getElementById('newSessionModal').classList.remove('hidden')" class="mt-4 px-4 py-2 bg-indigo-600 hover:bg-indigo-500 text-white font-semibold rounded-xl text-xs transition cursor-pointer shadow-xs">
|
||||||
Sessie Starten
|
Sessie Starten
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($sessions as $sess): ?>
|
<?php foreach ($sessions as $sess): ?>
|
||||||
<a href="/brainstorm_canvas.php?id=<?= $sess['id'] ?>" class="group fociz-card-interactive p-5 flex flex-col justify-between hover:border-indigo-400 dark:hover:border-indigo-500/60">
|
<a href="/brainstorm_canvas.php?id=<?= $sess['id'] ?>" class="group bg-white hover:bg-slate-50/70 dark:bg-[#111622] dark:hover:bg-[#151b2a] border border-slate-200/80 hover:border-indigo-300 dark:border-slate-800 dark:hover:border-indigo-700/60 rounded-2xl p-5 shadow-xs hover:shadow-sm transition flex flex-col justify-between">
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center justify-between mb-3">
|
<div class="flex items-center justify-between mb-3">
|
||||||
<span class="px-2.5 py-0.5 rounded-lg bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 text-indigo-700 dark:text-indigo-400 font-semibold text-[11px]">
|
<span class="px-2.5 py-0.5 rounded-md bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 text-indigo-700 dark:text-indigo-400 font-medium text-[11px]">
|
||||||
<?= htmlspecialchars($sess['theme']) ?>
|
<?= htmlspecialchars($sess['theme']) ?>
|
||||||
</span>
|
</span>
|
||||||
<span class="flex items-center space-x-1 text-slate-400 dark:text-slate-500 text-xs font-medium">
|
<span class="flex items-center space-x-1 text-slate-400 dark:text-slate-500 text-xs">
|
||||||
<i data-lucide="message-square" class="w-3.5 h-3.5"></i>
|
<i data-lucide="message-square" class="w-3.5 h-3.5"></i>
|
||||||
<span><?= $sess['cards_count'] ?> kaarten</span>
|
<span><?= $sess['cards_count'] ?> kaarten</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -107,8 +107,8 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-5 pt-4 border-t border-slate-100 dark:border-slate-800/80 flex items-center justify-between text-xs text-slate-500 dark:text-slate-400">
|
<div class="mt-5 pt-4 border-t border-slate-100 dark:border-slate-800/80 flex items-center justify-between text-xs text-slate-500 dark:text-slate-400">
|
||||||
<span class="truncate">Door <?= htmlspecialchars($sess['creator_name']) ?></span>
|
<span>Door <?= htmlspecialchars($sess['creator_name']) ?></span>
|
||||||
<div class="flex items-center space-x-1 text-indigo-600 dark:text-indigo-400 group-hover:translate-x-1 transition font-bold flex-shrink-0 ml-2">
|
<div class="flex items-center space-x-1 text-indigo-600 dark:text-indigo-400 group-hover:translate-x-1 transition font-medium">
|
||||||
<span>Open canvas</span>
|
<span>Open canvas</span>
|
||||||
<i data-lucide="arrow-right" class="w-3.5 h-3.5"></i>
|
<i data-lucide="arrow-right" class="w-3.5 h-3.5"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -120,15 +120,15 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Modal: Nieuwe sessie -->
|
<!-- Modal: Nieuwe sessie -->
|
||||||
<div id="newSessionModal" class="hidden fixed inset-0 z-50 bg-slate-950/70 backdrop-blur-sm flex items-center justify-center p-4">
|
<div id="newSessionModal" class="hidden fixed inset-0 z-50 bg-slate-950/60 backdrop-blur-xs flex items-center justify-center p-4">
|
||||||
<div class="fociz-card p-6 sm:p-7 shadow-2xl max-w-lg w-full space-y-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800 rounded-2xl p-6 sm:p-7 shadow-xl max-w-lg w-full transition">
|
||||||
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800">
|
<div class="flex items-center justify-between mb-4 pb-3 border-b border-slate-100 dark:border-slate-800">
|
||||||
<h3 class="text-sm font-bold text-slate-900 dark:text-white flex items-center space-x-2">
|
<h3 class="text-sm font-semibold text-slate-900 dark:text-white flex items-center space-x-2">
|
||||||
<i data-lucide="sparkles" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="sparkles" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<span>Nieuwe Brainstormsessie</span>
|
<span>Nieuwe Brainstormsessie</span>
|
||||||
</h3>
|
</h3>
|
||||||
<button onclick="document.getElementById('newSessionModal').classList.add('hidden')" class="p-1.5 text-slate-400 hover:text-slate-600 dark:hover:text-white rounded-lg hover:bg-slate-100 dark:hover:bg-slate-800 transition cursor-pointer">
|
<button onclick="document.getElementById('newSessionModal').classList.add('hidden')" class="text-slate-400 hover:text-slate-600 dark:hover:text-white cursor-pointer">
|
||||||
<i data-lucide="x" class="w-4 h-4"></i>
|
<i data-lucide="x" class="w-5 h-5"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -137,13 +137,13 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Onderwerp / Titel</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Onderwerp / Titel</label>
|
||||||
<input type="text" name="title" required placeholder="Bijv. Q4 Automatisering & Klantreis" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3.5 py-2.5 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<input type="text" name="title" required placeholder="Bijv. Q4 Automatisering & Klantreis" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3.5 py-2.5 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Thema / Categorie</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Thema / Categorie</label>
|
||||||
<select name="theme" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select name="theme" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="Product & Strategie">Product & Strategie</option>
|
<option value="Product & Strategie">Product & Strategie</option>
|
||||||
<option value="Procesverbetering">Procesverbetering</option>
|
<option value="Procesverbetering">Procesverbetering</option>
|
||||||
<option value="Klant & Service">Klant & Service</option>
|
<option value="Klant & Service">Klant & Service</option>
|
||||||
@@ -153,15 +153,15 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Doel / Beschrijving</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Doel / Beschrijving</label>
|
||||||
<input type="text" name="description" placeholder="Doel van deze sessie..." class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3.5 py-2 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<input type="text" name="description" placeholder="Doel van deze sessie..." class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3.5 py-2 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex space-x-2 pt-2 border-t border-slate-100 dark:border-slate-800/80">
|
<div class="flex space-x-2 pt-2">
|
||||||
<button type="submit" class="flex-1 bg-indigo-600 hover:bg-indigo-500 text-white font-bold py-2.5 px-4 rounded-xl text-xs transition cursor-pointer shadow-xs">
|
<button type="submit" class="flex-1 bg-indigo-600 hover:bg-indigo-500 text-white font-semibold py-2.5 px-4 rounded-xl text-xs transition cursor-pointer shadow-xs">
|
||||||
Sessie Aanmaken & Canvas Openen
|
Sessie Aanmaken & Canvas Openen
|
||||||
</button>
|
</button>
|
||||||
<button type="button" onclick="document.getElementById('newSessionModal').classList.add('hidden')" class="px-4 py-2.5 bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl text-xs font-semibold transition cursor-pointer">
|
<button type="button" onclick="document.getElementById('newSessionModal').classList.add('hidden')" class="px-4 py-2.5 bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl text-xs transition cursor-pointer">
|
||||||
Annuleren
|
Annuleren
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+41
-41
@@ -71,19 +71,19 @@ $categories = [
|
|||||||
|
|
||||||
<div class="space-y-6 max-w-7xl mx-auto">
|
<div class="space-y-6 max-w-7xl mx-auto">
|
||||||
<!-- Top Bar -->
|
<!-- Top Bar -->
|
||||||
<div class="fociz-card p-5 flex flex-col lg:flex-row lg:items-center justify-between gap-4">
|
<div class="flex flex-col lg:flex-row lg:items-center justify-between gap-4 bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-5 shadow-xs transition">
|
||||||
<div class="flex items-center space-x-4">
|
<div class="flex items-center space-x-4">
|
||||||
<a href="/brainstorm.php" class="p-2.5 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition cursor-pointer">
|
<a href="/brainstorm.php" class="p-2.5 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white transition cursor-pointer">
|
||||||
<i data-lucide="arrow-left" class="w-5 h-5"></i>
|
<i data-lucide="arrow-left" class="w-5 h-5"></i>
|
||||||
</a>
|
</a>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center space-x-2 text-xs">
|
<div class="flex items-center space-x-2 text-xs">
|
||||||
<span class="px-2.5 py-0.5 rounded-lg bg-indigo-50 dark:bg-indigo-500/10 text-indigo-700 dark:text-indigo-400 font-bold border border-indigo-200 dark:border-indigo-500/20">
|
<span class="px-2.5 py-0.5 rounded-md bg-indigo-50 dark:bg-indigo-500/10 text-indigo-700 dark:text-indigo-400 font-semibold border border-indigo-200 dark:border-indigo-500/20">
|
||||||
<?= htmlspecialchars($session['theme']) ?>
|
<?= htmlspecialchars($session['theme']) ?>
|
||||||
</span>
|
</span>
|
||||||
<span class="text-slate-400 dark:text-slate-500">Gestart door <?= htmlspecialchars($session['creator_name']) ?></span>
|
<span class="text-slate-400 dark:text-slate-500">Gestart door <?= htmlspecialchars($session['creator_name']) ?></span>
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-xl sm:text-2xl font-black text-slate-900 dark:text-white tracking-tight mt-0.5">
|
<h1 class="text-xl sm:text-2xl font-bold text-slate-900 dark:text-white tracking-tight mt-0.5">
|
||||||
<?= htmlspecialchars($session['title']) ?>
|
<?= htmlspecialchars($session['title']) ?>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,24 +91,24 @@ $categories = [
|
|||||||
|
|
||||||
<div class="flex flex-wrap items-center gap-2.5">
|
<div class="flex flex-wrap items-center gap-2.5">
|
||||||
<?php if ($aiSettings['ai_enabled'] && $aiSettings['has_key']): ?>
|
<?php if ($aiSettings['ai_enabled'] && $aiSettings['has_key']): ?>
|
||||||
<button onclick="aiGenerateIdeas(this)" class="flex items-center space-x-1.5 px-3 py-2 rounded-xl bg-violet-50 hover:bg-violet-100 dark:bg-violet-950/50 dark:hover:bg-violet-900/50 text-violet-700 dark:text-violet-300 border border-violet-200 dark:border-violet-800/60 text-xs font-bold transition cursor-pointer shadow-xs" title="Genereer 4 innovatieve ideeën via AI Co-Pilot">
|
<button onclick="aiGenerateIdeas(this)" class="flex items-center space-x-1.5 px-3 py-2 rounded-xl bg-violet-50 hover:bg-violet-100 dark:bg-violet-950/50 dark:hover:bg-violet-900/50 text-violet-700 dark:text-violet-300 border border-violet-200 dark:border-violet-800/60 text-xs font-semibold transition cursor-pointer shadow-xs" title="Genereer 4 innovatieve ideeën via AI Co-Pilot">
|
||||||
<i data-lucide="sparkles" class="w-4 h-4 text-violet-500"></i>
|
<i data-lucide="sparkles" class="w-4 h-4 text-violet-500"></i>
|
||||||
<span>💡 AI Ideeën</span>
|
<span>💡 AI Ideeën</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button onclick="aiCategorizeCards(this)" class="flex items-center space-x-1.5 px-3 py-2 rounded-xl bg-indigo-50 hover:bg-indigo-100 dark:bg-indigo-950/50 dark:hover:bg-indigo-900/50 text-indigo-700 dark:text-indigo-300 border border-indigo-200 dark:border-indigo-800/60 text-xs font-bold transition cursor-pointer shadow-xs" title="Sorteer alle kaartjes automatisch in Ideeën, Knelpunten, Oplossingen of Quick Wins">
|
<button onclick="aiCategorizeCards(this)" class="flex items-center space-x-1.5 px-3 py-2 rounded-xl bg-indigo-50 hover:bg-indigo-100 dark:bg-indigo-950/50 dark:hover:bg-indigo-900/50 text-indigo-700 dark:text-indigo-300 border border-indigo-200 dark:border-indigo-800/60 text-xs font-semibold transition cursor-pointer shadow-xs" title="Sorteer alle kaartjes automatisch in Ideeën, Knelpunten, Oplossingen of Quick Wins">
|
||||||
<i data-lucide="wand-2" class="w-4 h-4 text-indigo-500"></i>
|
<i data-lucide="wand-2" class="w-4 h-4 text-indigo-500"></i>
|
||||||
<span>✨ Auto-Categoriseer</span>
|
<span>✨ Auto-Categoriseer</span>
|
||||||
</button>
|
</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<button onclick="openAddCardModal()" class="flex items-center space-x-1.5 px-3.5 py-2 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-200 text-xs font-bold border border-slate-200 dark:border-slate-700 transition cursor-pointer shadow-xs">
|
<button onclick="openAddCardModal()" class="flex items-center space-x-1.5 px-3.5 py-2 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-200 text-xs font-semibold border border-slate-200 dark:border-slate-700 transition cursor-pointer shadow-xs">
|
||||||
<i data-lucide="plus" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="plus" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<span>Nieuwe Kaart</span>
|
<span>Nieuwe Kaart</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- De Kernfeature: Zet om naar Roadmap! -->
|
<!-- De Kernfeature: Zet om naar Roadmap! -->
|
||||||
<button onclick="openConvertModal()" class="flex items-center space-x-2 px-4 py-2 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-bold transition shadow-xs cursor-pointer">
|
<button onclick="openConvertModal()" class="flex items-center space-x-2 px-4 py-2 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-semibold transition shadow-xs cursor-pointer">
|
||||||
<i data-lucide="map" class="w-4 h-4"></i>
|
<i data-lucide="map" class="w-4 h-4"></i>
|
||||||
<span>Zet om naar Roadmap</span>
|
<span>Zet om naar Roadmap</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -120,14 +120,14 @@ $categories = [
|
|||||||
<?php foreach ($categories as $catKey => $catConfig):
|
<?php foreach ($categories as $catKey => $catConfig):
|
||||||
$catCards = array_filter($cards, fn($c) => $c['category'] === $catKey);
|
$catCards = array_filter($cards, fn($c) => $c['category'] === $catKey);
|
||||||
?>
|
?>
|
||||||
<div class="fociz-card p-4 flex flex-col min-h-[500px]">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-4 flex flex-col min-h-[500px] shadow-xs transition">
|
||||||
<!-- Column Header -->
|
<!-- Column Header -->
|
||||||
<div class="flex items-center justify-between pb-3 mb-3 border-b border-slate-100 dark:border-slate-800">
|
<div class="flex items-center justify-between pb-3 mb-3 border-b border-slate-100 dark:border-slate-800">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<i data-lucide="<?= $catConfig['icon'] ?>" class="w-4 h-4 text-<?= $catConfig['color'] ?>-500"></i>
|
<i data-lucide="<?= $catConfig['icon'] ?>" class="w-4 h-4 text-<?= $catConfig['color'] ?>-500"></i>
|
||||||
<h3 class="text-xs font-bold text-slate-900 dark:text-white uppercase tracking-wider"><?= $catConfig['title'] ?></h3>
|
<h3 class="text-xs font-semibold text-slate-900 dark:text-white uppercase tracking-wider"><?= $catConfig['title'] ?></h3>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-xs font-mono font-bold px-2 py-0.5 rounded-full bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-400 border border-slate-200 dark:border-slate-700">
|
<span class="text-xs font-mono font-semibold px-2 py-0.5 rounded-full bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-400">
|
||||||
<?= count($catCards) ?>
|
<?= count($catCards) ?>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -135,22 +135,22 @@ $categories = [
|
|||||||
<!-- Cards Container -->
|
<!-- Cards Container -->
|
||||||
<div class="flex-1 space-y-3">
|
<div class="flex-1 space-y-3">
|
||||||
<?php if (empty($catCards)): ?>
|
<?php if (empty($catCards)): ?>
|
||||||
<div class="py-8 text-center text-slate-400 dark:text-slate-600 text-xs font-medium">
|
<div class="py-8 text-center text-slate-400 dark:text-slate-600 text-xs">
|
||||||
Nog geen kaarten in deze categorie.
|
Nog geen kaarten in deze categorie.
|
||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($catCards as $card): ?>
|
<?php foreach ($catCards as $card): ?>
|
||||||
<div class="group relative rounded-xl p-4 border <?= $catConfig['border'] ?> <?= $catConfig['bg'] ?> backdrop-blur-sm shadow-2xs transition hover:-translate-y-0.5" id="card-<?= $card['id'] ?>">
|
<div class="group relative rounded-xl p-4 border <?= $catConfig['border'] ?> <?= $catConfig['bg'] ?> backdrop-blur-sm shadow-xs transition hover:-translate-y-0.5" id="card-<?= $card['id'] ?>">
|
||||||
|
|
||||||
<!-- Top: Checkbox voor selectie + Roadmap badge -->
|
<!-- Top: Checkbox voor selectie + Roadmap badge -->
|
||||||
<div class="flex items-center justify-between mb-2">
|
<div class="flex items-center justify-between mb-2">
|
||||||
<label class="flex items-center space-x-2 cursor-pointer">
|
<label class="flex items-center space-x-2 cursor-pointer">
|
||||||
<input type="checkbox" value="<?= $card['id'] ?>" data-content="<?= htmlspecialchars($card['content'], ENT_QUOTES) ?>" class="card-checkbox w-4 h-4 rounded bg-white dark:bg-slate-900 border-slate-300 dark:border-slate-700 text-indigo-600 focus:ring-0">
|
<input type="checkbox" value="<?= $card['id'] ?>" data-content="<?= htmlspecialchars($card['content'], ENT_QUOTES) ?>" class="card-checkbox w-4 h-4 rounded bg-white dark:bg-slate-900 border-slate-300 dark:border-slate-700 text-indigo-600 focus:ring-0">
|
||||||
<span class="text-[10px] text-slate-500 dark:text-slate-400 font-medium">Selecteer</span>
|
<span class="text-[10px] text-slate-500 dark:text-slate-400">Selecteer</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<?php if (!empty($card['converted_to_roadmap_item_id'])): ?>
|
<?php if (!empty($card['converted_to_roadmap_item_id'])): ?>
|
||||||
<span class="px-2 py-0.5 rounded-md bg-teal-50 dark:bg-teal-500/15 text-teal-700 dark:text-teal-400 font-bold text-[10px] flex items-center space-x-1 border border-teal-200 dark:border-teal-500/20">
|
<span class="px-2 py-0.5 rounded-md bg-teal-50 dark:bg-teal-500/15 text-teal-700 dark:text-teal-400 font-semibold text-[10px] flex items-center space-x-1 border border-teal-200 dark:border-teal-500/20">
|
||||||
<i data-lucide="check" class="w-3 h-3"></i>
|
<i data-lucide="check" class="w-3 h-3"></i>
|
||||||
<span>Op Roadmap</span>
|
<span>Op Roadmap</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -185,7 +185,7 @@ $categories = [
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Quick add button at column bottom -->
|
<!-- Quick add button at column bottom -->
|
||||||
<button onclick="openAddCardModal('<?= $catKey ?>')" class="mt-3 w-full py-2 rounded-xl border border-dashed border-slate-200 dark:border-slate-800 hover:border-indigo-300 dark:hover:border-indigo-700/60 text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 text-xs font-semibold transition flex items-center justify-center space-x-1 cursor-pointer">
|
<button onclick="openAddCardModal('<?= $catKey ?>')" class="mt-3 w-full py-2 rounded-xl border border-dashed border-slate-200 dark:border-slate-800 hover:border-indigo-300 dark:hover:border-indigo-700/60 text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 text-xs transition flex items-center justify-center space-x-1 cursor-pointer">
|
||||||
<i data-lucide="plus" class="w-3.5 h-3.5"></i>
|
<i data-lucide="plus" class="w-3.5 h-3.5"></i>
|
||||||
<span>Kaart toevoegen</span>
|
<span>Kaart toevoegen</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -195,22 +195,22 @@ $categories = [
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Modal: Nieuwe Kaart Toevoegen -->
|
<!-- Modal: Nieuwe Kaart Toevoegen -->
|
||||||
<div id="addCardModal" class="hidden fixed inset-0 z-50 bg-slate-950/70 backdrop-blur-sm flex items-center justify-center p-4">
|
<div id="addCardModal" class="hidden fixed inset-0 z-50 bg-slate-950/60 backdrop-blur-xs flex items-center justify-center p-4">
|
||||||
<div class="fociz-card p-6 shadow-2xl max-w-md w-full space-y-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800 rounded-2xl p-6 shadow-xl max-w-md w-full transition">
|
||||||
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800">
|
<div class="flex items-center justify-between mb-4 pb-3 border-b border-slate-100 dark:border-slate-800">
|
||||||
<h3 class="text-sm font-bold text-slate-900 dark:text-white flex items-center space-x-2">
|
<h3 class="text-sm font-semibold text-slate-900 dark:text-white flex items-center space-x-2">
|
||||||
<i data-lucide="sticky-note" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="sticky-note" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<span>Brainstormkaart Toevoegen</span>
|
<span>Brainstormkaart Toevoegen</span>
|
||||||
</h3>
|
</h3>
|
||||||
<button onclick="closeAddCardModal()" class="p-1.5 text-slate-400 hover:text-slate-600 dark:hover:text-white rounded-lg hover:bg-slate-100 dark:hover:bg-slate-800 transition cursor-pointer">
|
<button onclick="closeAddCardModal()" class="text-slate-400 hover:text-slate-600 dark:hover:text-white cursor-pointer">
|
||||||
<i data-lucide="x" class="w-4 h-4"></i>
|
<i data-lucide="x" class="w-5 h-5"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Categorie</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Categorie</label>
|
||||||
<select id="modalCardCategory" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select id="modalCardCategory" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="Ideeën">💡 Ideeën & Concepten</option>
|
<option value="Ideeën">💡 Ideeën & Concepten</option>
|
||||||
<option value="Knelpunten">⚠️ Knelpunten & Uitdagingen</option>
|
<option value="Knelpunten">⚠️ Knelpunten & Uitdagingen</option>
|
||||||
<option value="Oplossingen">🚀 Oplossingen & Features</option>
|
<option value="Oplossingen">🚀 Oplossingen & Features</option>
|
||||||
@@ -220,14 +220,14 @@ $categories = [
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Idee / Beschrijving</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Idee / Beschrijving</label>
|
||||||
<textarea id="modalCardContent" rows="4" placeholder="Schrijf hier uw inzicht, idee of knelpunt..." class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl p-3 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 resize-none shadow-2xs"></textarea>
|
<textarea id="modalCardContent" rows="4" placeholder="Schrijf hier uw inzicht, idee of knelpunt..." class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl p-3 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 resize-none"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex space-x-2 pt-2 border-t border-slate-100 dark:border-slate-800/80">
|
<div class="flex space-x-2 pt-2">
|
||||||
<button onclick="submitNewCard()" class="flex-1 bg-indigo-600 hover:bg-indigo-500 text-white font-bold py-2.5 px-4 rounded-xl text-xs transition cursor-pointer shadow-xs">
|
<button onclick="submitNewCard()" class="flex-1 bg-indigo-600 hover:bg-indigo-500 text-white font-semibold py-2.5 px-4 rounded-xl text-xs transition cursor-pointer shadow-xs">
|
||||||
Plaats op Canvas
|
Plaats op Canvas
|
||||||
</button>
|
</button>
|
||||||
<button onclick="closeAddCardModal()" class="px-4 py-2.5 bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl text-xs font-semibold transition cursor-pointer">
|
<button onclick="closeAddCardModal()" class="px-4 py-2.5 bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl text-xs transition cursor-pointer">
|
||||||
Annuleren
|
Annuleren
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -236,20 +236,20 @@ $categories = [
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Modal: Zet om naar Roadmap -->
|
<!-- Modal: Zet om naar Roadmap -->
|
||||||
<div id="convertModal" class="hidden fixed inset-0 z-50 bg-slate-950/70 backdrop-blur-sm flex items-center justify-center p-4">
|
<div id="convertModal" class="hidden fixed inset-0 z-50 bg-slate-950/60 backdrop-blur-xs flex items-center justify-center p-4">
|
||||||
<div class="fociz-card p-6 shadow-2xl max-w-lg w-full space-y-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800 rounded-2xl p-6 shadow-xl max-w-lg w-full transition">
|
||||||
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800">
|
<div class="flex items-center justify-between mb-4 pb-3 border-b border-slate-100 dark:border-slate-800">
|
||||||
<h3 class="text-sm font-bold text-slate-900 dark:text-white flex items-center space-x-2">
|
<h3 class="text-sm font-semibold text-slate-900 dark:text-white flex items-center space-x-2">
|
||||||
<i data-lucide="map" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="map" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<span>Zet Brainstorm om naar Roadmap</span>
|
<span>Zet Brainstorm om naar Roadmap</span>
|
||||||
</h3>
|
</h3>
|
||||||
<button onclick="closeConvertModal()" class="p-1.5 text-slate-400 hover:text-slate-600 dark:hover:text-white rounded-lg hover:bg-slate-100 dark:hover:bg-slate-800 transition cursor-pointer">
|
<button onclick="closeConvertModal()" class="text-slate-400 hover:text-slate-600 dark:hover:text-white cursor-pointer">
|
||||||
<i data-lucide="x" class="w-4 h-4"></i>
|
<i data-lucide="x" class="w-5 h-5"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div class="bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 rounded-xl p-3 text-xs text-indigo-800 dark:text-indigo-300 font-semibold">
|
<div class="bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 rounded-xl p-3 text-xs text-indigo-800 dark:text-indigo-300">
|
||||||
<span id="selectedCountText" class="font-bold">0</span> kaarten geselecteerd om om te zetten naar planbare roadmap items.
|
<span id="selectedCountText" class="font-bold">0</span> kaarten geselecteerd om om te zetten naar planbare roadmap items.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -259,7 +259,7 @@ $categories = [
|
|||||||
<i data-lucide="sparkles" class="w-4 h-4 text-violet-500 flex-shrink-0"></i>
|
<i data-lucide="sparkles" class="w-4 h-4 text-violet-500 flex-shrink-0"></i>
|
||||||
<span class="text-[11px] font-medium leading-tight">Laat AI Co-Pilot kwartaal, type & prioriteit adviseren</span>
|
<span class="text-[11px] font-medium leading-tight">Laat AI Co-Pilot kwartaal, type & prioriteit adviseren</span>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" onclick="aiSuggestRoadmapMeta(this)" id="aiSuggestBtn" class="px-2.5 py-1 bg-violet-600 hover:bg-violet-700 text-white rounded-lg text-xs font-bold transition flex items-center space-x-1 cursor-pointer flex-shrink-0 shadow-xs">
|
<button type="button" onclick="aiSuggestRoadmapMeta(this)" id="aiSuggestBtn" class="px-2.5 py-1 bg-violet-600 hover:bg-violet-700 text-white rounded-lg text-xs font-semibold transition flex items-center space-x-1 cursor-pointer flex-shrink-0 shadow-xs">
|
||||||
<span>✨ AI Advies</span>
|
<span>✨ AI Advies</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -268,7 +268,7 @@ $categories = [
|
|||||||
<div class="grid grid-cols-2 gap-3">
|
<div class="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Doel Kwartaal</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Doel Kwartaal</label>
|
||||||
<select id="roadmapQuarter" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select id="roadmapQuarter" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="Q1">Q1 (Jan - Mrt)</option>
|
<option value="Q1">Q1 (Jan - Mrt)</option>
|
||||||
<option value="Q2">Q2 (Apr - Jun)</option>
|
<option value="Q2">Q2 (Apr - Jun)</option>
|
||||||
<option value="Q3" selected>Q3 (Jul - Sep)</option>
|
<option value="Q3" selected>Q3 (Jul - Sep)</option>
|
||||||
@@ -278,7 +278,7 @@ $categories = [
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Item Type</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Item Type</label>
|
||||||
<select id="roadmapType" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select id="roadmapType" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="FEATURE" selected>Feature / Functionaliteit</option>
|
<option value="FEATURE" selected>Feature / Functionaliteit</option>
|
||||||
<option value="EPIC">Epic (Groot project)</option>
|
<option value="EPIC">Epic (Groot project)</option>
|
||||||
<option value="MILESTONE">Mijlpaal</option>
|
<option value="MILESTONE">Mijlpaal</option>
|
||||||
@@ -290,7 +290,7 @@ $categories = [
|
|||||||
<div class="grid grid-cols-2 gap-3">
|
<div class="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Prioriteit</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Prioriteit</label>
|
||||||
<select id="roadmapPriority" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select id="roadmapPriority" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="HIGH" selected>Hoog (Belangrijke milestone)</option>
|
<option value="HIGH" selected>Hoog (Belangrijke milestone)</option>
|
||||||
<option value="CRITICAL">Kritiek (Must-have)</option>
|
<option value="CRITICAL">Kritiek (Must-have)</option>
|
||||||
<option value="MEDIUM">Normaal</option>
|
<option value="MEDIUM">Normaal</option>
|
||||||
@@ -300,16 +300,16 @@ $categories = [
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Streefdatum (Deadline)</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Streefdatum (Deadline)</label>
|
||||||
<input type="date" id="roadmapDueDate" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-1.5 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<input type="date" id="roadmapDueDate" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-1.5 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex space-x-2 pt-2 border-t border-slate-100 dark:border-slate-800/80">
|
<div class="flex space-x-2 pt-2">
|
||||||
<button onclick="submitConvertToRoadmap()" class="flex-1 bg-indigo-600 hover:bg-indigo-500 text-white font-bold py-2.5 px-4 rounded-xl text-xs transition shadow-xs flex items-center justify-center space-x-2 cursor-pointer">
|
<button onclick="submitConvertToRoadmap()" class="flex-1 bg-indigo-600 hover:bg-indigo-500 text-white font-semibold py-2.5 px-4 rounded-xl text-xs transition shadow-xs flex items-center justify-center space-x-2 cursor-pointer">
|
||||||
<i data-lucide="check-circle" class="w-4 h-4"></i>
|
<i data-lucide="check-circle" class="w-4 h-4"></i>
|
||||||
<span>Definitief Toevoegen aan Roadmap</span>
|
<span>Definitief Toevoegen aan Roadmap</span>
|
||||||
</button>
|
</button>
|
||||||
<button onclick="closeConvertModal()" class="px-4 py-2.5 bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl text-xs font-semibold transition cursor-pointer">
|
<button onclick="closeConvertModal()" class="px-4 py-2.5 bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl text-xs transition cursor-pointer">
|
||||||
Annuleren
|
Annuleren
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
# MariaDB Verbinding
|
|
||||||
DB_HOST="192.168.2.33"
|
|
||||||
DB_PORT="3306"
|
|
||||||
DB_NAME="focizdev"
|
|
||||||
DB_USER="focizdev_user"
|
|
||||||
DB_PASS="F0c1z_Dev_Secure_2026!"
|
|
||||||
|
|
||||||
# Omgeving: 'development' (knippert rood) of 'live' (knippert groen)
|
|
||||||
APP_ENV="development"
|
|
||||||
|
|
||||||
# Applicatie URL (voor uitnodigingslinks en OAuth redirects: https://dev.fociz.nl of https://fociz.nl)
|
|
||||||
APP_URL="https://dev.fociz.nl"
|
|
||||||
|
|
||||||
# Applicatie Geheime Sleutel (willekeurige tekenreeks)
|
|
||||||
APP_SECRET="fociz-maria-db-super-secret-key-998877"
|
|
||||||
|
|
||||||
# Microsoft 365 / Outlook (Optionele globale defaults; kan ook via web UI worden ingesteld)
|
|
||||||
MICROSOFT_CLIENT_ID=""
|
|
||||||
MICROSOFT_CLIENT_SECRET=""
|
|
||||||
MICROSOFT_TENANT_ID="common"
|
|
||||||
|
|
||||||
# Atlassian Jira Cloud (Optionele globale defaults; kan ook via web UI worden ingesteld)
|
|
||||||
JIRA_DOMAIN=""
|
|
||||||
JIRA_EMAIL=""
|
|
||||||
JIRA_API_TOKEN=""
|
|
||||||
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Fociz Applicatie- en Databaseconfiguratie
|
|
||||||
* Laadt automatisch .env (of .env.example indien .env niet bestaat)
|
|
||||||
*/
|
|
||||||
|
|
||||||
$envVars = [];
|
|
||||||
|
|
||||||
// 1. Zoek naar .env of val terug op config/.env.example
|
|
||||||
$envCandidates = [
|
|
||||||
__DIR__ . '/../.env',
|
|
||||||
__DIR__ . '/.env.example',
|
|
||||||
__DIR__ . '/../.env.example',
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($envCandidates as $envFile) {
|
|
||||||
if (file_exists($envFile)) {
|
|
||||||
$lines = file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
||||||
if ($lines !== false) {
|
|
||||||
foreach ($lines as $line) {
|
|
||||||
$line = trim($line);
|
|
||||||
// Negeer lege regels en commentaarregels (# of //)
|
|
||||||
if ($line === '' || str_starts_with($line, '#') || str_starts_with($line, '//')) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (strpos($line, '=') !== false) {
|
|
||||||
list($name, $value) = explode('=', $line, 2);
|
|
||||||
$name = trim($name);
|
|
||||||
$value = trim($value);
|
|
||||||
// Verwijder omlijstende aanhalingstekens (" of ')
|
|
||||||
$value = trim($value, " \t\n\r\0\x0B\"'");
|
|
||||||
|
|
||||||
// Sla op in array en zet in globale PHP variabelen
|
|
||||||
$envVars[$name] = $value;
|
|
||||||
$_ENV[$name] = $value;
|
|
||||||
$_SERVER[$name] = $value;
|
|
||||||
@putenv("{$name}={$value}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break; // Stop zodra we het eerste geldige bestand hebben ingeladen
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Veilige helper om een omgevingsvariabele op te vragen
|
|
||||||
*/
|
|
||||||
if (!function_exists('fociz_env')) {
|
|
||||||
function fociz_env(string $key, $default = null) {
|
|
||||||
global $envVars;
|
|
||||||
if (isset($envVars[$key]) && $envVars[$key] !== '') {
|
|
||||||
return $envVars[$key];
|
|
||||||
}
|
|
||||||
if (isset($_ENV[$key]) && $_ENV[$key] !== '') {
|
|
||||||
return $_ENV[$key];
|
|
||||||
}
|
|
||||||
if (isset($_SERVER[$key]) && $_SERVER[$key] !== '') {
|
|
||||||
return $_SERVER[$key];
|
|
||||||
}
|
|
||||||
$val = @getenv($key);
|
|
||||||
if ($val !== false && $val !== '') {
|
|
||||||
return $val;
|
|
||||||
}
|
|
||||||
return $default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MariaDB Verbindingsgegevens (uit .env of .env.example)
|
|
||||||
define('DB_HOST', fociz_env('DB_HOST', '192.168.2.33'));
|
|
||||||
define('DB_PORT', fociz_env('DB_PORT', '3306'));
|
|
||||||
define('DB_NAME', fociz_env('DB_NAME', 'focizdev'));
|
|
||||||
define('DB_USER', fociz_env('DB_USER', 'focizdev_user'));
|
|
||||||
define('DB_PASS', fociz_env('DB_PASS', 'F0c1z_Dev_Secure_2026!'));
|
|
||||||
define('DB_CHARSET', 'utf8mb4');
|
|
||||||
|
|
||||||
// Bepaal de dynamische of geconfigureerde applicatie URL
|
|
||||||
if (!function_exists('fociz_detect_app_url')) {
|
|
||||||
function fociz_detect_app_url(): string {
|
|
||||||
$envUrl = fociz_env('APP_URL');
|
|
||||||
if (!empty($envUrl) && !str_contains($envUrl, 'uw-domein.nl') && !str_contains($envUrl, 'www.fociz.nl')) {
|
|
||||||
return rtrim($envUrl, '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dynamische detectie op basis van het huidige domein (werkt direct op dev.fociz.nl én fociz.nl)
|
|
||||||
if (!empty($_SERVER['HTTP_HOST'])) {
|
|
||||||
$isHttps = (
|
|
||||||
(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ||
|
|
||||||
(!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') ||
|
|
||||||
(!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'on') ||
|
|
||||||
(isset($_SERVER['SERVER_PORT']) && (int)$_SERVER['SERVER_PORT'] === 443)
|
|
||||||
);
|
|
||||||
$scheme = $isHttps ? 'https://' : 'http://';
|
|
||||||
return $scheme . $_SERVER['HTTP_HOST'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Standaard fallback per omgeving
|
|
||||||
return (defined('APP_ENV') && APP_ENV === 'live') ? 'https://fociz.nl' : 'https://dev.fociz.nl';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Applicatie instellingen
|
|
||||||
define('APP_NAME', 'Fociz');
|
|
||||||
define('APP_ENV', fociz_env('APP_ENV', 'development')); // 'development' of 'live'
|
|
||||||
define('APP_URL', fociz_detect_app_url());
|
|
||||||
define('APP_SECRET', fociz_env('APP_SECRET', 'fociz-maria-db-super-secret-key-998877'));
|
|
||||||
|
|
||||||
// Tijdzone
|
|
||||||
date_default_timezone_set('Europe/Amsterdam');
|
|
||||||
|
|
||||||
// Foutrapportage: in development tonen we fouten direct op het scherm
|
|
||||||
if (APP_ENV !== 'live') {
|
|
||||||
ini_set('display_errors', '1');
|
|
||||||
ini_set('display_startup_errors', '1');
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
}
|
|
||||||
+62
-65
@@ -30,17 +30,15 @@ function is_https_request(): bool {
|
|||||||
|
|
||||||
function start_secure_session(): void {
|
function start_secure_session(): void {
|
||||||
if (session_status() === PHP_SESSION_NONE) {
|
if (session_status() === PHP_SESSION_NONE) {
|
||||||
// Dagsessie: verloopt iedere nacht om 23:59:59 (blijft niet meerdere dagen staan)
|
// Zorg voor een ruime sessieduur (30 dagen)
|
||||||
$secondsUntilMidnight = max(60, strtotime('today 23:59:59') - time());
|
ini_set('session.gc_maxlifetime', '2592000');
|
||||||
|
ini_set('session.cookie_lifetime', '2592000');
|
||||||
ini_set('session.gc_maxlifetime', (string)$secondsUntilMidnight);
|
|
||||||
ini_set('session.cookie_lifetime', (string)$secondsUntilMidnight);
|
|
||||||
ini_set('session.use_strict_mode', '1');
|
ini_set('session.use_strict_mode', '1');
|
||||||
ini_set('session.use_only_cookies', '1');
|
ini_set('session.use_only_cookies', '1');
|
||||||
|
|
||||||
$isSecure = is_https_request();
|
$isSecure = is_https_request();
|
||||||
session_set_cookie_params([
|
session_set_cookie_params([
|
||||||
'lifetime' => $secondsUntilMidnight, // Verloopt vannacht om 23:59:59
|
'lifetime' => 30 * 24 * 60 * 60, // 30 dagen
|
||||||
'path' => '/',
|
'path' => '/',
|
||||||
'domain' => '',
|
'domain' => '',
|
||||||
'secure' => $isSecure,
|
'secure' => $isSecure,
|
||||||
@@ -76,9 +74,6 @@ function ensure_remember_token_columns(PDO $db): void {
|
|||||||
$result = $db->query("SHOW COLUMNS FROM `users` LIKE 'remember_token'");
|
$result = $db->query("SHOW COLUMNS FROM `users` LIKE 'remember_token'");
|
||||||
if (!$result || $result->rowCount() === 0) {
|
if (!$result || $result->rowCount() === 0) {
|
||||||
$db->exec("ALTER TABLE `users` ADD COLUMN `remember_token` VARCHAR(64) NULL AFTER `backup_codes`, ADD COLUMN `remember_token_expires_at` DATETIME NULL AFTER `remember_token`");
|
$db->exec("ALTER TABLE `users` ADD COLUMN `remember_token` VARCHAR(64) NULL AFTER `backup_codes`, ADD COLUMN `remember_token_expires_at` DATETIME NULL AFTER `remember_token`");
|
||||||
} else {
|
|
||||||
// Maak alle bestaande actieve tokens direct leeg zodat geen enkele oude persistente browser-sessie blijft bestaan
|
|
||||||
$db->exec("UPDATE `users` SET `remember_token` = NULL, `remember_token_expires_at` = NULL WHERE `remember_token` IS NOT NULL");
|
|
||||||
}
|
}
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
// Stil negeren indien al aanwezig of tijdens migraties
|
// Stil negeren indien al aanwezig of tijdens migraties
|
||||||
@@ -122,23 +117,33 @@ function ensure_theme_column(PDO $db): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verouderde functie voor persistent login.
|
* Genereert en bewaart een persistente 'Onthoud mij' token in MariaDB en plaatst een veilige cookie
|
||||||
* Bewust geneutraliseerd: cookies worden direct gewist en geen tokens meer aangemaakt,
|
|
||||||
* zodat gebruikers iedere dag om 23:59:59 worden uitgelogd en daadwerkelijk opnieuw moeten inloggen.
|
|
||||||
*/
|
*/
|
||||||
function issue_remember_token(int $userId): string {
|
function issue_remember_token(int $userId): string {
|
||||||
clear_remember_cookie();
|
$rawToken = bin2hex(random_bytes(32));
|
||||||
try {
|
$tokenHash = hash('sha256', $rawToken);
|
||||||
$db = get_db_connection();
|
$expiresAt = date('Y-m-d H:i:s', time() + (30 * 86400)); // 30 dagen geldig
|
||||||
ensure_remember_token_columns($db);
|
|
||||||
$stmt = $db->prepare("UPDATE users SET remember_token = NULL, remember_token_expires_at = NULL WHERE id = ?");
|
$db = get_db_connection();
|
||||||
$stmt->execute([$userId]);
|
ensure_remember_token_columns($db);
|
||||||
} catch (Throwable $e) {}
|
|
||||||
return '';
|
$stmt = $db->prepare("UPDATE users SET remember_token = ?, remember_token_expires_at = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$tokenHash, $expiresAt, $userId]);
|
||||||
|
|
||||||
|
$isSecure = is_https_request();
|
||||||
|
setcookie('fociz_remember', $rawToken, [
|
||||||
|
'expires' => time() + (30 * 86400),
|
||||||
|
'path' => '/',
|
||||||
|
'secure' => $isSecure,
|
||||||
|
'httponly' => true,
|
||||||
|
'samesite' => 'Lax'
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $rawToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verwijdert de persistente remember cookie uit de browser
|
* Verwijdert de persistente remember cookie
|
||||||
*/
|
*/
|
||||||
function clear_remember_cookie(): void {
|
function clear_remember_cookie(): void {
|
||||||
$isSecure = is_https_request();
|
$isSecure = is_https_request();
|
||||||
@@ -149,60 +154,58 @@ function clear_remember_cookie(): void {
|
|||||||
'httponly' => true,
|
'httponly' => true,
|
||||||
'samesite' => 'Lax'
|
'samesite' => 'Lax'
|
||||||
]);
|
]);
|
||||||
if (isset($_COOKIE['fociz_remember'])) {
|
|
||||||
unset($_COOKIE['fociz_remember']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Haalt de huidige ingelogde gebruiker op uit de database.
|
* Haalt de huidige ingelogde gebruiker op uit de database.
|
||||||
* Garandeert dat de sessie strikt om 23:59:59 gereset wordt en nooit meerdere dagen blijft staan.
|
* Herstelt automatisch de sessie als een geldige 'fociz_remember' cookie aanwezig is.
|
||||||
* Bevat GEEN persistente cookies of auto-login bypass: de gebruiker moet iedere dag daadwerkelijk opnieuw inloggen.
|
|
||||||
*/
|
*/
|
||||||
function get_logged_in_user(): ?array {
|
function get_logged_in_user(): ?array {
|
||||||
start_secure_session();
|
start_secure_session();
|
||||||
|
|
||||||
$today = date('Y-m-d');
|
$db = get_db_connection();
|
||||||
$now = time();
|
ensure_remember_token_columns($db);
|
||||||
|
|
||||||
// Verwijder altijd eventuele oude of achtergebleven fociz_remember cookies
|
// 1. Controleer actieve PHP sessie
|
||||||
if (isset($_COOKIE['fociz_remember'])) {
|
|
||||||
clear_remember_cookie();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Controleer of de sessie van een eerdere dag is of voorbij 23:59:59
|
|
||||||
$isExpired = false;
|
|
||||||
if (!empty($_SESSION['auth_date']) && $_SESSION['auth_date'] !== $today) {
|
|
||||||
$isExpired = true;
|
|
||||||
}
|
|
||||||
if (!empty($_SESSION['session_expires_at']) && $now > (int)$_SESSION['session_expires_at']) {
|
|
||||||
$isExpired = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($isExpired) {
|
|
||||||
$_SESSION = ['session_was_expired' => true];
|
|
||||||
clear_remember_cookie();
|
|
||||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
|
||||||
@session_regenerate_id(true);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Controleer actieve PHP sessie (uitsluitend de sessie van vandaag is geldig)
|
|
||||||
if (!empty($_SESSION['user_id']) && !empty($_SESSION['is_2fa_verified'])) {
|
if (!empty($_SESSION['user_id']) && !empty($_SESSION['is_2fa_verified'])) {
|
||||||
$db = get_db_connection();
|
|
||||||
ensure_remember_token_columns($db);
|
|
||||||
$stmt = $db->prepare("SELECT id, name, email, role, two_factor_enabled, created_at FROM users WHERE id = ?");
|
$stmt = $db->prepare("SELECT id, name, email, role, two_factor_enabled, created_at FROM users WHERE id = ?");
|
||||||
$stmt->execute([$_SESSION['user_id']]);
|
$stmt->execute([$_SESSION['user_id']]);
|
||||||
$user = $stmt->fetch();
|
$user = $stmt->fetch();
|
||||||
if ($user) {
|
if ($user) {
|
||||||
$_SESSION['auth_date'] = $today;
|
|
||||||
$_SESSION['session_expires_at'] = strtotime('today 23:59:59');
|
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
// Gebruiker bestaat niet meer in database
|
// Gebruiker bestaat niet meer in database
|
||||||
$_SESSION = [];
|
$_SESSION = [];
|
||||||
clear_remember_cookie();
|
}
|
||||||
|
|
||||||
|
// 2. Controleer persistente 'remember me' cookie (voorkomt ongewenst uitloggen bij refresh of herstart)
|
||||||
|
if (!empty($_COOKIE['fociz_remember'])) {
|
||||||
|
$rawToken = trim($_COOKIE['fociz_remember']);
|
||||||
|
$tokenHash = hash('sha256', $rawToken);
|
||||||
|
|
||||||
|
$stmt = $db->prepare("
|
||||||
|
SELECT id, name, email, role, two_factor_enabled, created_at
|
||||||
|
FROM users
|
||||||
|
WHERE remember_token = ? AND remember_token_expires_at > NOW()
|
||||||
|
");
|
||||||
|
$stmt->execute([$tokenHash]);
|
||||||
|
$user = $stmt->fetch();
|
||||||
|
|
||||||
|
if ($user) {
|
||||||
|
// Herstel volledige PHP sessie
|
||||||
|
$_SESSION['user_id'] = $user['id'];
|
||||||
|
$_SESSION['user_name'] = $user['name'];
|
||||||
|
$_SESSION['user_email'] = $user['email'];
|
||||||
|
$_SESSION['user_role'] = $user['role'];
|
||||||
|
$_SESSION['is_2fa_verified'] = true;
|
||||||
|
|
||||||
|
// Verleng direct de geldigheid van de remember token voor nog eens 30 dagen
|
||||||
|
issue_remember_token((int)$user['id']);
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
} else {
|
||||||
|
clear_remember_cookie();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -230,7 +233,7 @@ function require_auth(bool $json = false): array {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Controleer of gebruiker ingelogd én 2FA geverifieerd is voor vandaag
|
// 2. Controleer of gebruiker ingelogd én 2FA geverifieerd is
|
||||||
$user = get_logged_in_user();
|
$user = get_logged_in_user();
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
if ($isAjax) {
|
if ($isAjax) {
|
||||||
@@ -239,13 +242,7 @@ function require_auth(bool $json = false): array {
|
|||||||
echo json_encode(['success' => false, 'error' => 'Niet geauthenticeerd of sessie verlopen']);
|
echo json_encode(['success' => false, 'error' => 'Niet geauthenticeerd of sessie verlopen']);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$wasExpired = !empty($_SESSION['session_was_expired']);
|
header('Location: /auth/login.php');
|
||||||
unset($_SESSION['session_was_expired']);
|
|
||||||
if ($wasExpired) {
|
|
||||||
header('Location: /auth/login.php?expired=1');
|
|
||||||
} else {
|
|
||||||
header('Location: /auth/login.php');
|
|
||||||
}
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,40 +57,6 @@ $currentUserTheme = !empty($currentUser['id']) ? get_user_theme((int)$currentUse
|
|||||||
</script>
|
</script>
|
||||||
<!-- Lucide Icons -->
|
<!-- Lucide Icons -->
|
||||||
<script src="https://unpkg.com/lucide@latest"></script>
|
<script src="https://unpkg.com/lucide@latest"></script>
|
||||||
<!-- Dagsessie Expiratie Watchdog: reset iedere nacht om 23:59:59 en dwingt dagelijks opnieuw inloggen af -->
|
|
||||||
<script>
|
|
||||||
(function() {
|
|
||||||
try {
|
|
||||||
const sessionDate = "<?= date('Y-m-d') ?>";
|
|
||||||
const checkMidnight = function() {
|
|
||||||
const now = new Date();
|
|
||||||
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
|
|
||||||
const todayStr = now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0') + '-' + String(now.getDate()).padStart(2, '0');
|
|
||||||
if (todayStr !== sessionDate || now.getTime() > midnight.getTime()) {
|
|
||||||
window.location.href = '/auth/login.php?expired=1';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
|
|
||||||
const msUntilMidnight = midnight.getTime() - now.getTime();
|
|
||||||
if (msUntilMidnight > 0) {
|
|
||||||
setTimeout(function() {
|
|
||||||
window.location.href = '/auth/login.php?expired=1';
|
|
||||||
}, msUntilMidnight);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Controleer direct zodra de gebruiker de browser weer activeert (bij bijv. standby / slaapstand overnacht)
|
|
||||||
document.addEventListener('visibilitychange', function() {
|
|
||||||
if (document.visibilityState === 'visible') {
|
|
||||||
checkMidnight();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
window.addEventListener('focus', checkMidnight);
|
|
||||||
setInterval(checkMidnight, 30000);
|
|
||||||
} catch(e) {}
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
<style>
|
<style>
|
||||||
html.dark body {
|
html.dark body {
|
||||||
background-color: #0c0f17;
|
background-color: #0c0f17;
|
||||||
@@ -111,33 +77,6 @@ $currentUserTheme = !empty($currentUser['id']) ? get_user_theme((int)$currentUse
|
|||||||
html:not(.dark) ::-webkit-scrollbar-track { background: #f8fafc; }
|
html:not(.dark) ::-webkit-scrollbar-track { background: #f8fafc; }
|
||||||
html:not(.dark) ::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
|
html:not(.dark) ::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
|
||||||
html:not(.dark) ::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
|
html:not(.dark) ::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
|
||||||
|
|
||||||
/* Modern Block & Card Design System */
|
|
||||||
.fociz-card, .fociz-card-interactive {
|
|
||||||
background: rgba(255, 255, 255, 0.95);
|
|
||||||
border: 1px solid rgba(226, 232, 240, 0.9);
|
|
||||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.04), 0 1px 2px -1px rgba(0, 0, 0, 0.04);
|
|
||||||
border-radius: 1rem;
|
|
||||||
backdrop-filter: blur(12px);
|
|
||||||
transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
|
|
||||||
}
|
|
||||||
html.dark .fociz-card, html.dark .fociz-card-interactive {
|
|
||||||
background: rgba(17, 22, 34, 0.88);
|
|
||||||
border: 1px solid rgba(30, 41, 59, 0.7);
|
|
||||||
box-shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.35);
|
|
||||||
}
|
|
||||||
.fociz-card-interactive {
|
|
||||||
transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
|
|
||||||
}
|
|
||||||
.fociz-card-interactive:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.06);
|
|
||||||
border-color: rgba(99, 102, 241, 0.4);
|
|
||||||
}
|
|
||||||
html.dark .fociz-card-interactive:hover {
|
|
||||||
box-shadow: 0 12px 28px -5px rgba(0, 0, 0, 0.5), 0 0 20px rgba(99, 102, 241, 0.15);
|
|
||||||
border-color: rgba(99, 102, 241, 0.5);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="min-h-screen flex flex-col antialiased selection:bg-indigo-500 selection:text-white transition-colors duration-150">
|
<body class="min-h-screen flex flex-col antialiased selection:bg-indigo-500 selection:text-white transition-colors duration-150">
|
||||||
|
|||||||
@@ -563,6 +563,7 @@ function microsoft_delete_event(int $userId, string $eventId): bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
<<<<<<< HEAD
|
||||||
* Werkt een bestaande afspraak bij in Microsoft Outlook via Graph API (PATCH)
|
* Werkt een bestaande afspraak bij in Microsoft Outlook via Graph API (PATCH)
|
||||||
*/
|
*/
|
||||||
function microsoft_update_event(int $userId, string $eventId, array $eventData): bool {
|
function microsoft_update_event(int $userId, string $eventId, array $eventData): bool {
|
||||||
@@ -632,6 +633,8 @@ function microsoft_update_event(int $userId, string $eventId, array $eventData):
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
* Ontkoppelt Microsoft integratie voor een gebruiker
|
* Ontkoppelt Microsoft integratie voor een gebruiker
|
||||||
* Wist uitsluitend de persoonlijke tokens; behoudt de centrale Azure App gegevens indien aanwezig.
|
* Wist uitsluitend de persoonlijke tokens; behoudt de centrale Azure App gegevens indien aanwezig.
|
||||||
*/
|
*/
|
||||||
@@ -663,6 +666,7 @@ function microsoft_disconnect(int $userId): bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
/**
|
/**
|
||||||
* Haalt één specifieke afspraak op uit Microsoft Outlook via Graph API.
|
* Haalt één specifieke afspraak op uit Microsoft Outlook via Graph API.
|
||||||
* Retourneert:
|
* Retourneert:
|
||||||
@@ -881,3 +885,7 @@ function microsoft_reconcile_tasks_with_outlook(int $userId, string $startDate,
|
|||||||
'updated' => $updatedCount,
|
'updated' => $updatedCount,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
|
|||||||
+263
-128
@@ -42,7 +42,53 @@ $dutchShortMonths = ['', 'jan', 'feb', 'mrt', 'apr', 'mei', 'jun', 'jul', 'aug',
|
|||||||
$formattedSelectedDate = $dutchFullDays[(int)date('N', $selectedTs)] . ' ' . date('j', $selectedTs) . ' ' . $dutchMonths[(int)date('n', $selectedTs)] . ' ' . date('Y', $selectedTs);
|
$formattedSelectedDate = $dutchFullDays[(int)date('N', $selectedTs)] . ' ' . date('j', $selectedTs) . ' ' . $dutchMonths[(int)date('n', $selectedTs)] . ' ' . date('Y', $selectedTs);
|
||||||
$formattedWeekRange = date('j', $mondayTs) . ' ' . $dutchShortMonths[(int)date('n', $mondayTs)] . ' – ' . date('j', $sundayTs) . ' ' . $dutchShortMonths[(int)date('n', $sundayTs)] . ' ' . date('Y', $sundayTs);
|
$formattedWeekRange = date('j', $mondayTs) . ' ' . $dutchShortMonths[(int)date('n', $mondayTs)] . ' – ' . date('j', $sundayTs) . ' ' . $dutchShortMonths[(int)date('n', $sundayTs)] . ' ' . date('Y', $sundayTs);
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
// 1. Haal integratiestatussen op
|
// 1. Haal integratiestatussen op
|
||||||
|
=======
|
||||||
|
// 1. Haal dagplanning op of maak aan voor $selectedDate
|
||||||
|
$stmtPlan = $db->prepare("SELECT * FROM daily_plans WHERE user_id = ? AND plan_date = ?");
|
||||||
|
$stmtPlan->execute([$userId, $selectedDate]);
|
||||||
|
$dailyPlan = $stmtPlan->fetch();
|
||||||
|
|
||||||
|
if (!$dailyPlan) {
|
||||||
|
$defaultGoal = ($selectedDate === $today) ? 'Mijn belangrijkste doel van vandaag behalen' : 'Focusdoel voor deze dag bepalen';
|
||||||
|
$stmtCreatePlan = $db->prepare("
|
||||||
|
INSERT INTO daily_plans (user_id, plan_date, focus_goal)
|
||||||
|
VALUES (?, ?, ?)
|
||||||
|
");
|
||||||
|
$stmtCreatePlan->execute([$userId, $selectedDate, $defaultGoal]);
|
||||||
|
$planId = (int)$db->lastInsertId();
|
||||||
|
$dailyPlan = ['id' => $planId, 'plan_date' => $selectedDate, 'focus_goal' => $defaultGoal, 'notes' => ''];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Haal taken op voor de geselecteerde dag
|
||||||
|
$stmtTasks = $db->prepare("
|
||||||
|
SELECT * FROM tasks
|
||||||
|
WHERE user_id = ? AND (daily_plan_id = ? " . ($selectedDate === $today ? "OR daily_plan_id IS NULL" : "") . ")
|
||||||
|
ORDER BY is_completed ASC, priority ASC, time_block_start ASC, created_at DESC
|
||||||
|
");
|
||||||
|
$stmtTasks->execute([$userId, $dailyPlan['id']]);
|
||||||
|
$tasks = $stmtTasks->fetchAll();
|
||||||
|
|
||||||
|
// 3. Haal weekstatistieken voor taken op (aantal per dag)
|
||||||
|
$stmtWeekTasks = $db->prepare("
|
||||||
|
SELECT dp.plan_date, COUNT(t.id) as total_tasks, SUM(CASE WHEN t.is_completed = 1 THEN 1 ELSE 0 END) as completed_tasks
|
||||||
|
FROM daily_plans dp
|
||||||
|
LEFT JOIN tasks t ON t.daily_plan_id = dp.id AND t.user_id = ?
|
||||||
|
WHERE dp.user_id = ? AND dp.plan_date BETWEEN ? AND ?
|
||||||
|
GROUP BY dp.plan_date
|
||||||
|
");
|
||||||
|
$stmtWeekTasks->execute([$userId, $userId, $weekStart, $weekEnd]);
|
||||||
|
$weekTaskStats = [];
|
||||||
|
foreach ($stmtWeekTasks->fetchAll() as $row) {
|
||||||
|
$weekTaskStats[$row['plan_date']] = [
|
||||||
|
'total' => (int)$row['total_tasks'],
|
||||||
|
'completed' => (int)$row['completed_tasks'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Haal integratiestatussen op
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
$stmtInt = $db->prepare("SELECT * FROM integrations WHERE user_id = ?");
|
$stmtInt = $db->prepare("SELECT * FROM integrations WHERE user_id = ?");
|
||||||
$stmtInt->execute([$userId]);
|
$stmtInt->execute([$userId]);
|
||||||
$userIntegrations = [];
|
$userIntegrations = [];
|
||||||
@@ -51,9 +97,12 @@ foreach ($stmtInt->fetchAll() as $row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$isOutlookConnected = !empty($userIntegrations['OUTLOOK']['access_token']) && empty($userIntegrations['OUTLOOK']['is_demo_mode']);
|
$isOutlookConnected = !empty($userIntegrations['OUTLOOK']['access_token']) && empty($userIntegrations['OUTLOOK']['is_demo_mode']);
|
||||||
|
<<<<<<< HEAD
|
||||||
$outlookIntegrationSettings = json_decode($userIntegrations['OUTLOOK']['settings'] ?? '{}', true) ?: [];
|
$outlookIntegrationSettings = json_decode($userIntegrations['OUTLOOK']['settings'] ?? '{}', true) ?: [];
|
||||||
$syncIntervalSeconds = isset($outlookIntegrationSettings['sync_interval_seconds']) ? (int)$outlookIntegrationSettings['sync_interval_seconds'] : 30;
|
$syncIntervalSeconds = isset($outlookIntegrationSettings['sync_interval_seconds']) ? (int)$outlookIntegrationSettings['sync_interval_seconds'] : 30;
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
$weekOutlookEvents = [];
|
$weekOutlookEvents = [];
|
||||||
$isLiveOutlook = false;
|
$isLiveOutlook = false;
|
||||||
|
|
||||||
@@ -61,9 +110,12 @@ if ($isOutlookConnected) {
|
|||||||
// Haal afspraken op voor het volledige datumbereik van de week
|
// Haal afspraken op voor het volledige datumbereik van de week
|
||||||
$weekOutlookEvents = microsoft_fetch_events_range($userId, $weekStart, $weekEnd);
|
$weekOutlookEvents = microsoft_fetch_events_range($userId, $weekStart, $weekEnd);
|
||||||
$isLiveOutlook = true;
|
$isLiveOutlook = true;
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
// Synchroniseer / reconcilieer Fociz taken direct met actuele Outlook data
|
// Synchroniseer / reconcilieer Fociz taken direct met actuele Outlook data
|
||||||
microsoft_reconcile_tasks_with_outlook($userId, $weekStart, $weekEnd, $weekOutlookEvents);
|
microsoft_reconcile_tasks_with_outlook($userId, $weekStart, $weekEnd, $weekOutlookEvents);
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
} else {
|
} else {
|
||||||
// Demo data indien Microsoft Outlook nog niet gekoppeld is
|
// Demo data indien Microsoft Outlook nog niet gekoppeld is
|
||||||
$weekOutlookEvents = [
|
$weekOutlookEvents = [
|
||||||
@@ -100,6 +152,7 @@ if ($isOutlookConnected) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
// 2. Haal dagplanning op of maak aan voor $selectedDate
|
// 2. Haal dagplanning op of maak aan voor $selectedDate
|
||||||
$stmtPlan = $db->prepare("SELECT * FROM daily_plans WHERE user_id = ? AND plan_date = ?");
|
$stmtPlan = $db->prepare("SELECT * FROM daily_plans WHERE user_id = ? AND plan_date = ?");
|
||||||
$stmtPlan->execute([$userId, $selectedDate]);
|
$stmtPlan->execute([$userId, $selectedDate]);
|
||||||
@@ -142,6 +195,8 @@ foreach ($stmtWeekTasks->fetchAll() as $row) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
// Groepeer Outlook afspraken per datum
|
// Groepeer Outlook afspraken per datum
|
||||||
$outlookEventsByDate = [];
|
$outlookEventsByDate = [];
|
||||||
foreach ($weekOutlookEvents as $evt) {
|
foreach ($weekOutlookEvents as $evt) {
|
||||||
@@ -194,6 +249,7 @@ foreach ($dayOutlookEvents as $evt) {
|
|||||||
$displayedOutlookEvents[] = $evt;
|
$displayedOutlookEvents[] = $evt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
// Bereken initiële status-hash voor achtergrondsynchronisatie
|
// Bereken initiële status-hash voor achtergrondsynchronisatie
|
||||||
$dayEventsForHash = [];
|
$dayEventsForHash = [];
|
||||||
foreach ($displayedOutlookEvents as $e) {
|
foreach ($displayedOutlookEvents as $e) {
|
||||||
@@ -218,6 +274,8 @@ $initialSyncHash = md5(json_encode([
|
|||||||
'tasks' => $tasksForHash
|
'tasks' => $tasksForHash
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
// 6. Tijdlijn uren & Werkdag Standaarden (Release v1.4)
|
// 6. Tijdlijn uren & Werkdag Standaarden (Release v1.4)
|
||||||
$workdayStartStr = $workdaySettings['workday_start'] ?? '08:30';
|
$workdayStartStr = $workdaySettings['workday_start'] ?? '08:30';
|
||||||
$workdayEndStr = $workdaySettings['workday_end'] ?? '17:30';
|
$workdayEndStr = $workdaySettings['workday_end'] ?? '17:30';
|
||||||
@@ -260,19 +318,19 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
|
|
||||||
<div class="space-y-6 max-w-7xl mx-auto">
|
<div class="space-y-6 max-w-7xl mx-auto">
|
||||||
<!-- Top Banner: Datum, Hoofddoel & Integraties Status -->
|
<!-- Top Banner: Datum, Hoofddoel & Integraties Status -->
|
||||||
<div class="fociz-card p-6 sm:p-7 relative overflow-hidden">
|
<div class="bg-white dark:bg-slate-900/90 border border-slate-200/80 dark:border-slate-800/60 rounded-2xl p-6 sm:p-7 shadow-xs backdrop-blur-sm transition">
|
||||||
<div class="flex flex-col lg:flex-row lg:items-center justify-between gap-4">
|
<div class="flex flex-col lg:flex-row lg:items-center justify-between gap-4">
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center space-x-2 text-indigo-600 dark:text-indigo-400 text-xs font-bold uppercase tracking-wider mb-1">
|
<div class="flex items-center space-x-2 text-indigo-600 dark:text-indigo-400 text-xs font-semibold uppercase tracking-wider mb-1">
|
||||||
<i data-lucide="calendar" class="w-4 h-4"></i>
|
<i data-lucide="calendar" class="w-4 h-4"></i>
|
||||||
<span><?= htmlspecialchars($formattedSelectedDate) ?></span>
|
<span><?= htmlspecialchars($formattedSelectedDate) ?></span>
|
||||||
<?php if ($isTodaySelected): ?>
|
<?php if ($isTodaySelected): ?>
|
||||||
<span class="px-2.5 py-0.5 rounded-full text-[10px] font-extrabold bg-indigo-50 text-indigo-700 dark:bg-indigo-500/15 dark:text-indigo-300 ring-1 ring-indigo-500/30">VANDAAG</span>
|
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold bg-indigo-50 text-indigo-700 dark:bg-indigo-500/15 dark:text-indigo-300">VANDAAG</span>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<span class="px-2.5 py-0.5 rounded-full text-[10px] font-bold bg-slate-100 dark:bg-slate-800/80 text-slate-600 dark:text-slate-400">GEKOZEN DAG</span>
|
<span class="px-2 py-0.5 rounded-full text-[10px] font-semibold bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-400">GEKOZEN DAG</span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-2xl sm:text-3xl font-black tracking-tight text-slate-900 dark:text-white">
|
<h1 class="text-2xl sm:text-3xl font-black text-slate-900 dark:text-white tracking-tight">
|
||||||
Dagplanning & Structuur
|
Dagplanning & Structuur
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
@@ -280,28 +338,36 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<!-- Integratie Status Badges -->
|
<!-- Integratie Status Badges -->
|
||||||
<div class="flex flex-wrap items-center gap-2">
|
<div class="flex flex-wrap items-center gap-2">
|
||||||
<?php if ($isOutlookConnected): ?>
|
<?php if ($isOutlookConnected): ?>
|
||||||
<div id="outlookSyncBadge" class="flex items-center space-x-2 px-3.5 py-1.5 rounded-xl bg-sky-50 dark:bg-sky-500/10 border border-sky-200/80 dark:border-sky-500/20 text-sky-800 dark:text-sky-300 text-xs font-semibold shadow-2xs transition">
|
<<<<<<< HEAD
|
||||||
|
<div id="outlookSyncBadge" class="flex items-center space-x-2 px-3 py-1.5 rounded-xl bg-sky-50 dark:bg-sky-500/10 border border-sky-200/80 dark:border-sky-500/20 text-sky-800 dark:text-sky-300 text-xs font-medium shadow-2xs transition">
|
||||||
<span id="outlookSyncDot" class="w-2 h-2 rounded-full bg-sky-500"></span>
|
<span id="outlookSyncDot" class="w-2 h-2 rounded-full bg-sky-500"></span>
|
||||||
<span id="outlookSyncStatusText">Outlook 365 Live</span>
|
<span id="outlookSyncStatusText">Outlook 365 Live</span>
|
||||||
<span id="outlookLastSyncText" class="text-[10px] text-sky-600/80 dark:text-sky-400/70 font-mono hidden sm:inline">(synced <span id="syncTimeDisplay"><?= date('H:i') ?></span>)</span>
|
<span id="outlookLastSyncText" class="text-[10px] text-sky-600/70 dark:text-sky-400/60 font-mono hidden sm:inline">(synced <span id="syncTimeDisplay"><?= date('H:i') ?></span>)</span>
|
||||||
<button id="manualSyncBtn" onclick="triggerManualSync()" title="Nu handmatig synchroniseren met Outlook" class="p-0.5 hover:bg-sky-100 dark:hover:bg-sky-500/20 text-sky-600 hover:text-sky-900 dark:text-sky-400 dark:hover:text-white rounded transition cursor-pointer">
|
<button id="manualSyncBtn" onclick="triggerManualSync()" title="Nu handmatig synchroniseren met Outlook" class="p-0.5 hover:bg-sky-100 dark:hover:bg-sky-500/20 text-sky-600 hover:text-sky-900 dark:text-sky-400 dark:hover:text-white rounded transition cursor-pointer">
|
||||||
<i id="manualSyncIcon" data-lucide="refresh-cw" class="w-3 h-3"></i>
|
<i id="manualSyncIcon" data-lucide="refresh-cw" class="w-3 h-3"></i>
|
||||||
|
=======
|
||||||
|
<div class="flex items-center space-x-2 px-3 py-1.5 rounded-xl bg-sky-50 dark:bg-sky-500/10 border border-sky-200/80 dark:border-sky-500/20 text-sky-800 dark:text-sky-300 text-xs font-medium shadow-2xs">
|
||||||
|
<span class="w-2 h-2 rounded-full bg-sky-500 animate-pulse"></span>
|
||||||
|
<span>Outlook 365 Live</span>
|
||||||
|
<button onclick="location.reload()" title="Agenda Verversen" class="p-0.5 text-sky-600 hover:text-sky-900 dark:text-sky-400 dark:hover:text-white rounded transition">
|
||||||
|
<i data-lucide="refresh-cw" class="w-3 h-3"></i>
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<a href="/profile.php" class="flex items-center space-x-1.5 px-3 py-1.5 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800/80 dark:hover:bg-slate-700 border border-slate-200 dark:border-slate-700 text-slate-700 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white text-xs font-semibold transition shadow-2xs">
|
<a href="/profile.php" class="flex items-center space-x-1.5 px-3 py-1.5 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800/80 dark:hover:bg-slate-700 border border-slate-200 dark:border-slate-700 text-slate-700 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white text-xs font-medium transition shadow-2xs">
|
||||||
<i data-lucide="link-2" class="w-3.5 h-3.5 text-sky-500"></i>
|
<i data-lucide="link-2" class="w-3.5 h-3.5 text-sky-500"></i>
|
||||||
<span>Koppel Outlook</span>
|
<span>Koppel Outlook</span>
|
||||||
</a>
|
</a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if ($isJiraLive): ?>
|
<?php if ($isJiraLive): ?>
|
||||||
<a href="#jiraPanel" class="flex items-center space-x-1.5 px-3.5 py-1.5 rounded-xl bg-slate-100 dark:bg-slate-800/80 border border-slate-200 dark:border-slate-700 text-slate-700 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white text-xs font-semibold transition shadow-2xs">
|
<a href="#jiraPanel" class="flex items-center space-x-1.5 px-3 py-1.5 rounded-xl bg-slate-100 dark:bg-slate-800/70 border border-slate-200 dark:border-slate-700 text-slate-700 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white text-xs font-medium transition shadow-2xs">
|
||||||
<span class="w-2 h-2 rounded-full bg-indigo-500 animate-pulse"></span>
|
<span class="w-2 h-2 rounded-full bg-indigo-500 animate-pulse"></span>
|
||||||
<span>Jira: <?= count($jiraIssues) ?> tickets</span>
|
<span>Jira: <?= count($jiraIssues) ?> tickets</span>
|
||||||
</a>
|
</a>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<a href="/profile.php" class="flex items-center space-x-1.5 px-3 py-1.5 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800/80 dark:hover:bg-slate-700 border border-slate-200 dark:border-slate-700 text-slate-700 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white text-xs font-semibold transition shadow-2xs">
|
<a href="/profile.php" class="flex items-center space-x-1.5 px-3 py-1.5 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800/80 dark:hover:bg-slate-700 border border-slate-200 dark:border-slate-700 text-slate-700 dark:text-slate-300 hover:text-slate-900 dark:hover:text-white text-xs font-medium transition shadow-2xs">
|
||||||
<i data-lucide="trello" class="w-3.5 h-3.5 text-indigo-500"></i>
|
<i data-lucide="trello" class="w-3.5 h-3.5 text-indigo-500"></i>
|
||||||
<span>Koppel Jira</span>
|
<span>Koppel Jira</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -309,32 +375,26 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Dagdoel Focus Spotlight Blok -->
|
<!-- Dagdoel invoerveld -->
|
||||||
<div class="mt-6 p-4 sm:p-5 rounded-2xl bg-gradient-to-r from-indigo-500/[0.08] via-sky-500/[0.04] to-transparent dark:from-indigo-500/[0.14] dark:via-sky-500/[0.06] dark:to-transparent border border-indigo-500/20 dark:border-indigo-500/30 shadow-xs relative overflow-hidden">
|
<div class="mt-5 pt-4 border-t border-slate-100 dark:border-slate-800/60">
|
||||||
<div class="flex items-center space-x-2 mb-2">
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 uppercase tracking-wider mb-1.5 flex items-center space-x-1.5">
|
||||||
<div class="w-6 h-6 rounded-lg bg-indigo-600 text-white flex items-center justify-center shadow-xs">
|
<i data-lucide="target" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<i data-lucide="target" class="w-3.5 h-3.5"></i>
|
<span>Mijn Belangrijkste Dagdoel voor <?= htmlspecialchars($dutchFullDays[(int)date('N', $selectedTs)]) ?></span>
|
||||||
</div>
|
</label>
|
||||||
<label for="focusGoalInput" class="text-xs font-bold text-indigo-950 dark:text-indigo-200 uppercase tracking-wider">
|
<div class="flex items-center space-x-2">
|
||||||
Focus van de Dag • <?= htmlspecialchars($dutchFullDays[(int)date('N', $selectedTs)]) ?>
|
<input
|
||||||
</label>
|
type="text"
|
||||||
</div>
|
id="focusGoalInput"
|
||||||
<div class="flex items-center gap-2">
|
value="<?= htmlspecialchars($dailyPlan['focus_goal'] ?? '') ?>"
|
||||||
<div class="relative flex-1">
|
placeholder="Wat moet er deze dag absoluut gebeuren voor succes?"
|
||||||
<input
|
class="flex-1 bg-slate-50 dark:bg-slate-950/60 border border-slate-200 dark:border-slate-800 rounded-xl px-4 py-2.5 text-slate-900 dark:text-white placeholder-slate-400 dark:placeholder-slate-500 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500/30 focus:border-indigo-500 font-medium transition"
|
||||||
type="text"
|
>
|
||||||
id="focusGoalInput"
|
|
||||||
value="<?= htmlspecialchars($dailyPlan['focus_goal'] ?? '') ?>"
|
|
||||||
placeholder="Wat moet er deze dag absoluut gebeuren voor succes?"
|
|
||||||
class="w-full bg-white/95 dark:bg-[#0c0f17]/95 border border-slate-200/90 dark:border-slate-800/90 rounded-xl px-4 py-2.5 text-slate-900 dark:text-white placeholder-slate-400 dark:placeholder-slate-500 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500/40 focus:border-indigo-500 font-medium transition shadow-2xs"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<button
|
<button
|
||||||
onclick="saveGoal()"
|
onclick="saveGoal()"
|
||||||
id="saveGoalBtn"
|
id="saveGoalBtn"
|
||||||
class="px-5 py-2.5 bg-gradient-to-r from-indigo-600 to-indigo-500 hover:from-indigo-500 hover:to-indigo-400 text-white font-semibold text-xs rounded-xl transition flex items-center space-x-1.5 shadow-sm shadow-indigo-600/30 flex-shrink-0 cursor-pointer"
|
class="px-4 py-2.5 bg-indigo-600 hover:bg-indigo-500 text-white font-semibold text-xs rounded-xl transition flex items-center space-x-1 shadow-sm shadow-indigo-600/20 flex-shrink-0 cursor-pointer"
|
||||||
>
|
>
|
||||||
<i data-lucide="check" class="w-4 h-4 stroke-[2.5]"></i>
|
<i data-lucide="check-circle-2" class="w-4 h-4"></i>
|
||||||
<span>Opslaan</span>
|
<span>Opslaan</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -342,20 +402,20 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Week Navigatie & Dagselector -->
|
<!-- Week Navigatie & Dagselector -->
|
||||||
<div class="fociz-card p-5 sm:p-6">
|
<div class="bg-white dark:bg-slate-900/90 border border-slate-200/80 dark:border-slate-800/60 rounded-2xl p-5 sm:p-6 shadow-xs backdrop-blur-sm transition">
|
||||||
<div class="flex flex-col md:flex-row md:items-center justify-between gap-4 pb-4 mb-4 border-b border-slate-100 dark:border-slate-800/60">
|
<div class="flex flex-col md:flex-row md:items-center justify-between gap-4 pb-4 mb-4 border-b border-slate-100 dark:border-slate-800/60">
|
||||||
<!-- Navigatie controls -->
|
<!-- Navigatie controls -->
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<a href="planner.php?date=<?= $prevWeekDate ?>" class="flex items-center space-x-1.5 px-3.5 py-1.5 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800/80 dark:hover:bg-slate-700/80 text-slate-700 dark:text-slate-300 text-xs font-semibold transition shadow-2xs" title="Vorige week (Maandag <?= date('j M', strtotime($prevWeekDate)) ?>)">
|
<a href="planner.php?date=<?= $prevWeekDate ?>" class="flex items-center space-x-1.5 px-3 py-1.5 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 text-xs font-semibold transition shadow-2xs" title="Vorige week (Maandag <?= date('j M', strtotime($prevWeekDate)) ?>)">
|
||||||
<i data-lucide="chevron-left" class="w-4 h-4"></i>
|
<i data-lucide="chevron-left" class="w-4 h-4"></i>
|
||||||
<span class="hidden sm:inline">Vorige week</span>
|
<span class="hidden sm:inline">Vorige week</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="planner.php?date=<?= $today ?>" class="px-3.5 py-1.5 rounded-xl <?= $isTodaySelected ? 'bg-slate-900 text-white dark:bg-white dark:text-slate-900 font-bold shadow-xs' : 'bg-slate-100 hover:bg-slate-200 dark:bg-slate-800/80 dark:hover:bg-slate-700/80 text-slate-700 dark:text-slate-300 font-semibold shadow-2xs' ?> text-xs transition" title="Spring direct naar vandaag">
|
<a href="planner.php?date=<?= $today ?>" class="px-3 py-1.5 rounded-xl <?= $isTodaySelected ? 'bg-slate-900 text-white dark:bg-white dark:text-slate-900 font-bold' : 'bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 font-semibold' ?> text-xs transition shadow-2xs" title="Spring direct naar vandaag">
|
||||||
Vandaag
|
Vandaag
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="planner.php?date=<?= $nextWeekDate ?>" class="flex items-center space-x-1.5 px-3.5 py-1.5 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800/80 dark:hover:bg-slate-700/80 text-slate-700 dark:text-slate-300 text-xs font-semibold transition shadow-2xs" title="Volgende week (Maandag <?= date('j M', strtotime($nextWeekDate)) ?>)">
|
<a href="planner.php?date=<?= $nextWeekDate ?>" class="flex items-center space-x-1.5 px-3 py-1.5 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 text-xs font-semibold transition shadow-2xs" title="Volgende week (Maandag <?= date('j M', strtotime($nextWeekDate)) ?>)">
|
||||||
<span class="hidden sm:inline">Volgende week</span>
|
<span class="hidden sm:inline">Volgende week</span>
|
||||||
<i data-lucide="chevron-right" class="w-4 h-4"></i>
|
<i data-lucide="chevron-right" class="w-4 h-4"></i>
|
||||||
</a>
|
</a>
|
||||||
@@ -363,7 +423,7 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
|
|
||||||
<!-- Week Titel & Datumrange -->
|
<!-- Week Titel & Datumrange -->
|
||||||
<div class="text-center md:text-left">
|
<div class="text-center md:text-left">
|
||||||
<div class="text-xs font-bold uppercase tracking-wider text-indigo-600 dark:text-indigo-400">
|
<div class="text-xs font-semibold uppercase tracking-wider text-indigo-600 dark:text-indigo-400">
|
||||||
Week <?= $weekNumber ?> • <?= $yearNumber ?>
|
Week <?= $weekNumber ?> • <?= $yearNumber ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-base font-black text-slate-900 dark:text-white">
|
<div class="text-base font-black text-slate-900 dark:text-white">
|
||||||
@@ -379,58 +439,58 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
id="jumpDateInput"
|
id="jumpDateInput"
|
||||||
value="<?= htmlspecialchars($selectedDate) ?>"
|
value="<?= htmlspecialchars($selectedDate) ?>"
|
||||||
onchange="if(this.value) window.location.href='planner.php?date=' + this.value;"
|
onchange="if(this.value) window.location.href='planner.php?date=' + this.value;"
|
||||||
class="bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-1.5 text-xs text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-indigo-500/30 font-medium cursor-pointer shadow-2xs"
|
class="bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-1.5 text-xs text-slate-800 dark:text-slate-200 focus:outline-none focus:ring-2 focus:ring-indigo-500/30 font-medium cursor-pointer"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 7 Dagen Weekstrook -->
|
<!-- 7 Dagen Weekstrook -->
|
||||||
<div class="grid grid-cols-2 sm:grid-cols-4 md:grid-cols-7 gap-3">
|
<div class="grid grid-cols-2 sm:grid-cols-4 md:grid-cols-7 gap-2.5">
|
||||||
<?php foreach ($weekDays as $wd): ?>
|
<?php foreach ($weekDays as $wd): ?>
|
||||||
<a
|
<a
|
||||||
href="planner.php?date=<?= $wd['date'] ?>"
|
href="planner.php?date=<?= $wd['date'] ?>"
|
||||||
class="fociz-card-interactive group relative flex flex-col p-3.5 rounded-2xl border transition-all text-left <?= $wd['is_selected']
|
class="group relative flex flex-col p-3 rounded-xl border transition text-left <?= $wd['is_selected']
|
||||||
? 'bg-gradient-to-b from-indigo-500/15 via-indigo-500/5 to-transparent dark:from-indigo-500/25 dark:via-indigo-500/10 dark:to-transparent border-indigo-500 ring-2 ring-indigo-500/40 shadow-sm'
|
? 'bg-indigo-50/80 dark:bg-indigo-500/10 border-indigo-500/40 ring-1 ring-indigo-500/30 shadow-xs'
|
||||||
: 'bg-slate-50/70 dark:bg-[#0c0f17]/50 border-slate-200/80 dark:border-slate-800/80 hover:border-indigo-300 dark:hover:border-indigo-600/50 hover:bg-white dark:hover:bg-[#111624] shadow-2xs' ?>"
|
: 'bg-slate-50/70 dark:bg-slate-950/40 border-slate-200/80 dark:border-slate-800/60 hover:border-slate-300 dark:hover:border-slate-700 hover:bg-white dark:hover:bg-slate-900/60 shadow-2xs' ?>"
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-between mb-1.5">
|
<div class="flex items-center justify-between mb-1.5">
|
||||||
<span class="text-[11px] font-bold uppercase tracking-wider <?= $wd['is_selected'] ? 'text-indigo-600 dark:text-indigo-400' : 'text-slate-500 dark:text-slate-400' ?>">
|
<span class="text-[11px] font-semibold uppercase tracking-wider <?= $wd['is_selected'] ? 'text-indigo-700 dark:text-indigo-400 font-bold' : 'text-slate-500 dark:text-slate-400' ?>">
|
||||||
<?= $wd['short_name'] ?>
|
<?= $wd['short_name'] ?>
|
||||||
</span>
|
</span>
|
||||||
<?php if ($wd['is_today']): ?>
|
<?php if ($wd['is_today']): ?>
|
||||||
<span class="px-2 py-0.5 rounded-full text-[9px] font-extrabold uppercase bg-indigo-600 text-white shadow-xs">
|
<span class="px-1.5 py-0.5 rounded-full text-[9px] font-bold uppercase bg-indigo-600 text-white">
|
||||||
Nu
|
Nu
|
||||||
</span>
|
</span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-baseline space-x-1.5 mb-3">
|
<div class="flex items-baseline space-x-1 mb-2">
|
||||||
<span class="text-2xl font-black <?= $wd['is_selected'] ? 'text-indigo-600 dark:text-indigo-400' : 'text-slate-900 dark:text-white' ?>">
|
<span class="text-xl font-black <?= $wd['is_selected'] ? 'text-indigo-600 dark:text-indigo-400' : 'text-slate-900 dark:text-white' ?>">
|
||||||
<?= $wd['day_num'] ?>
|
<?= $wd['day_num'] ?>
|
||||||
</span>
|
</span>
|
||||||
<span class="text-[11px] font-semibold text-slate-400 dark:text-slate-500 uppercase">
|
<span class="text-[10px] font-medium text-slate-400 dark:text-slate-500">
|
||||||
<?= $wd['month_short'] ?>
|
<?= $wd['month_short'] ?>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Mini chips voor taken en meetings op deze dag -->
|
<!-- Indicatoren voor taken en meetings op deze dag -->
|
||||||
<div class="flex flex-col gap-1.5 mt-auto pt-2 border-t border-slate-200/60 dark:border-slate-800/60 text-[10px]">
|
<div class="flex flex-col gap-1 mt-auto pt-1.5 border-t border-slate-200/60 dark:border-slate-800/60 text-[10px]">
|
||||||
<div class="flex items-center justify-between px-2 py-1 rounded-lg bg-white/70 dark:bg-slate-900/60 border border-slate-200/50 dark:border-slate-800/50 text-slate-600 dark:text-slate-400">
|
<div class="flex items-center justify-between text-slate-600 dark:text-slate-400">
|
||||||
<span class="flex items-center space-x-1">
|
<span class="flex items-center space-x-1">
|
||||||
<i data-lucide="check-square" class="w-3 h-3 text-indigo-500"></i>
|
<i data-lucide="check-square" class="w-3 h-3 text-slate-400 dark:text-slate-500"></i>
|
||||||
<span>Taken</span>
|
<span>Taken</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="font-bold <?= $wd['task_count'] > 0 ? ($wd['completed_count'] === $wd['task_count'] ? 'text-indigo-600 dark:text-indigo-400' : 'text-slate-800 dark:text-slate-200') : 'text-slate-400' ?>">
|
<span class="font-semibold <?= $wd['task_count'] > 0 ? ($wd['completed_count'] === $wd['task_count'] ? 'text-indigo-600 dark:text-indigo-400' : 'text-slate-700 dark:text-slate-300') : 'text-slate-400' ?>">
|
||||||
<?= $wd['completed_count'] ?>/<?= $wd['task_count'] ?>
|
<?= $wd['completed_count'] ?>/<?= $wd['task_count'] ?>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center justify-between px-2 py-1 rounded-lg bg-sky-50/70 dark:bg-sky-500/10 border border-sky-200/50 dark:border-sky-500/20 text-sky-800 dark:text-sky-300">
|
<div class="flex items-center justify-between text-slate-600 dark:text-slate-400">
|
||||||
<span class="flex items-center space-x-1">
|
<span class="flex items-center space-x-1">
|
||||||
<i data-lucide="calendar" class="w-3 h-3 text-sky-500"></i>
|
<i data-lucide="calendar" class="w-3 h-3 text-sky-500"></i>
|
||||||
<span>Agenda</span>
|
<span>Agenda</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="font-bold">
|
<span class="font-semibold <?= $wd['meeting_count'] > 0 ? 'text-sky-600 dark:text-sky-400' : 'text-slate-400' ?>">
|
||||||
<?= $wd['meeting_count'] ?>
|
<?= $wd['meeting_count'] ?>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -446,86 +506,93 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<!-- Linker kolom: Focus Timer & Taken -->
|
<!-- Linker kolom: Focus Timer & Taken -->
|
||||||
<div class="lg:col-span-7 space-y-6 min-w-0">
|
<div class="lg:col-span-7 space-y-6 min-w-0">
|
||||||
|
|
||||||
<!-- Focus Modus Timer Workstation -->
|
<!-- Focus Modus Timer -->
|
||||||
<div class="fociz-card p-6 sm:p-7 relative overflow-hidden">
|
<div class="bg-white dark:bg-slate-900/90 border border-slate-200/80 dark:border-slate-800/60 rounded-2xl p-6 shadow-xs relative overflow-hidden backdrop-blur-sm transition">
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<div class="flex items-center space-x-3">
|
<div class="flex items-center space-x-2">
|
||||||
<div class="w-10 h-10 rounded-2xl bg-amber-500/10 border border-amber-500/20 text-amber-500 flex items-center justify-center font-bold shadow-xs">
|
<div class="w-8 h-8 rounded-xl bg-amber-50 dark:bg-amber-500/10 text-amber-500 flex items-center justify-center font-bold">
|
||||||
<i data-lucide="flame" class="w-5 h-5"></i>
|
<i data-lucide="flame" class="w-4 h-4"></i>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-sm font-bold text-slate-900 dark:text-white uppercase tracking-wider">Focus Modus</h3>
|
<h3 class="text-sm font-bold text-slate-900 dark:text-white uppercase tracking-wider">Focus Modus</h3>
|
||||||
<p class="text-[11px] text-slate-500 dark:text-slate-400">Pomodoro werkstation & concentratie</p>
|
<p class="text-[11px] text-slate-500 dark:text-slate-400">Pomodoro & geconcentreerd werken</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex bg-slate-100/90 dark:bg-[#0c0f17]/90 p-1 rounded-xl border border-slate-200/80 dark:border-slate-800/80 text-xs">
|
<div class="flex bg-slate-100 dark:bg-slate-950/80 p-1 rounded-xl border border-slate-200/80 dark:border-slate-800 text-xs">
|
||||||
<button onclick="setTimerPreset(<?= (int)$workdaySettings['pomodoro_focus'] ?>)" id="btnPresetFocus" class="px-3 py-1.5 rounded-lg font-bold bg-indigo-600 text-white shadow-xs transition"><?= (int)$workdaySettings['pomodoro_focus'] ?>m Focus</button>
|
<button onclick="setTimerPreset(<?= (int)$workdaySettings['pomodoro_focus'] ?>)" id="btnPresetFocus" class="px-2.5 py-1 rounded-lg font-semibold bg-indigo-600 text-white shadow-xs transition"><?= (int)$workdaySettings['pomodoro_focus'] ?>m Focus</button>
|
||||||
<button onclick="setTimerPreset(<?= (int)$workdaySettings['pomodoro_deep'] ?>)" id="btnPresetDeep" class="px-3 py-1.5 rounded-lg font-semibold text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-slate-200 transition"><?= (int)$workdaySettings['pomodoro_deep'] ?>m Deep</button>
|
<button onclick="setTimerPreset(<?= (int)$workdaySettings['pomodoro_deep'] ?>)" id="btnPresetDeep" class="px-2.5 py-1 rounded-lg font-medium text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-slate-200 transition"><?= (int)$workdaySettings['pomodoro_deep'] ?>m Deep</button>
|
||||||
<button onclick="setTimerPreset(<?= (int)$workdaySettings['pomodoro_break'] ?>)" id="btnPresetBreak" class="px-3 py-1.5 rounded-lg font-semibold text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-slate-200 transition"><?= (int)$workdaySettings['pomodoro_break'] ?>m Pauze</button>
|
<button onclick="setTimerPreset(<?= (int)$workdaySettings['pomodoro_break'] ?>)" id="btnPresetBreak" class="px-2.5 py-1 rounded-lg font-medium text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-slate-200 transition"><?= (int)$workdaySettings['pomodoro_break'] ?>m Pauze</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-center my-6 relative">
|
<div class="text-center my-6">
|
||||||
<div id="timerDisplay" class="text-6xl sm:text-7xl font-black font-mono tracking-tight text-slate-900 dark:text-white mb-2"><?= sprintf('%02d:00', (int)$workdaySettings['pomodoro_focus']) ?></div>
|
<div id="timerDisplay" class="text-5xl sm:text-6xl font-black font-mono tracking-tight text-slate-900 dark:text-white mb-2"><?= sprintf('%02d:00', (int)$workdaySettings['pomodoro_focus']) ?></div>
|
||||||
<div class="min-h-[26px] text-xs text-slate-500 dark:text-slate-400 truncate max-w-md mx-auto flex items-center justify-center space-x-1.5 px-3.5 py-1 rounded-full bg-slate-100/80 dark:bg-slate-950/80 border border-slate-200/70 dark:border-slate-800/70 w-fit">
|
<div class="min-h-[22px] text-xs text-slate-500 dark:text-slate-400 truncate max-w-sm mx-auto flex items-center justify-center space-x-1">
|
||||||
<span class="w-2 h-2 rounded-full bg-emerald-500 animate-pulse"></span>
|
<span class="text-indigo-600 dark:text-indigo-400 font-medium">Actieve focus:</span>
|
||||||
<span class="text-indigo-600 dark:text-indigo-400 font-semibold">Doeltaak:</span>
|
<span id="activeTaskDisplay" class="text-slate-800 dark:text-slate-200 font-semibold">Kies een taak hieronder</span>
|
||||||
<span id="activeTaskDisplay" class="text-slate-800 dark:text-slate-200 font-bold truncate max-w-[260px]">Kies een taak hieronder</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full bg-slate-100 dark:bg-slate-950 h-2 rounded-full overflow-hidden mt-5 border border-slate-200/80 dark:border-slate-800">
|
<div class="w-full bg-slate-100 dark:bg-slate-950/80 h-1.5 rounded-full overflow-hidden mt-4 border border-slate-200/80 dark:border-slate-800/80">
|
||||||
<div id="timerProgress" class="h-full bg-gradient-to-r from-indigo-500 via-sky-500 to-indigo-600 transition-all duration-300 rounded-full shadow-[0_0_12px_rgba(99,102,241,0.35)]" style="width: 0%"></div>
|
<div id="timerProgress" class="h-full bg-gradient-to-r from-indigo-600 to-sky-400 transition-all duration-300 rounded-full" style="width: 0%"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center justify-center space-x-3">
|
<div class="flex items-center justify-center space-x-3">
|
||||||
<button id="timerToggleBtn" onclick="toggleTimer()" class="flex items-center space-x-2 px-7 py-3 rounded-xl font-bold text-sm bg-gradient-to-r from-indigo-600 to-indigo-500 hover:from-indigo-500 hover:to-indigo-400 text-white transition shadow-md shadow-indigo-600/30 hover:scale-[1.02] active:scale-[0.98] cursor-pointer">
|
<button id="timerToggleBtn" onclick="toggleTimer()" class="flex items-center space-x-2 px-6 py-2.5 rounded-xl font-semibold text-sm bg-indigo-600 hover:bg-indigo-500 text-white transition shadow-sm shadow-indigo-600/20 cursor-pointer">
|
||||||
<i data-lucide="play" class="w-4 h-4 fill-current"></i>
|
<i data-lucide="play" class="w-4 h-4 fill-current"></i>
|
||||||
<span id="timerToggleText">Start Focus</span>
|
<span id="timerToggleText">Start Focus</span>
|
||||||
</button>
|
</button>
|
||||||
<button onclick="resetTimer()" class="p-3 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800/80 dark:hover:bg-slate-700 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-slate-100 transition border border-slate-200 dark:border-slate-700/80 cursor-pointer shadow-2xs" title="Reset">
|
<button onclick="resetTimer()" class="p-2.5 rounded-xl bg-slate-100 hover:bg-slate-200 dark:bg-slate-800/80 dark:hover:bg-slate-700 text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-slate-200 transition border border-slate-200 dark:border-slate-700/60 cursor-pointer" title="Reset">
|
||||||
<i data-lucide="rotate-ccw" class="w-4 h-4"></i>
|
<i data-lucide="rotate-ccw" class="w-4 h-4"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Takenlijst Blok -->
|
<!-- Takenlijst -->
|
||||||
<div class="fociz-card p-6 sm:p-7">
|
<div class="bg-white dark:bg-slate-900/90 border border-slate-200/80 dark:border-slate-800/60 rounded-2xl p-6 shadow-xs backdrop-blur-sm transition">
|
||||||
<div class="flex items-center justify-between mb-5 pb-3 border-b border-slate-100 dark:border-slate-800/60">
|
<div class="flex items-center justify-between mb-4 pb-3 border-b border-slate-100 dark:border-slate-800/60">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-sm font-bold text-slate-900 dark:text-white uppercase tracking-wider flex items-center space-x-2">
|
<h3 class="text-sm font-bold text-slate-900 dark:text-white uppercase tracking-wider flex items-center space-x-2">
|
||||||
<span>Dagtaken & Prioriteiten</span>
|
<span>Dagtaken & Prioriteiten</span>
|
||||||
<span class="px-2 py-0.5 rounded-full text-xs font-bold bg-indigo-50 text-indigo-700 dark:bg-indigo-500/15 dark:text-indigo-300 ring-1 ring-indigo-500/20"><?= count($tasks) ?></span>
|
<span class="text-xs font-normal text-slate-500 dark:text-slate-400">(<?= count($tasks) ?>)</span>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onclick="toggleAddTaskForm()" class="flex items-center space-x-1.5 px-3.5 py-1.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-bold transition shadow-sm shadow-indigo-600/25 cursor-pointer">
|
<button onclick="toggleAddTaskForm()" class="flex items-center space-x-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-semibold transition shadow-sm shadow-indigo-600/20 cursor-pointer">
|
||||||
<i data-lucide="plus" class="w-4 h-4"></i>
|
<i data-lucide="plus" class="w-4 h-4"></i>
|
||||||
<span>Nieuwe Taak</span>
|
<span>Nieuwe Taak</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Nieuwe taak formulier (verborgen by default) -->
|
<!-- Nieuwe taak formulier (verborgen by default) -->
|
||||||
<div id="addTaskForm" class="hidden mb-5 p-5 rounded-2xl bg-slate-50/90 dark:bg-[#0c0f17]/90 border border-indigo-500/30 shadow-xs space-y-3.5 transition">
|
<div id="addTaskForm" class="hidden mb-4 p-4 rounded-xl bg-slate-50 dark:bg-slate-950/80 border border-indigo-500/30 space-y-3 transition">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Taaktitel</label>
|
<label class="block text-[11px] font-medium text-slate-600 dark:text-slate-400 mb-1">Taaktitel</label>
|
||||||
<input type="text" id="newTaskTitle" placeholder="Wat moet er vandaag gedaan worden?" class="w-full bg-white dark:bg-[#111624] border border-slate-300 dark:border-slate-800 rounded-xl px-3.5 py-2 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
<input type="text" id="newTaskTitle" placeholder="Wat moet er vandaag gedaan worden?" class="w-full bg-white dark:bg-slate-900 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
|
<<<<<<< HEAD
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-semibold text-slate-700 dark:text-slate-300 mb-1">Prioriteit</label>
|
<label class="block text-[11px] font-semibold text-slate-700 dark:text-slate-300 mb-1">Prioriteit</label>
|
||||||
<select id="newTaskPriority" class="w-full bg-white dark:bg-[#111624] border border-slate-300 dark:border-slate-800 rounded-xl px-2.5 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
<select id="newTaskPriority" class="w-full bg-white dark:bg-slate-900 border border-slate-300 dark:border-slate-800 rounded-xl px-2.5 py-1.5 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
|
=======
|
||||||
|
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3">
|
||||||
|
<div>
|
||||||
|
<label class="block text-[11px] font-medium text-slate-600 dark:text-slate-400 mb-1">Prioriteit</label>
|
||||||
|
<select id="newTaskPriority" class="w-full bg-white dark:bg-slate-900 border border-slate-300 dark:border-slate-800 rounded-xl px-2.5 py-1.5 text-slate-900 dark:text-white text-xs focus:outline-none">
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
<option value="P1">P1 - Brandend / Focus</option>
|
<option value="P1">P1 - Brandend / Focus</option>
|
||||||
<option value="P2" selected>P2 - Belangrijk (Standaard)</option>
|
<option value="P2" selected>P2 - Belangrijk (Standaard)</option>
|
||||||
<option value="P3">P3 - Regulier / Lage druk</option>
|
<option value="P3">P3 - Regulier / Lage druk</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
<<<<<<< HEAD
|
||||||
<label class="block text-[11px] font-semibold text-slate-700 dark:text-slate-300 mb-1">Starttijd</label>
|
<label class="block text-[11px] font-semibold text-slate-700 dark:text-slate-300 mb-1">Starttijd</label>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input type="text" id="newTaskTime" placeholder="Bijv. 09:30" class="w-full bg-white dark:bg-[#111624] border border-slate-300 dark:border-slate-800 rounded-xl pl-3 pr-7 py-2 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500" oninput="onNewTaskTimeOrDurationChange('start')">
|
<input type="text" id="newTaskTime" placeholder="Bijv. 09:30" class="w-full bg-white dark:bg-slate-900 border border-slate-300 dark:border-slate-800 rounded-xl pl-2.5 pr-7 py-1.5 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500" oninput="onNewTaskTimeOrDurationChange('start')">
|
||||||
<i data-lucide="clock" class="w-3.5 h-3.5 text-slate-400 absolute right-2.5 top-2.5 pointer-events-none"></i>
|
<i data-lucide="clock" class="w-3.5 h-3.5 text-slate-400 absolute right-2.5 top-2 pointer-events-none"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -534,8 +601,8 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<span class="text-[9px] text-indigo-600 dark:text-indigo-400 font-medium">Vrij invulbaar</span>
|
<span class="text-[9px] text-indigo-600 dark:text-indigo-400 font-medium">Vrij invulbaar</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input type="text" id="newTaskEndTime" placeholder="Bijv. 09:40" class="w-full bg-white dark:bg-[#111624] border border-slate-300 dark:border-slate-800 rounded-xl pl-3 pr-7 py-2 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500" oninput="onNewTaskTimeOrDurationChange('end')">
|
<input type="text" id="newTaskEndTime" placeholder="Bijv. 09:40" class="w-full bg-white dark:bg-slate-900 border border-slate-300 dark:border-slate-800 rounded-xl pl-2.5 pr-7 py-1.5 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500" oninput="onNewTaskTimeOrDurationChange('end')">
|
||||||
<i data-lucide="clock-arrow-down" class="w-3.5 h-3.5 text-slate-400 absolute right-2.5 top-2.5 pointer-events-none"></i>
|
<i data-lucide="clock-arrow-down" class="w-3.5 h-3.5 text-slate-400 absolute right-2.5 top-2 pointer-events-none"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -547,7 +614,7 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<?php
|
<?php
|
||||||
$defDuration = (int)($workdaySettings['default_task_duration'] ?? 30);
|
$defDuration = (int)($workdaySettings['default_task_duration'] ?? 30);
|
||||||
?>
|
?>
|
||||||
<select id="newTaskDuration" class="w-full bg-white dark:bg-[#111624] border border-slate-300 dark:border-slate-800 rounded-xl px-2.5 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500" onchange="onNewTaskTimeOrDurationChange('duration')">
|
<select id="newTaskDuration" class="w-full bg-white dark:bg-slate-900 border border-slate-300 dark:border-slate-800 rounded-xl px-2.5 py-1.5 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500" onchange="onNewTaskTimeOrDurationChange('duration')">
|
||||||
<option value="5" <?= $defDuration === 5 ? 'selected' : '' ?>>5 minuten</option>
|
<option value="5" <?= $defDuration === 5 ? 'selected' : '' ?>>5 minuten</option>
|
||||||
<option value="10" <?= $defDuration === 10 ? 'selected' : '' ?>>10 minuten</option>
|
<option value="10" <?= $defDuration === 10 ? 'selected' : '' ?>>10 minuten</option>
|
||||||
<option value="15" <?= $defDuration === 15 ? 'selected' : '' ?>>15 minuten</option>
|
<option value="15" <?= $defDuration === 15 ? 'selected' : '' ?>>15 minuten</option>
|
||||||
@@ -560,16 +627,32 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<option value="120" <?= $defDuration === 120 ? 'selected' : '' ?>>120 minuten (2 uur)</option>
|
<option value="120" <?= $defDuration === 120 ? 'selected' : '' ?>>120 minuten (2 uur)</option>
|
||||||
<option value="custom">Aangepast...</option>
|
<option value="custom">Aangepast...</option>
|
||||||
</select>
|
</select>
|
||||||
<input type="number" id="newTaskCustomDuration" min="1" max="720" placeholder="Min" class="hidden w-20 bg-white dark:bg-[#111624] border border-slate-300 dark:border-slate-800 rounded-xl px-2 py-2 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500" oninput="onNewTaskTimeOrDurationChange('custom_duration')">
|
<input type="number" id="newTaskCustomDuration" min="1" max="720" placeholder="Min" class="hidden w-20 bg-white dark:bg-slate-900 border border-slate-300 dark:border-slate-800 rounded-xl px-2 py-1.5 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500" oninput="onNewTaskTimeOrDurationChange('custom_duration')">
|
||||||
</div>
|
</div>
|
||||||
|
=======
|
||||||
|
<label class="block text-[11px] font-medium text-slate-600 dark:text-slate-400 mb-1">Tijdblok (Starttijd)</label>
|
||||||
|
<input type="text" id="newTaskTime" placeholder="Bijv. 09:30" class="w-full bg-white dark:bg-slate-900 border border-slate-300 dark:border-slate-800 rounded-xl px-2.5 py-1.5 text-slate-900 dark:text-white text-xs font-mono focus:outline-none">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-[11px] font-medium text-slate-600 dark:text-slate-400 mb-1">Tijdsduur</label>
|
||||||
|
<select id="newTaskDuration" class="w-full bg-white dark:bg-slate-900 border border-slate-300 dark:border-slate-800 rounded-xl px-2.5 py-1.5 text-slate-900 dark:text-white text-xs focus:outline-none">
|
||||||
|
<?php
|
||||||
|
$defDuration = (int)($workdaySettings['default_task_duration'] ?? 30);
|
||||||
|
$durations = [15 => '15 minuten', 30 => '30 minuten', 45 => '45 minuten', 60 => '60 minuten (1 uur)', 90 => '90 minuten (1,5 uur)', 120 => '120 minuten (2 uur)'];
|
||||||
|
foreach ($durations as $mins => $label):
|
||||||
|
?>
|
||||||
|
<option value="<?= $mins ?>" <?= $defDuration === $mins ? 'selected' : '' ?>><?= $label ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($isOutlookConnected): ?>
|
<?php if ($isOutlookConnected): ?>
|
||||||
<div class="p-3 rounded-xl bg-sky-50/80 dark:bg-sky-950/40 border border-sky-200/70 dark:border-sky-800/50">
|
<div class="p-2.5 rounded-xl bg-sky-50/70 dark:bg-sky-950/30 border border-sky-200/70 dark:border-sky-800/40">
|
||||||
<label class="flex items-center space-x-2 text-xs text-sky-900 dark:text-sky-200 cursor-pointer select-none">
|
<label class="flex items-center space-x-2 text-xs text-sky-900 dark:text-sky-200 cursor-pointer select-none">
|
||||||
<input type="checkbox" id="newTaskSyncOutlook" checked class="w-4 h-4 rounded text-indigo-600 focus:ring-indigo-500 border-slate-300 dark:border-slate-700">
|
<input type="checkbox" id="newTaskSyncOutlook" checked class="w-4 h-4 rounded text-indigo-600 focus:ring-indigo-500 border-slate-300 dark:border-slate-700">
|
||||||
<span class="flex items-center space-x-1.5 font-semibold">
|
<span class="flex items-center space-x-1.5 font-medium">
|
||||||
<i data-lucide="calendar" class="w-3.5 h-3.5 text-sky-500"></i>
|
<i data-lucide="calendar" class="w-3.5 h-3.5 text-sky-500"></i>
|
||||||
<span>Direct inplannen in Microsoft Outlook agenda</span>
|
<span>Direct inplannen in Microsoft Outlook agenda</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -578,22 +661,20 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<div class="flex space-x-2 pt-1">
|
<div class="flex space-x-2 pt-1">
|
||||||
<button onclick="submitNewTask()" class="px-5 py-2 bg-indigo-600 hover:bg-indigo-500 text-white font-bold rounded-xl text-xs transition cursor-pointer shadow-xs">Opslaan</button>
|
<button onclick="submitNewTask()" class="px-4 py-1.5 bg-indigo-600 hover:bg-indigo-500 text-white font-semibold rounded-lg text-xs transition cursor-pointer">Opslaan</button>
|
||||||
<button onclick="toggleAddTaskForm()" class="px-4 py-2 bg-slate-200 hover:bg-slate-300 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-400 rounded-xl text-xs transition cursor-pointer">Annuleren</button>
|
<button onclick="toggleAddTaskForm()" class="px-3 py-1.5 bg-slate-200 hover:bg-slate-300 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-400 rounded-lg text-xs transition cursor-pointer">Annuleren</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Taken weergave -->
|
<!-- Taken weergave -->
|
||||||
<div class="space-y-2.5" id="tasksContainer">
|
<div class="space-y-2" id="tasksContainer">
|
||||||
<?php if (empty($tasks)): ?>
|
<?php if (empty($tasks)): ?>
|
||||||
<div class="text-center py-10 text-slate-400 dark:text-slate-500 text-xs">
|
<div class="text-center py-8 text-slate-400 dark:text-slate-500 text-xs">
|
||||||
<i data-lucide="check-circle" class="w-8 h-8 text-slate-300 dark:text-slate-700 mx-auto mb-2"></i>
|
Nog geen taken gepland voor <?= htmlspecialchars($formattedSelectedDate) ?>. Klik op 'Nieuwe Taak' of importeer een Jira ticket hieronder.
|
||||||
<p>Nog geen taken gepland voor <?= htmlspecialchars($formattedSelectedDate) ?>.</p>
|
|
||||||
<p class="text-[11px] mt-0.5">Klik op 'Nieuwe Taak' of importeer een Jira ticket hieronder.</p>
|
|
||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($tasks as $task): ?>
|
<?php foreach ($tasks as $task): ?>
|
||||||
<div class="fociz-card-interactive group flex items-center justify-between p-3.5 rounded-2xl border <?= $task['is_completed'] ? 'bg-slate-50/50 dark:bg-slate-950/25 border-slate-200/60 dark:border-slate-800/40 opacity-60' : 'bg-white/95 dark:bg-[#111624]/90 border-slate-200/80 dark:border-slate-800/80 hover:border-indigo-400 dark:hover:border-indigo-500/50 shadow-2xs hover:shadow-xs' ?> <?= $task['priority'] === 'P1' ? 'border-l-4 border-l-rose-500' : ($task['priority'] === 'P2' ? 'border-l-4 border-l-amber-500' : 'border-l-4 border-l-indigo-400 dark:border-l-indigo-500') ?> transition min-w-0" id="task-row-<?= $task['id'] ?>">
|
<div class="group flex items-center justify-between p-3 rounded-xl border <?= $task['is_completed'] ? 'bg-slate-50/50 dark:bg-slate-950/30 border-slate-200 dark:border-slate-900 opacity-60' : 'bg-white dark:bg-slate-950/40 border-slate-200/80 dark:border-slate-800/70 hover:border-slate-300 dark:hover:border-slate-700' ?> transition shadow-2xs" id="task-row-<?= $task['id'] ?>">
|
||||||
<div class="flex items-center space-x-3 truncate mr-2">
|
<div class="flex items-center space-x-3 truncate mr-2">
|
||||||
<button onclick="toggleTask(<?= $task['id'] ?>, <?= $task['is_completed'] ? 0 : 1 ?>)" class="w-5 h-5 rounded-lg border flex items-center justify-center transition <?= $task['is_completed'] ? 'bg-indigo-600 border-indigo-600 text-white font-bold' : 'border-slate-300 dark:border-slate-700 hover:border-indigo-500 bg-white dark:bg-slate-900' ?>">
|
<button onclick="toggleTask(<?= $task['id'] ?>, <?= $task['is_completed'] ? 0 : 1 ?>)" class="w-5 h-5 rounded-lg border flex items-center justify-center transition <?= $task['is_completed'] ? 'bg-indigo-600 border-indigo-600 text-white font-bold' : 'border-slate-300 dark:border-slate-700 hover:border-indigo-500 bg-white dark:bg-slate-900' ?>">
|
||||||
<?php if ($task['is_completed']): ?>
|
<?php if ($task['is_completed']): ?>
|
||||||
@@ -613,7 +694,7 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<span>OUTLOOK</span>
|
<span>OUTLOOK</span>
|
||||||
</span>
|
</span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<span class="text-xs font-semibold truncate <?= $task['is_completed'] ? 'line-through text-slate-400 dark:text-slate-500' : 'text-slate-800 dark:text-slate-200' ?>">
|
<span class="text-xs font-medium truncate <?= $task['is_completed'] ? 'line-through text-slate-400 dark:text-slate-500' : 'text-slate-800 dark:text-slate-200' ?>">
|
||||||
<?= htmlspecialchars($task['title']) ?>
|
<?= htmlspecialchars($task['title']) ?>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -622,7 +703,11 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<?php if (!empty($task['time_block_start'])): ?>
|
<?php if (!empty($task['time_block_start'])): ?>
|
||||||
<span class="text-[10px] text-slate-500 dark:text-slate-400 font-mono flex items-center space-x-1">
|
<span class="text-[10px] text-slate-500 dark:text-slate-400 font-mono flex items-center space-x-1">
|
||||||
<i data-lucide="clock" class="w-2.5 h-2.5"></i>
|
<i data-lucide="clock" class="w-2.5 h-2.5"></i>
|
||||||
|
<<<<<<< HEAD
|
||||||
<span><?= htmlspecialchars($task['time_block_start']) ?><?= !empty($task['time_block_end']) ? ' - ' . htmlspecialchars($task['time_block_end']) : '' ?><?= !empty($task['duration_minutes']) ? ' (' . (int)$task['duration_minutes'] . 'm)' : '' ?></span>
|
<span><?= htmlspecialchars($task['time_block_start']) ?><?= !empty($task['time_block_end']) ? ' - ' . htmlspecialchars($task['time_block_end']) : '' ?><?= !empty($task['duration_minutes']) ? ' (' . (int)$task['duration_minutes'] . 'm)' : '' ?></span>
|
||||||
|
=======
|
||||||
|
<span><?= htmlspecialchars($task['time_block_start']) ?><?= !empty($task['time_block_end']) ? ' - ' . htmlspecialchars($task['time_block_end']) : '' ?></span>
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
</span>
|
</span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php if (!empty($task['external_url'])): ?>
|
<?php if (!empty($task['external_url'])): ?>
|
||||||
@@ -648,11 +733,16 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (!$task['is_completed']): ?>
|
<?php if (!$task['is_completed']): ?>
|
||||||
|
<<<<<<< HEAD
|
||||||
<button onclick="selectFocusTask('<?= htmlspecialchars(addslashes($task['title'])) ?>')" title="Koppel aan Focus Timer" class="p-1.5 rounded-lg text-slate-400 hover:text-amber-500 hover:bg-amber-500/10 transition cursor-pointer">
|
<button onclick="selectFocusTask('<?= htmlspecialchars(addslashes($task['title'])) ?>')" title="Koppel aan Focus Timer" class="p-1.5 rounded-lg text-slate-400 hover:text-amber-500 hover:bg-amber-500/10 transition cursor-pointer">
|
||||||
|
=======
|
||||||
|
<button onclick="selectFocusTask('<?= htmlspecialchars(addslashes($task['title'])) ?>')" title="Koppel aan Focus Timer" class="p-1.5 rounded-lg text-slate-400 hover:text-amber-500 hover:bg-amber-500/10 transition">
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
<i data-lucide="flame" class="w-3.5 h-3.5"></i>
|
<i data-lucide="flame" class="w-3.5 h-3.5"></i>
|
||||||
</button>
|
</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
<button onclick="openEditTaskModal(<?= htmlspecialchars(json_encode([
|
<button onclick="openEditTaskModal(<?= htmlspecialchars(json_encode([
|
||||||
'id' => (int)$task['id'],
|
'id' => (int)$task['id'],
|
||||||
'title' => $task['title'],
|
'title' => $task['title'],
|
||||||
@@ -667,6 +757,9 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button onclick="deleteTask(<?= $task['id'] ?>)" title="Verwijderen" class="p-1.5 rounded-lg text-slate-400 hover:text-red-600 dark:hover:text-red-400 hover:bg-red-500/10 opacity-0 group-hover:opacity-100 transition cursor-pointer">
|
<button onclick="deleteTask(<?= $task['id'] ?>)" title="Verwijderen" class="p-1.5 rounded-lg text-slate-400 hover:text-red-600 dark:hover:text-red-400 hover:bg-red-500/10 opacity-0 group-hover:opacity-100 transition cursor-pointer">
|
||||||
|
=======
|
||||||
|
<button onclick="deleteTask(<?= $task['id'] ?>)" title="Verwijderen" class="p-1.5 rounded-lg text-slate-400 hover:text-red-600 dark:hover:text-red-400 hover:bg-red-500/10 opacity-0 group-hover:opacity-100 transition">
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
<i data-lucide="trash-2" class="w-3.5 h-3.5"></i>
|
<i data-lucide="trash-2" class="w-3.5 h-3.5"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -677,19 +770,19 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Jira Snelle Import Widget -->
|
<!-- Jira Snelle Import Widget -->
|
||||||
<div id="jiraPanel" class="fociz-card p-6">
|
<div id="jiraPanel" class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-6 shadow-xs backdrop-blur-sm transition">
|
||||||
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800 mb-3">
|
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800 mb-3">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<i data-lucide="trello" class="w-4 h-4 text-sky-500"></i>
|
<i data-lucide="trello" class="w-4 h-4 text-sky-500"></i>
|
||||||
<h3 class="text-xs font-bold text-slate-900 dark:text-white uppercase tracking-wider">
|
<h3 class="text-xs font-semibold text-slate-900 dark:text-white uppercase tracking-wider">
|
||||||
Mijn Jira Tickets
|
Mijn Jira Tickets
|
||||||
</h3>
|
</h3>
|
||||||
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold <?= $isJiraLive ? 'bg-sky-50 dark:bg-sky-500/15 text-sky-700 dark:text-sky-400 border border-sky-200 dark:border-sky-500/30' : 'bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-400' ?>">
|
<span class="px-2 py-0.5 rounded-full text-[10px] font-semibold <?= $isJiraLive ? 'bg-sky-50 dark:bg-sky-500/15 text-sky-700 dark:text-sky-400 border border-sky-200 dark:border-sky-500/30' : 'bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-400' ?>">
|
||||||
<?= count($jiraIssues) ?>
|
<?= count($jiraIssues) ?>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="/profile.php" class="text-xs text-slate-500 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition flex items-center space-x-1 font-medium">
|
<a href="/profile.php" class="text-xs text-slate-500 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition flex items-center space-x-1">
|
||||||
<span>Beheren</span>
|
<span>Beheren</span>
|
||||||
<i data-lucide="chevron-right" class="w-3.5 h-3.5"></i>
|
<i data-lucide="chevron-right" class="w-3.5 h-3.5"></i>
|
||||||
</a>
|
</a>
|
||||||
@@ -702,7 +795,7 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<div class="space-y-2 max-h-64 overflow-y-auto pr-1">
|
<div class="space-y-2 max-h-64 overflow-y-auto pr-1">
|
||||||
<?php foreach (array_slice($jiraIssues, 0, 6) as $issue): ?>
|
<?php foreach (array_slice($jiraIssues, 0, 6) as $issue): ?>
|
||||||
<div class="fociz-card-interactive flex items-center justify-between p-2.5 rounded-xl bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-200/80 dark:border-slate-800/80 hover:border-indigo-300 dark:hover:border-indigo-600/50 transition shadow-2xs">
|
<div class="flex items-center justify-between p-2.5 rounded-xl bg-slate-50/70 dark:bg-slate-900/60 border border-slate-200/80 dark:border-slate-800/80 hover:border-slate-300 dark:hover:border-slate-700 transition shadow-xs">
|
||||||
<div class="truncate mr-2">
|
<div class="truncate mr-2">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<span class="font-mono text-[10px] font-bold text-sky-700 dark:text-sky-400 bg-sky-50 dark:bg-sky-500/10 border border-sky-200 dark:border-sky-500/20 px-1.5 py-0.5 rounded">
|
<span class="font-mono text-[10px] font-bold text-sky-700 dark:text-sky-400 bg-sky-50 dark:bg-sky-500/10 border border-sky-200 dark:border-sky-500/20 px-1.5 py-0.5 rounded">
|
||||||
@@ -732,28 +825,28 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Dagnotities & Reflectie -->
|
<!-- Dagnotities & Reflectie -->
|
||||||
<div class="fociz-card p-6">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-6 shadow-xs backdrop-blur-sm transition">
|
||||||
<div class="flex items-center space-x-2 mb-3">
|
<div class="flex items-center space-x-2 mb-3">
|
||||||
<i data-lucide="book-open" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="book-open" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<h3 class="text-xs font-bold text-slate-900 dark:text-white uppercase tracking-wider">Dagnotities & Kladblok</h3>
|
<h3 class="text-xs font-semibold text-slate-900 dark:text-white uppercase tracking-wider">Dagnotities & Kladblok</h3>
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
<textarea
|
||||||
id="dailyNotesInput"
|
id="dailyNotesInput"
|
||||||
rows="3"
|
rows="3"
|
||||||
placeholder="Belangrijke aantekeningen, reflecties of snelle memo's voor vandaag..."
|
placeholder="Belangrijke aantekeningen, reflecties of snelle memo's voor vandaag..."
|
||||||
onblur="saveGoal()"
|
onblur="saveGoal()"
|
||||||
class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-200 dark:border-slate-800 rounded-xl p-3 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 resize-none transition shadow-2xs"
|
class="w-full bg-slate-50/70 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl p-3 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 resize-none transition"
|
||||||
><?= htmlspecialchars($dailyPlan['notes'] ?? '') ?></textarea>
|
><?= htmlspecialchars($dailyPlan['notes'] ?? '') ?></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Rechter kolom: Timeblocking & Outlook Tijdlijn -->
|
<!-- Rechter kolom: Timeblocking & Outlook Tijdlijn -->
|
||||||
<div class="lg:col-span-5 space-y-6 min-w-0">
|
<div class="lg:col-span-5 space-y-6 min-w-0">
|
||||||
<div class="fociz-card p-5 sm:p-6 overflow-hidden">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-5 sm:p-6 shadow-xs backdrop-blur-sm transition overflow-hidden">
|
||||||
<div class="flex items-center justify-between mb-4 pb-3 border-b border-slate-100 dark:border-slate-800">
|
<div class="flex items-center justify-between mb-4 pb-3 border-b border-slate-100 dark:border-slate-800">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<i data-lucide="clock" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="clock" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<h3 class="text-xs font-bold text-slate-900 dark:text-white uppercase tracking-wider">Tijdlijn & Time-blocking</h3>
|
<h3 class="text-xs font-semibold text-slate-900 dark:text-white uppercase tracking-wider">Tijdlijn & Time-blocking</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<?php if ($aiSettings['ai_enabled'] && $aiSettings['has_key']): ?>
|
<?php if ($aiSettings['ai_enabled'] && $aiSettings['has_key']): ?>
|
||||||
@@ -763,7 +856,7 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
</button>
|
</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php if ($isOutlookConnected): ?>
|
<?php if ($isOutlookConnected): ?>
|
||||||
<span class="px-2 py-0.5 rounded-lg bg-sky-50 dark:bg-sky-500/10 border border-sky-200 dark:border-sky-500/20 text-sky-700 dark:text-sky-400 text-[10px] font-semibold">Outlook 365</span>
|
<span class="px-2 py-0.5 rounded bg-sky-50 dark:bg-sky-500/10 border border-sky-200 dark:border-sky-500/20 text-sky-700 dark:text-sky-400 text-[10px] font-semibold">Outlook 365</span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<span class="text-xs text-slate-500 dark:text-slate-400 font-mono"><?= $hours[0] ?> – <?= end($hours) ?></span>
|
<span class="text-xs text-slate-500 dark:text-slate-400 font-mono"><?= $hours[0] ?> – <?= end($hours) ?></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -786,16 +879,16 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
});
|
});
|
||||||
?>
|
?>
|
||||||
<div class="flex items-start group min-h-[48px] border-b border-slate-100 dark:border-slate-800/40 pb-2.5 last:border-0 min-w-0">
|
<div class="flex items-start group min-h-[48px] border-b border-slate-100 dark:border-slate-800/40 pb-2.5 last:border-0 min-w-0">
|
||||||
<div class="w-12 sm:w-14 text-xs font-mono font-semibold text-slate-500 dark:text-slate-400 pt-1.5 flex-shrink-0">
|
<div class="w-12 sm:w-14 text-xs font-mono font-medium text-slate-500 dark:text-slate-400 pt-1 flex-shrink-0">
|
||||||
<?= $hour ?>
|
<?= $hour ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-1 space-y-1.5 min-w-0">
|
<div class="flex-1 space-y-1.5 min-w-0">
|
||||||
<?php if ($isLunchSlot): ?>
|
<?php if ($isLunchSlot): ?>
|
||||||
<!-- Automatische Lunchpauze Reservering (Release v1.4) -->
|
<!-- Automatische Lunchpauze Reservering (Release v1.4) -->
|
||||||
<div class="p-3 rounded-xl bg-amber-500/10 dark:bg-amber-500/15 border-l-4 border-l-amber-500 border border-amber-500/20 text-amber-900 dark:text-amber-200 text-xs shadow-2xs flex items-center justify-between min-w-0 transition-all">
|
<div class="p-2.5 rounded-xl bg-amber-50/80 dark:bg-amber-950/25 border border-amber-200/80 dark:border-amber-800/40 text-amber-950 dark:text-amber-200 text-xs shadow-xs flex items-center justify-between min-w-0">
|
||||||
<div class="flex items-center space-x-2.5 min-w-0">
|
<div class="flex items-center space-x-2.5 min-w-0">
|
||||||
<span class="px-2 py-0.5 rounded-md bg-amber-500/20 text-amber-900 dark:text-amber-200 font-mono text-[10px] font-bold flex-shrink-0">
|
<span class="px-2 py-0.5 rounded-md bg-amber-500/15 text-amber-800 dark:text-amber-300 font-mono text-[10px] font-bold flex-shrink-0">
|
||||||
<?= htmlspecialchars($lunchStart) ?> - <?= htmlspecialchars($lunchEnd) ?>
|
<?= htmlspecialchars($lunchStart) ?> - <?= htmlspecialchars($lunchEnd) ?>
|
||||||
</span>
|
</span>
|
||||||
<span class="font-semibold text-xs flex items-center space-x-1.5 truncate">
|
<span class="font-semibold text-xs flex items-center space-x-1.5 truncate">
|
||||||
@@ -809,7 +902,7 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
|
|
||||||
<!-- Outlook meetings -->
|
<!-- Outlook meetings -->
|
||||||
<?php foreach ($slotEvents as $evt): ?>
|
<?php foreach ($slotEvents as $evt): ?>
|
||||||
<div class="p-3 rounded-xl bg-sky-500/[0.07] dark:bg-sky-500/[0.12] border-l-4 border-l-sky-500 border border-sky-500/20 text-sky-950 dark:text-sky-100 text-xs shadow-2xs min-w-0 overflow-hidden transition-all hover:bg-sky-500/[0.10] dark:hover:bg-sky-500/[0.16]">
|
<div class="p-2.5 rounded-xl bg-sky-50/80 dark:bg-sky-950/30 border border-sky-200/80 dark:border-sky-800/40 text-sky-950 dark:text-sky-100 text-xs shadow-xs min-w-0 overflow-hidden">
|
||||||
<div class="flex items-start justify-between gap-2.5 min-w-0">
|
<div class="flex items-start justify-between gap-2.5 min-w-0">
|
||||||
<div class="flex items-start space-x-2 min-w-0 flex-1">
|
<div class="flex items-start space-x-2 min-w-0 flex-1">
|
||||||
<span class="px-2 py-0.5 rounded-md bg-sky-500/15 text-sky-800 dark:text-sky-300 font-mono text-[10px] font-bold flex-shrink-0 whitespace-nowrap mt-0.5">
|
<span class="px-2 py-0.5 rounded-md bg-sky-500/15 text-sky-800 dark:text-sky-300 font-mono text-[10px] font-bold flex-shrink-0 whitespace-nowrap mt-0.5">
|
||||||
@@ -838,7 +931,7 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
|
|
||||||
<!-- Geplande taken -->
|
<!-- Geplande taken -->
|
||||||
<?php foreach ($slotTasks as $t): ?>
|
<?php foreach ($slotTasks as $t): ?>
|
||||||
<div class="p-3 rounded-xl border-l-4 <?= $t['priority'] === 'P1' ? 'border-l-rose-500' : ($t['priority'] === 'P2' ? 'border-l-amber-500' : 'border-l-indigo-400') ?> <?= $t['is_completed'] ? 'bg-slate-100/60 dark:bg-slate-900/40 border border-slate-200 dark:border-slate-800 text-slate-400 dark:text-slate-500 line-through' : 'bg-white/80 dark:bg-[#0c0f17]/70 border border-slate-200/90 dark:border-slate-800 text-slate-900 dark:text-slate-100 shadow-2xs hover:shadow-xs' ?> text-xs min-w-0 overflow-hidden transition-all">
|
<div class="p-2.5 rounded-xl border text-xs min-w-0 overflow-hidden transition <?= $t['is_completed'] ? 'bg-slate-50 dark:bg-slate-900/40 border-slate-200 dark:border-slate-800 text-slate-400 dark:text-slate-500 line-through' : 'bg-white dark:bg-[#111622] border-slate-200/80 dark:border-slate-800 text-slate-900 dark:text-slate-100 shadow-xs' ?>">
|
||||||
<div class="flex items-start justify-between gap-2.5 min-w-0">
|
<div class="flex items-start justify-between gap-2.5 min-w-0">
|
||||||
<div class="flex items-start space-x-2 min-w-0 flex-1">
|
<div class="flex items-start space-x-2 min-w-0 flex-1">
|
||||||
<span class="px-2 py-0.5 rounded-md bg-indigo-50 dark:bg-indigo-500/10 text-indigo-700 dark:text-indigo-300 border border-indigo-200 dark:border-indigo-500/20 font-mono text-[10px] font-bold flex-shrink-0 whitespace-nowrap mt-0.5">
|
<span class="px-2 py-0.5 rounded-md bg-indigo-50 dark:bg-indigo-500/10 text-indigo-700 dark:text-indigo-300 border border-indigo-200 dark:border-indigo-500/20 font-mono text-[10px] font-bold flex-shrink-0 whitespace-nowrap mt-0.5">
|
||||||
@@ -869,9 +962,8 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|
||||||
<?php if (empty($slotEvents) && empty($slotTasks) && !$isLunchSlot): ?>
|
<?php if (empty($slotEvents) && empty($slotTasks) && !$isLunchSlot): ?>
|
||||||
<button onclick="quickSchedule('<?= $hour ?>')" class="w-full text-left py-2 px-3 rounded-xl border border-dashed border-slate-200 dark:border-slate-800/80 hover:border-indigo-400 dark:hover:border-indigo-500/50 hover:bg-indigo-500/[0.04] dark:hover:bg-indigo-500/[0.08] text-slate-400 dark:text-slate-500 hover:text-indigo-600 dark:hover:text-indigo-400 text-xs font-medium transition flex items-center justify-between group/slot cursor-pointer">
|
<button onclick="quickSchedule('<?= $hour ?>')" class="w-full text-left py-1.5 px-2.5 rounded-xl border border-dashed border-slate-200 dark:border-slate-800 hover:border-indigo-300 dark:hover:border-indigo-700/60 hover:bg-indigo-50/40 dark:hover:bg-indigo-950/20 text-slate-400 dark:text-slate-500 hover:text-indigo-600 dark:hover:text-indigo-400 text-xs transition cursor-pointer">
|
||||||
<span>+ Plan taak om <?= $hour ?></span>
|
+ Plan taak om <?= $hour ?>
|
||||||
<i data-lucide="plus" class="w-3.5 h-3.5 opacity-0 group-hover/slot:opacity-100 transition-opacity"></i>
|
|
||||||
</button>
|
</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
@@ -883,9 +975,10 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
<!-- Modal: Taak & Tijdblok Bewerken (Vrij invullen van tijden & duur) -->
|
<!-- Modal: Taak & Tijdblok Bewerken (Vrij invullen van tijden & duur) -->
|
||||||
<div id="editTaskModal" class="fixed inset-0 z-50 bg-slate-950/70 backdrop-blur-sm hidden items-center justify-center p-4">
|
<div id="editTaskModal" class="fixed inset-0 z-50 bg-slate-900/60 backdrop-blur-xs hidden items-center justify-center p-4">
|
||||||
<div class="fociz-card p-6 w-full max-w-lg shadow-2xl space-y-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/90 dark:border-slate-800 rounded-2xl p-6 w-full max-w-lg shadow-2xl space-y-4">
|
||||||
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800/80">
|
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800/80">
|
||||||
<div class="flex items-center space-x-2.5">
|
<div class="flex items-center space-x-2.5">
|
||||||
<div class="w-8 h-8 rounded-xl bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 text-indigo-600 dark:text-indigo-400 flex items-center justify-center">
|
<div class="w-8 h-8 rounded-xl bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 text-indigo-600 dark:text-indigo-400 flex items-center justify-center">
|
||||||
@@ -905,13 +998,13 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Taaktitel</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Taaktitel</label>
|
||||||
<input type="text" id="editTaskTitle" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<input type="text" id="editTaskTitle" class="w-full bg-white dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Prioriteit</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Prioriteit</label>
|
||||||
<select id="editTaskPriority" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-2.5 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select id="editTaskPriority" class="w-full bg-white dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl px-2.5 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="P1">P1 - Brandend / Focus</option>
|
<option value="P1">P1 - Brandend / Focus</option>
|
||||||
<option value="P2">P2 - Belangrijk (Standaard)</option>
|
<option value="P2">P2 - Belangrijk (Standaard)</option>
|
||||||
<option value="P3">P3 - Regulier / Lage druk</option>
|
<option value="P3">P3 - Regulier / Lage druk</option>
|
||||||
@@ -923,7 +1016,7 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<span id="editTaskDurationDisplay" class="text-[11px] font-mono font-bold text-indigo-600 dark:text-indigo-400">30m</span>
|
<span id="editTaskDurationDisplay" class="text-[11px] font-mono font-bold text-indigo-600 dark:text-indigo-400">30m</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center space-x-1.5">
|
<div class="flex items-center space-x-1.5">
|
||||||
<select id="editTaskDuration" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-2.5 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs" onchange="onEditTaskTimeOrDurationChange('duration')">
|
<select id="editTaskDuration" class="w-full bg-white dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl px-2.5 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500" onchange="onEditTaskTimeOrDurationChange('duration')">
|
||||||
<option value="5">5 minuten</option>
|
<option value="5">5 minuten</option>
|
||||||
<option value="10">10 minuten</option>
|
<option value="10">10 minuten</option>
|
||||||
<option value="15">15 minuten</option>
|
<option value="15">15 minuten</option>
|
||||||
@@ -936,7 +1029,7 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<option value="120">120 minuten (2 uur)</option>
|
<option value="120">120 minuten (2 uur)</option>
|
||||||
<option value="custom">Aangepast...</option>
|
<option value="custom">Aangepast...</option>
|
||||||
</select>
|
</select>
|
||||||
<input type="number" id="editTaskCustomDuration" min="1" max="720" placeholder="Min" class="hidden w-20 bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-2 py-2 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs" oninput="onEditTaskTimeOrDurationChange('custom_duration')">
|
<input type="number" id="editTaskCustomDuration" min="1" max="720" placeholder="Min" class="hidden w-20 bg-white dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl px-2 py-2 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500" oninput="onEditTaskTimeOrDurationChange('custom_duration')">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -945,7 +1038,7 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Starttijd</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Starttijd</label>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input type="text" id="editTaskStartTime" placeholder="Bijv. 09:30" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl pl-3 pr-8 py-2 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs" oninput="onEditTaskTimeOrDurationChange('start')">
|
<input type="text" id="editTaskStartTime" placeholder="Bijv. 09:30" class="w-full bg-white dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl pl-3 pr-8 py-2 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500" oninput="onEditTaskTimeOrDurationChange('start')">
|
||||||
<i data-lucide="clock" class="w-4 h-4 text-slate-400 absolute right-2.5 top-2.5 pointer-events-none"></i>
|
<i data-lucide="clock" class="w-4 h-4 text-slate-400 absolute right-2.5 top-2.5 pointer-events-none"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -955,13 +1048,13 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
<span class="text-[9px] text-indigo-600 dark:text-indigo-400 font-medium">Vrij invulbaar</span>
|
<span class="text-[9px] text-indigo-600 dark:text-indigo-400 font-medium">Vrij invulbaar</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input type="text" id="editTaskEndTime" placeholder="Bijv. 09:40" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl pl-3 pr-8 py-2 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs" oninput="onEditTaskTimeOrDurationChange('end')">
|
<input type="text" id="editTaskEndTime" placeholder="Bijv. 09:40" class="w-full bg-white dark:bg-slate-950 border border-slate-300 dark:border-slate-800 rounded-xl pl-3 pr-8 py-2 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500" oninput="onEditTaskTimeOrDurationChange('end')">
|
||||||
<i data-lucide="clock-arrow-down" class="w-4 h-4 text-slate-400 absolute right-2.5 top-2.5 pointer-events-none"></i>
|
<i data-lucide="clock-arrow-down" class="w-4 h-4 text-slate-400 absolute right-2.5 top-2.5 pointer-events-none"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="editTaskOutlookNotice" class="hidden p-3 rounded-xl bg-sky-50 dark:bg-sky-500/10 border border-sky-200 dark:border-sky-500/20 text-sky-800 dark:text-sky-300 text-[11px] flex items-center space-x-2">
|
<div id="editTaskOutlookNotice" class="hidden p-2.5 rounded-xl bg-sky-50 dark:bg-sky-500/10 border border-sky-200 dark:border-sky-500/20 text-sky-800 dark:text-sky-300 text-[11px] flex items-center space-x-2">
|
||||||
<i data-lucide="refresh-cw" class="w-3.5 h-3.5 flex-shrink-0"></i>
|
<i data-lucide="refresh-cw" class="w-3.5 h-3.5 flex-shrink-0"></i>
|
||||||
<span>Deze taak is gekoppeld aan Outlook 365. Wijzigingen worden automatisch in uw Outlook agenda gesynchroniseerd.</span>
|
<span>Deze taak is gekoppeld aan Outlook 365. Wijzigingen worden automatisch in uw Outlook agenda gesynchroniseerd.</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -977,6 +1070,8 @@ for ($h = $startHour; $h <= $endHour; $h++) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
<script>
|
<script>
|
||||||
// --- Focus Timer Logica (Release v1.4) ---
|
// --- Focus Timer Logica (Release v1.4) ---
|
||||||
const pomodoroFocusTime = <?= (int)$workdaySettings['pomodoro_focus'] ?>;
|
const pomodoroFocusTime = <?= (int)$workdaySettings['pomodoro_focus'] ?>;
|
||||||
@@ -1018,7 +1113,10 @@ function toggleTimer() {
|
|||||||
clearInterval(timerInterval);
|
clearInterval(timerInterval);
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
document.getElementById('timerToggleText').innerText = 'Hervatten';
|
document.getElementById('timerToggleText').innerText = 'Hervatten';
|
||||||
|
<<<<<<< HEAD
|
||||||
saveTimerStateBeforeReload();
|
saveTimerStateBeforeReload();
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
} else {
|
} else {
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
document.getElementById('timerToggleText').innerText = 'Pauzeren';
|
document.getElementById('timerToggleText').innerText = 'Pauzeren';
|
||||||
@@ -1029,7 +1127,10 @@ function toggleTimer() {
|
|||||||
} else {
|
} else {
|
||||||
clearInterval(timerInterval);
|
clearInterval(timerInterval);
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
|
<<<<<<< HEAD
|
||||||
sessionStorage.removeItem('fociz_timer_state');
|
sessionStorage.removeItem('fociz_timer_state');
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
document.getElementById('timerToggleText').innerText = 'Start Focus';
|
document.getElementById('timerToggleText').innerText = 'Start Focus';
|
||||||
alert('Focus sessie voltooid! Neem even een korte pauze.');
|
alert('Focus sessie voltooid! Neem even een korte pauze.');
|
||||||
}
|
}
|
||||||
@@ -1041,11 +1142,15 @@ function resetTimer() {
|
|||||||
clearInterval(timerInterval);
|
clearInterval(timerInterval);
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
timerSeconds = totalDuration;
|
timerSeconds = totalDuration;
|
||||||
|
<<<<<<< HEAD
|
||||||
sessionStorage.removeItem('fociz_timer_state');
|
sessionStorage.removeItem('fociz_timer_state');
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
document.getElementById('timerToggleText').innerText = 'Start Focus';
|
document.getElementById('timerToggleText').innerText = 'Start Focus';
|
||||||
updateTimerDisplay();
|
updateTimerDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
function saveTimerStateBeforeReload() {
|
function saveTimerStateBeforeReload() {
|
||||||
try {
|
try {
|
||||||
if (isRunning || timerSeconds < totalDuration) {
|
if (isRunning || timerSeconds < totalDuration) {
|
||||||
@@ -1094,6 +1199,8 @@ window.addEventListener('beforeunload', () => {
|
|||||||
saveTimerStateBeforeReload();
|
saveTimerStateBeforeReload();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
function selectFocusTask(title) {
|
function selectFocusTask(title) {
|
||||||
document.getElementById('activeTaskDisplay').innerText = title;
|
document.getElementById('activeTaskDisplay').innerText = title;
|
||||||
}
|
}
|
||||||
@@ -1124,6 +1231,7 @@ async function saveGoal() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
// --- Tijdblok Hulpfuncties & Vrije Duur Berekening ---
|
// --- Tijdblok Hulpfuncties & Vrije Duur Berekening ---
|
||||||
function parseTimeToMinutes(str) {
|
function parseTimeToMinutes(str) {
|
||||||
if (!str || typeof str !== 'string') return null;
|
if (!str || typeof str !== 'string') return null;
|
||||||
@@ -1257,6 +1365,8 @@ function setSelectedNewTaskDuration(mins) {
|
|||||||
if (durationDisplay) durationDisplay.innerText = `${mins}m`;
|
if (durationDisplay) durationDisplay.innerText = `${mins}m`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
function toggleAddTaskForm() {
|
function toggleAddTaskForm() {
|
||||||
const form = document.getElementById('addTaskForm');
|
const form = document.getElementById('addTaskForm');
|
||||||
form.classList.toggle('hidden');
|
form.classList.toggle('hidden');
|
||||||
@@ -1266,6 +1376,7 @@ function toggleAddTaskForm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function quickSchedule(hour) {
|
function quickSchedule(hour) {
|
||||||
|
<<<<<<< HEAD
|
||||||
const form = document.getElementById('addTaskForm');
|
const form = document.getElementById('addTaskForm');
|
||||||
if (form && form.classList.contains('hidden')) {
|
if (form && form.classList.contains('hidden')) {
|
||||||
form.classList.remove('hidden');
|
form.classList.remove('hidden');
|
||||||
@@ -1278,12 +1389,20 @@ function quickSchedule(hour) {
|
|||||||
const outlookCheckbox = document.getElementById('newTaskSyncOutlook');
|
const outlookCheckbox = document.getElementById('newTaskSyncOutlook');
|
||||||
if (outlookCheckbox) outlookCheckbox.checked = true;
|
if (outlookCheckbox) outlookCheckbox.checked = true;
|
||||||
document.getElementById('newTaskTitle')?.focus();
|
document.getElementById('newTaskTitle')?.focus();
|
||||||
|
=======
|
||||||
|
toggleAddTaskForm();
|
||||||
|
const timeInput = document.getElementById('newTaskTime');
|
||||||
|
if (timeInput) timeInput.value = hour;
|
||||||
|
const outlookCheckbox = document.getElementById('newTaskSyncOutlook');
|
||||||
|
if (outlookCheckbox) outlookCheckbox.checked = true;
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitNewTask() {
|
async function submitNewTask() {
|
||||||
const title = document.getElementById('newTaskTitle').value.trim();
|
const title = document.getElementById('newTaskTitle').value.trim();
|
||||||
const priority = document.getElementById('newTaskPriority').value;
|
const priority = document.getElementById('newTaskPriority').value;
|
||||||
const time = document.getElementById('newTaskTime').value.trim();
|
const time = document.getElementById('newTaskTime').value.trim();
|
||||||
|
<<<<<<< HEAD
|
||||||
const endTime = document.getElementById('newTaskEndTime') ? document.getElementById('newTaskEndTime').value.trim() : '';
|
const endTime = document.getElementById('newTaskEndTime') ? document.getElementById('newTaskEndTime').value.trim() : '';
|
||||||
const duration = getSelectedNewTaskDurationMinutes();
|
const duration = getSelectedNewTaskDurationMinutes();
|
||||||
const syncOutlook = document.getElementById('newTaskSyncOutlook') ? document.getElementById('newTaskSyncOutlook').checked : false;
|
const syncOutlook = document.getElementById('newTaskSyncOutlook') ? document.getElementById('newTaskSyncOutlook').checked : false;
|
||||||
@@ -1292,6 +1411,12 @@ async function submitNewTask() {
|
|||||||
alert('Vul een taaktitel in.');
|
alert('Vul een taaktitel in.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
const duration = document.getElementById('newTaskDuration') ? parseInt(document.getElementById('newTaskDuration').value) : 30;
|
||||||
|
const syncOutlook = document.getElementById('newTaskSyncOutlook') ? document.getElementById('newTaskSyncOutlook').checked : false;
|
||||||
|
|
||||||
|
if (!title) return;
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/planner.php?action=add_task', {
|
const res = await fetch('/api/planner.php?action=add_task', {
|
||||||
@@ -1300,8 +1425,12 @@ async function submitNewTask() {
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
title,
|
title,
|
||||||
priority,
|
priority,
|
||||||
|
<<<<<<< HEAD
|
||||||
time_block_start: time,
|
time_block_start: time,
|
||||||
time_block_end: endTime,
|
time_block_end: endTime,
|
||||||
|
=======
|
||||||
|
time_block_start: time,
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
duration_minutes: duration,
|
duration_minutes: duration,
|
||||||
sync_to_outlook: syncOutlook,
|
sync_to_outlook: syncOutlook,
|
||||||
date: activePlannerDate
|
date: activePlannerDate
|
||||||
@@ -1321,6 +1450,7 @@ async function submitNewTask() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
// --- Taak & Tijdblok Bewerken Modal Logica ---
|
// --- Taak & Tijdblok Bewerken Modal Logica ---
|
||||||
function openEditTaskModal(task) {
|
function openEditTaskModal(task) {
|
||||||
if (!task) return;
|
if (!task) return;
|
||||||
@@ -1509,6 +1639,8 @@ async function submitEditTask() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
async function syncTaskToOutlook(taskId, btn) {
|
async function syncTaskToOutlook(taskId, btn) {
|
||||||
if (!btn) return;
|
if (!btn) return;
|
||||||
const originalHtml = btn.innerHTML;
|
const originalHtml = btn.innerHTML;
|
||||||
@@ -1634,6 +1766,7 @@ async function aiSmartSchedule(btn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
<<<<<<< HEAD
|
||||||
// --- Outlook 365 Auto-Sync & Achtergrond Controle ---
|
// --- Outlook 365 Auto-Sync & Achtergrond Controle ---
|
||||||
const isOutlookConnected = <?= $isOutlookConnected ? 'true' : 'false' ?>;
|
const isOutlookConnected = <?= $isOutlookConnected ? 'true' : 'false' ?>;
|
||||||
let currentSyncHash = '<?= $initialSyncHash ?? '' ?>';
|
let currentSyncHash = '<?= $initialSyncHash ?? '' ?>';
|
||||||
@@ -1722,6 +1855,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||||
|
|||||||
+18
-10
@@ -48,6 +48,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
// 2b. Outlook synchronisatievoorkeuren opslaan
|
// 2b. Outlook synchronisatievoorkeuren opslaan
|
||||||
elseif ($action === 'save_outlook_settings') {
|
elseif ($action === 'save_outlook_settings') {
|
||||||
$syncInterval = (int)($_POST['sync_interval_seconds'] ?? 30);
|
$syncInterval = (int)($_POST['sync_interval_seconds'] ?? 30);
|
||||||
@@ -64,6 +65,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$message = "Uw Microsoft Outlook synchronisatievoorkeur is succesvol opgeslagen.";
|
$message = "Uw Microsoft Outlook synchronisatievoorkeur is succesvol opgeslagen.";
|
||||||
$messageType = 'success';
|
$messageType = 'success';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
// 3. Jira Opslaan & Testen
|
// 3. Jira Opslaan & Testen
|
||||||
elseif ($action === 'save_jira') {
|
elseif ($action === 'save_jira') {
|
||||||
$companyDomain = jira_get_company_domain();
|
$companyDomain = jira_get_company_domain();
|
||||||
@@ -223,7 +227,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
|
|
||||||
<div class="space-y-8 max-w-5xl mx-auto pb-12">
|
<div class="space-y-8 max-w-5xl mx-auto pb-12">
|
||||||
<!-- Profiel Header Card -->
|
<!-- Profiel Header Card -->
|
||||||
<div class="relative overflow-hidden fociz-card p-6 sm:p-8">
|
<div class="relative overflow-hidden bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-6 sm:p-8 shadow-xs transition">
|
||||||
<div class="absolute -top-20 -right-20 w-72 h-72 bg-indigo-500/10 rounded-full blur-3xl pointer-events-none"></div>
|
<div class="absolute -top-20 -right-20 w-72 h-72 bg-indigo-500/10 rounded-full blur-3xl pointer-events-none"></div>
|
||||||
|
|
||||||
<div class="relative z-10 flex flex-col sm:flex-row sm:items-center justify-between gap-6">
|
<div class="relative z-10 flex flex-col sm:flex-row sm:items-center justify-between gap-6">
|
||||||
@@ -236,7 +240,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
|
|
||||||
<div class="space-y-1">
|
<div class="space-y-1">
|
||||||
<div class="flex flex-wrap items-center gap-2">
|
<div class="flex flex-wrap items-center gap-2">
|
||||||
<h1 class="text-2xl sm:text-3xl font-black text-slate-900 dark:text-white tracking-tight">
|
<h1 class="text-2xl sm:text-3xl font-bold text-slate-900 dark:text-white tracking-tight">
|
||||||
<?= htmlspecialchars($userProfile['name']) ?>
|
<?= htmlspecialchars($userProfile['name']) ?>
|
||||||
</h1>
|
</h1>
|
||||||
<?php if ($userProfile['role'] === 'ADMIN'): ?>
|
<?php if ($userProfile['role'] === 'ADMIN'): ?>
|
||||||
@@ -285,7 +289,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<!-- Sectie 0: Weergave & Thema Instellingen (Dark & Light mode) -->
|
<!-- Sectie 0: Weergave & Thema Instellingen (Dark & Light mode) -->
|
||||||
<div class="fociz-card p-6 sm:p-7">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-6 sm:p-7 shadow-xs transition">
|
||||||
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3 pb-6 border-b border-slate-100 dark:border-slate-800/80">
|
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3 pb-6 border-b border-slate-100 dark:border-slate-800/80">
|
||||||
<div class="flex items-center space-x-3.5">
|
<div class="flex items-center space-x-3.5">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 flex items-center justify-center text-indigo-600 dark:text-indigo-400 font-bold shadow-xs">
|
<div class="w-12 h-12 rounded-2xl bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 flex items-center justify-center text-indigo-600 dark:text-indigo-400 font-bold shadow-xs">
|
||||||
@@ -420,7 +424,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sectie 1: Mijn Microsoft 365 Outlook Agenda -->
|
<!-- Sectie 1: Mijn Microsoft 365 Outlook Agenda -->
|
||||||
<div class="fociz-card p-6 sm:p-7">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-6 sm:p-7 shadow-xs transition">
|
||||||
<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 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="flex items-center space-x-3.5">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-sky-50 dark:bg-sky-500/10 border border-sky-200 dark:border-sky-500/20 flex items-center justify-center text-sky-600 dark:text-sky-400 font-bold shadow-xs">
|
<div class="w-12 h-12 rounded-2xl bg-sky-50 dark:bg-sky-500/10 border border-sky-200 dark:border-sky-500/20 flex items-center justify-center text-sky-600 dark:text-sky-400 font-bold shadow-xs">
|
||||||
@@ -478,6 +482,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
<form method="POST" class="mt-4 p-4 rounded-xl bg-slate-50/70 dark:bg-slate-900/60 border border-slate-200/80 dark:border-slate-800 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
<form method="POST" class="mt-4 p-4 rounded-xl bg-slate-50/70 dark:bg-slate-900/60 border border-slate-200/80 dark:border-slate-800 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||||
<input type="hidden" name="action" value="save_outlook_settings">
|
<input type="hidden" name="action" value="save_outlook_settings">
|
||||||
<div class="space-y-1">
|
<div class="space-y-1">
|
||||||
@@ -503,6 +508,9 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> dd738e670b78819c11e329da93db1b472808f195
|
||||||
<div class="mt-4 p-3.5 rounded-xl bg-teal-50 dark:bg-teal-500/10 border border-teal-200 dark:border-teal-500/20 text-teal-800 dark:text-teal-300 text-xs flex items-center justify-between">
|
<div class="mt-4 p-3.5 rounded-xl bg-teal-50 dark:bg-teal-500/10 border border-teal-200 dark:border-teal-500/20 text-teal-800 dark:text-teal-300 text-xs flex items-center justify-between">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<i data-lucide="check-circle" class="w-4 h-4 text-teal-600 dark:text-teal-400 flex-shrink-0"></i>
|
<i data-lucide="check-circle" class="w-4 h-4 text-teal-600 dark:text-teal-400 flex-shrink-0"></i>
|
||||||
@@ -553,7 +561,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sectie 2: Mijn Atlassian Jira Koppeling -->
|
<!-- Sectie 2: Mijn Atlassian Jira Koppeling -->
|
||||||
<div class="fociz-card p-6 sm:p-7">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-6 sm:p-7 shadow-xs transition">
|
||||||
<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 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="flex items-center space-x-3.5">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 flex items-center justify-center text-indigo-600 dark:text-indigo-400 font-bold shadow-xs">
|
<div class="w-12 h-12 rounded-2xl bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 flex items-center justify-center text-indigo-600 dark:text-indigo-400 font-bold shadow-xs">
|
||||||
@@ -642,7 +650,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sectie 3: Mijn Meldingen & Agenda Push Notificaties -->
|
<!-- Sectie 3: Mijn Meldingen & Agenda Push Notificaties -->
|
||||||
<div class="fociz-card p-6 sm:p-7">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-6 sm:p-7 shadow-xs transition">
|
||||||
<div class="flex items-center space-x-3.5 pb-6 border-b border-slate-100 dark:border-slate-800/80">
|
<div class="flex items-center space-x-3.5 pb-6 border-b border-slate-100 dark:border-slate-800/80">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 flex items-center justify-center text-indigo-600 dark:text-indigo-400 font-bold shadow-xs">
|
<div class="w-12 h-12 rounded-2xl bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-200 dark:border-indigo-500/20 flex items-center justify-center text-indigo-600 dark:text-indigo-400 font-bold shadow-xs">
|
||||||
<i data-lucide="bell" class="w-6 h-6"></i>
|
<i data-lucide="bell" class="w-6 h-6"></i>
|
||||||
@@ -790,7 +798,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<!-- Profielnaam formulier -->
|
<!-- Profielnaam formulier -->
|
||||||
<div class="fociz-card p-6 sm:p-7 space-y-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-6 sm:p-7 shadow-xs space-y-4 transition">
|
||||||
<div class="flex items-center space-x-3 pb-4 border-b border-slate-100 dark:border-slate-800/80">
|
<div class="flex items-center space-x-3 pb-4 border-b border-slate-100 dark:border-slate-800/80">
|
||||||
<i data-lucide="user" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="user" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<h3 class="text-sm font-bold text-slate-900 dark:text-white">Persoonlijke Gegevens</h3>
|
<h3 class="text-sm font-bold text-slate-900 dark:text-white">Persoonlijke Gegevens</h3>
|
||||||
@@ -803,14 +811,14 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1.5">
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1.5">
|
||||||
Weergavenaam
|
Weergavenaam
|
||||||
</label>
|
</label>
|
||||||
<input type="text" name="name" required value="<?= htmlspecialchars($userProfile['name']) ?>" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3.5 py-2.5 text-xs text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<input type="text" name="name" required value="<?= htmlspecialchars($userProfile['name']) ?>" class="w-full bg-white dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3.5 py-2.5 text-xs text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1.5">
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1.5">
|
||||||
E-mailadres
|
E-mailadres
|
||||||
</label>
|
</label>
|
||||||
<input type="email" readonly disabled value="<?= htmlspecialchars($userProfile['email']) ?>" class="w-full bg-slate-100/70 dark:bg-slate-900/40 border border-slate-200 dark:border-slate-800/60 rounded-xl px-3.5 py-2.5 text-xs text-slate-500 cursor-not-allowed shadow-2xs">
|
<input type="email" readonly disabled value="<?= htmlspecialchars($userProfile['email']) ?>" class="w-full bg-slate-100/70 dark:bg-slate-900/40 border border-slate-200 dark:border-slate-800/60 rounded-xl px-3.5 py-2.5 text-xs text-slate-500 cursor-not-allowed">
|
||||||
<span class="text-[10px] text-slate-500 mt-1 block">E-mailadres is gekoppeld aan uw account en 2FA.</span>
|
<span class="text-[10px] text-slate-500 mt-1 block">E-mailadres is gekoppeld aan uw account en 2FA.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -823,7 +831,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Wachtwoord Wijzigen Formulier -->
|
<!-- Wachtwoord Wijzigen Formulier -->
|
||||||
<div class="fociz-card p-6 sm:p-7 space-y-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-6 sm:p-7 shadow-xs space-y-4 transition">
|
||||||
<div class="flex items-center space-x-3 pb-4 border-b border-slate-100 dark:border-slate-800/80">
|
<div class="flex items-center space-x-3 pb-4 border-b border-slate-100 dark:border-slate-800/80">
|
||||||
<i data-lucide="key" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="key" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<h3 class="text-sm font-bold text-slate-900 dark:text-white">Wachtwoord Wijzigen</h3>
|
<h3 class="text-sm font-bold text-slate-900 dark:text-white">Wachtwoord Wijzigen</h3>
|
||||||
|
|||||||
+44
-51
@@ -37,35 +37,35 @@ $quarters = ['Q1', 'Q2', 'Q3', 'Q4'];
|
|||||||
|
|
||||||
<div class="space-y-6 max-w-7xl mx-auto">
|
<div class="space-y-6 max-w-7xl mx-auto">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="fociz-card p-6 sm:p-7 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4 bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-6 sm:p-7 shadow-xs transition">
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center space-x-2 text-indigo-600 dark:text-indigo-400 text-xs font-bold uppercase tracking-wider mb-1">
|
<div class="flex items-center space-x-2 text-indigo-600 dark:text-indigo-400 text-xs font-semibold uppercase tracking-wider mb-1">
|
||||||
<i data-lucide="map" class="w-4 h-4"></i>
|
<i data-lucide="map" class="w-4 h-4"></i>
|
||||||
<span>Planning & Strategie</span>
|
<span>Planning & Strategie</span>
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-2xl sm:text-3xl font-black text-slate-900 dark:text-white tracking-tight">
|
<h1 class="text-2xl sm:text-3xl font-bold text-slate-900 dark:text-white tracking-tight">
|
||||||
Roadmap & Tijdlijn
|
Roadmap & Tijdlijn
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-slate-500 dark:text-slate-400 text-xs sm:text-sm mt-1 max-w-2xl">
|
<p class="text-slate-500 dark:text-slate-400 text-xs sm:text-sm mt-1">
|
||||||
Centraal overzicht van alle mijlpalen, features en doelen, direct voortgekomen uit brainstorms en gesynchroniseerd met Jira.
|
Centraal overzicht van alle mijlpalen, features en doelen, direct voortgekomen uit brainstorms en gesynchroniseerd met Jira.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onclick="document.getElementById('newItemModal').classList.remove('hidden')" class="flex items-center space-x-2 px-4 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-bold transition shadow-xs flex-shrink-0 cursor-pointer">
|
<button onclick="document.getElementById('newItemModal').classList.remove('hidden')" class="flex items-center space-x-2 px-4 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-semibold transition shadow-xs flex-shrink-0 cursor-pointer">
|
||||||
<i data-lucide="plus" class="w-4 h-4"></i>
|
<i data-lucide="plus" class="w-4 h-4"></i>
|
||||||
<span>Nieuw Item</span>
|
<span>Nieuw Item</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Filters: Quarters & Status -->
|
<!-- Filters: Quarters & Status -->
|
||||||
<div class="fociz-card p-4 flex flex-wrap items-center justify-between gap-3">
|
<div class="flex flex-wrap items-center justify-between gap-3 bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-4 shadow-xs transition">
|
||||||
<!-- Quarter Tabs -->
|
<!-- Quarter Tabs -->
|
||||||
<div class="flex items-center space-x-1 text-xs">
|
<div class="flex items-center space-x-1 text-xs">
|
||||||
<a href="/roadmap.php?quarter=ALL&status=<?= htmlspecialchars($selectedStatus) ?>" class="px-3 py-1.5 rounded-lg transition font-semibold <?= $selectedQuarter === 'ALL' ? 'bg-indigo-600 text-white shadow-xs' : 'text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-200 hover:bg-slate-100 dark:hover:bg-slate-800/80' ?>">
|
<a href="/roadmap.php?quarter=ALL&status=<?= htmlspecialchars($selectedStatus) ?>" class="px-3 py-1.5 rounded-lg transition font-medium <?= $selectedQuarter === 'ALL' ? 'bg-indigo-600 text-white shadow-xs' : 'text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-200 hover:bg-slate-100 dark:hover:bg-slate-800' ?>">
|
||||||
Alle Quarters
|
Alle Quarters
|
||||||
</a>
|
</a>
|
||||||
<?php foreach ($quarters as $q): ?>
|
<?php foreach ($quarters as $q): ?>
|
||||||
<a href="/roadmap.php?quarter=<?= $q ?>&status=<?= htmlspecialchars($selectedStatus) ?>" class="px-3 py-1.5 rounded-lg transition font-semibold <?= $selectedQuarter === $q ? 'bg-indigo-600 text-white shadow-xs' : 'text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-200 hover:bg-slate-100 dark:hover:bg-slate-800/80' ?>">
|
<a href="/roadmap.php?quarter=<?= $q ?>&status=<?= htmlspecialchars($selectedStatus) ?>" class="px-3 py-1.5 rounded-lg transition font-medium <?= $selectedQuarter === $q ? 'bg-indigo-600 text-white shadow-xs' : 'text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-200 hover:bg-slate-100 dark:hover:bg-slate-800' ?>">
|
||||||
<?= $q ?>
|
<?= $q ?>
|
||||||
</a>
|
</a>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
@@ -73,8 +73,8 @@ $quarters = ['Q1', 'Q2', 'Q3', 'Q4'];
|
|||||||
|
|
||||||
<!-- Status Filter -->
|
<!-- Status Filter -->
|
||||||
<div class="flex items-center space-x-2 text-xs">
|
<div class="flex items-center space-x-2 text-xs">
|
||||||
<span class="text-slate-500 dark:text-slate-400 font-semibold">Status:</span>
|
<span class="text-slate-500 dark:text-slate-400 font-medium">Status:</span>
|
||||||
<select onchange="window.location.href='/roadmap.php?quarter=<?= htmlspecialchars($selectedQuarter) ?>&status='+this.value" class="bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-1.5 text-slate-900 dark:text-white text-xs font-semibold focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select onchange="window.location.href='/roadmap.php?quarter=<?= htmlspecialchars($selectedQuarter) ?>&status='+this.value" class="bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-2.5 py-1 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="ALL" <?= $selectedStatus === 'ALL' ? 'selected' : '' ?>>Alle Statussen</option>
|
<option value="ALL" <?= $selectedStatus === 'ALL' ? 'selected' : '' ?>>Alle Statussen</option>
|
||||||
<option value="PLANNED" <?= $selectedStatus === 'PLANNED' ? 'selected' : '' ?>>Gepland</option>
|
<option value="PLANNED" <?= $selectedStatus === 'PLANNED' ? 'selected' : '' ?>>Gepland</option>
|
||||||
<option value="IN_PROGRESS" <?= $selectedStatus === 'IN_PROGRESS' ? 'selected' : '' ?>>In Uitvoering</option>
|
<option value="IN_PROGRESS" <?= $selectedStatus === 'IN_PROGRESS' ? 'selected' : '' ?>>In Uitvoering</option>
|
||||||
@@ -87,34 +87,27 @@ $quarters = ['Q1', 'Q2', 'Q3', 'Q4'];
|
|||||||
<!-- Roadmap Items Lijst -->
|
<!-- Roadmap Items Lijst -->
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<?php if (empty($roadmapItems)): ?>
|
<?php if (empty($roadmapItems)): ?>
|
||||||
<div class="fociz-card p-12 text-center">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 rounded-2xl p-12 text-center shadow-xs">
|
||||||
<i data-lucide="map-pin" class="w-12 h-12 text-slate-300 dark:text-slate-700 mx-auto mb-3"></i>
|
<i data-lucide="map-pin" class="w-12 h-12 text-slate-300 dark:text-slate-700 mx-auto mb-3"></i>
|
||||||
<h3 class="text-base font-bold text-slate-900 dark:text-white">Geen items gevonden op de roadmap</h3>
|
<h3 class="text-base font-semibold text-slate-900 dark:text-white">Geen items gevonden op de roadmap</h3>
|
||||||
<p class="text-xs text-slate-500 dark:text-slate-400 mt-1 max-w-sm mx-auto">
|
<p class="text-xs text-slate-500 dark:text-slate-400 mt-1 max-w-sm mx-auto">
|
||||||
Ga naar een <a href="/brainstorm.php" class="text-indigo-600 dark:text-indigo-400 underline font-medium">Brainstorm sessie</a> en zet ideeën met één klik om naar de roadmap, of voeg handmatig een item toe.
|
Ga naar een <a href="/brainstorm.php" class="text-indigo-600 dark:text-indigo-400 underline font-medium">Brainstorm sessie</a> en zet ideeën met één klik om naar de roadmap, of voeg handmatig een item toe.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($roadmapItems as $item):
|
<?php foreach ($roadmapItems as $item): ?>
|
||||||
$statusBorder = match($item['status']) {
|
<div class="bg-white dark:bg-[#111622] border border-slate-200/80 dark:border-slate-800 hover:border-indigo-300 dark:hover:border-indigo-700/60 rounded-2xl p-5 shadow-xs transition space-y-3" id="roadmap-item-<?= $item['id'] ?>">
|
||||||
'COMPLETED' => 'border-l-4 border-l-emerald-500',
|
|
||||||
'IN_PROGRESS' => 'border-l-4 border-l-indigo-500',
|
|
||||||
'REVIEW' => 'border-l-4 border-l-amber-500',
|
|
||||||
default => 'border-l-4 border-l-slate-300 dark:border-l-slate-700',
|
|
||||||
};
|
|
||||||
?>
|
|
||||||
<div class="fociz-card-interactive p-5 space-y-3.5 <?= $statusBorder ?>" id="roadmap-item-<?= $item['id'] ?>">
|
|
||||||
|
|
||||||
<!-- Top header van item -->
|
<!-- Top header van item -->
|
||||||
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-2">
|
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-2">
|
||||||
<div class="flex items-center space-x-2.5 flex-wrap">
|
<div class="flex items-center space-x-2.5 flex-wrap">
|
||||||
<!-- Quarter badge -->
|
<!-- Quarter badge -->
|
||||||
<span class="px-2.5 py-0.5 rounded-lg bg-indigo-50 dark:bg-indigo-500/10 text-indigo-700 dark:text-indigo-300 font-mono text-xs font-bold border border-indigo-200 dark:border-indigo-500/20">
|
<span class="px-2.5 py-0.5 rounded-md bg-indigo-50 dark:bg-indigo-500/10 text-indigo-700 dark:text-indigo-300 font-mono text-xs font-semibold border border-indigo-200 dark:border-indigo-500/20">
|
||||||
<?= htmlspecialchars($item['quarter']) ?>
|
<?= htmlspecialchars($item['quarter']) ?>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<!-- Type badge -->
|
<!-- Type badge -->
|
||||||
<span class="px-2 py-0.5 rounded-lg bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 text-[10px] font-semibold border border-slate-200 dark:border-slate-700">
|
<span class="px-2 py-0.5 rounded-md bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 text-[10px] font-semibold">
|
||||||
<?= htmlspecialchars($item['type']) ?>
|
<?= htmlspecialchars($item['type']) ?>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@@ -125,7 +118,7 @@ $quarters = ['Q1', 'Q2', 'Q3', 'Q4'];
|
|||||||
|
|
||||||
<!-- Jira Issue Key link -->
|
<!-- Jira Issue Key link -->
|
||||||
<?php if (!empty($item['jira_issue_key'])): ?>
|
<?php if (!empty($item['jira_issue_key'])): ?>
|
||||||
<a href="/profile.php" class="flex items-center space-x-1 px-2.5 py-0.5 rounded-lg bg-sky-50 dark:bg-sky-500/10 border border-sky-200 dark:border-sky-500/20 text-sky-700 dark:text-sky-400 text-[10px] font-mono hover:underline">
|
<a href="/profile.php" class="flex items-center space-x-1 px-2 py-0.5 rounded-md bg-sky-50 dark:bg-sky-500/10 border border-sky-200 dark:border-sky-500/20 text-sky-700 dark:text-sky-400 text-[10px] font-mono hover:underline">
|
||||||
<i data-lucide="layers" class="w-3 h-3"></i>
|
<i data-lucide="layers" class="w-3 h-3"></i>
|
||||||
<span><?= htmlspecialchars($item['jira_issue_key']) ?></span>
|
<span><?= htmlspecialchars($item['jira_issue_key']) ?></span>
|
||||||
</a>
|
</a>
|
||||||
@@ -134,7 +127,7 @@ $quarters = ['Q1', 'Q2', 'Q3', 'Q4'];
|
|||||||
|
|
||||||
<!-- Status Selector -->
|
<!-- Status Selector -->
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<select onchange="updateRoadmapStatus(<?= $item['id'] ?>, this.value)" class="bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-200 dark:border-slate-800 rounded-xl px-2.5 py-1 text-xs text-slate-800 dark:text-slate-200 font-bold focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select onchange="updateRoadmapStatus(<?= $item['id'] ?>, this.value)" class="bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-2.5 py-1 text-xs text-slate-800 dark:text-slate-200 font-semibold focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="PLANNED" <?= $item['status'] === 'PLANNED' ? 'selected' : '' ?>>⏳ Gepland</option>
|
<option value="PLANNED" <?= $item['status'] === 'PLANNED' ? 'selected' : '' ?>>⏳ Gepland</option>
|
||||||
<option value="IN_PROGRESS" <?= $item['status'] === 'IN_PROGRESS' ? 'selected' : '' ?>>⚡ In Uitvoering</option>
|
<option value="IN_PROGRESS" <?= $item['status'] === 'IN_PROGRESS' ? 'selected' : '' ?>>⚡ In Uitvoering</option>
|
||||||
<option value="REVIEW" <?= $item['status'] === 'REVIEW' ? 'selected' : '' ?>>🔍 In Review</option>
|
<option value="REVIEW" <?= $item['status'] === 'REVIEW' ? 'selected' : '' ?>>🔍 In Review</option>
|
||||||
@@ -161,32 +154,32 @@ $quarters = ['Q1', 'Q2', 'Q3', 'Q4'];
|
|||||||
|
|
||||||
<!-- Origin Brainstorm snippet -->
|
<!-- Origin Brainstorm snippet -->
|
||||||
<?php if (!empty($item['origin_brainstorm_card_id'])): ?>
|
<?php if (!empty($item['origin_brainstorm_card_id'])): ?>
|
||||||
<div class="bg-slate-50/70 dark:bg-[#0c0f17]/60 rounded-xl p-2.5 text-[11px] text-slate-600 dark:text-slate-400 flex items-center space-x-2 border border-slate-200/80 dark:border-slate-800">
|
<div class="bg-slate-50 dark:bg-slate-900/60 rounded-xl p-2.5 text-[11px] text-slate-500 dark:text-slate-400 flex items-center space-x-2 border border-slate-200/80 dark:border-slate-800">
|
||||||
<i data-lucide="lightbulb" class="w-3.5 h-3.5 text-amber-500 flex-shrink-0"></i>
|
<i data-lucide="lightbulb" class="w-3.5 h-3.5 text-amber-500 flex-shrink-0"></i>
|
||||||
<span class="truncate">Ontstaan uit brainstormsessie</span>
|
<span class="truncate">Ontstaan uit brainstormsessie</span>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<!-- Voortgangsbalk & Deadline -->
|
<!-- Voortgangsbalk & Deadline -->
|
||||||
<div class="pt-2.5 border-t border-slate-100 dark:border-slate-800/60 flex flex-col sm:flex-row sm:items-center justify-between gap-3 text-xs">
|
<div class="pt-2 border-t border-slate-100 dark:border-slate-800/60 flex flex-col sm:flex-row sm:items-center justify-between gap-3 text-xs">
|
||||||
<!-- Progress Slider -->
|
<!-- Progress Slider -->
|
||||||
<div class="flex items-center space-x-3 flex-1 max-w-md">
|
<div class="flex items-center space-x-3 flex-1 max-w-md">
|
||||||
<span class="text-slate-500 dark:text-slate-400 text-[11px] font-semibold w-16">Voortgang:</span>
|
<span class="text-slate-500 dark:text-slate-400 text-[11px] font-medium w-16">Voortgang:</span>
|
||||||
<div class="flex-1 bg-slate-100 dark:bg-slate-900 h-2.5 rounded-full overflow-hidden border border-slate-200 dark:border-slate-800">
|
<div class="flex-1 bg-slate-100 dark:bg-slate-900 h-2 rounded-full overflow-hidden border border-slate-200 dark:border-slate-800">
|
||||||
<div class="bg-gradient-to-r from-indigo-600 to-sky-500 h-full transition-all" style="width: <?= $item['progress'] ?>%"></div>
|
<div class="bg-gradient-to-r from-indigo-600 to-sky-500 h-full transition-all" style="width: <?= $item['progress'] ?>%"></div>
|
||||||
</div>
|
</div>
|
||||||
<span class="font-mono text-slate-800 dark:text-slate-200 font-bold w-10 text-right"><?= $item['progress'] ?>%</span>
|
<span class="font-mono text-slate-800 dark:text-slate-200 font-semibold w-10 text-right"><?= $item['progress'] ?>%</span>
|
||||||
<div class="flex space-x-1">
|
<div class="flex space-x-1">
|
||||||
<button onclick="updateRoadmapProgress(<?= $item['id'] ?>, 25)" class="px-2 py-0.5 rounded-lg bg-slate-100 dark:bg-slate-800 text-[10px] text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white cursor-pointer font-semibold transition">25%</button>
|
<button onclick="updateRoadmapProgress(<?= $item['id'] ?>, 25)" class="px-1.5 py-0.5 rounded bg-slate-100 dark:bg-slate-800 text-[10px] text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white cursor-pointer">25%</button>
|
||||||
<button onclick="updateRoadmapProgress(<?= $item['id'] ?>, 50)" class="px-2 py-0.5 rounded-lg bg-slate-100 dark:bg-slate-800 text-[10px] text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white cursor-pointer font-semibold transition">50%</button>
|
<button onclick="updateRoadmapProgress(<?= $item['id'] ?>, 50)" class="px-1.5 py-0.5 rounded bg-slate-100 dark:bg-slate-800 text-[10px] text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white cursor-pointer">50%</button>
|
||||||
<button onclick="updateRoadmapProgress(<?= $item['id'] ?>, 100)" class="px-2 py-0.5 rounded-lg bg-indigo-50 dark:bg-indigo-500/15 text-[10px] text-indigo-700 dark:text-indigo-400 hover:text-indigo-800 dark:hover:text-indigo-300 font-bold cursor-pointer transition">100%</button>
|
<button onclick="updateRoadmapProgress(<?= $item['id'] ?>, 100)" class="px-1.5 py-0.5 rounded bg-indigo-50 dark:bg-indigo-500/15 text-[10px] text-indigo-700 dark:text-indigo-400 hover:text-indigo-800 dark:hover:text-indigo-300 font-semibold cursor-pointer">100%</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Deadline & Creator -->
|
<!-- Deadline & Creator -->
|
||||||
<div class="flex items-center space-x-3 text-slate-500 text-[11px]">
|
<div class="flex items-center space-x-3 text-slate-500 text-[11px]">
|
||||||
<?php if (!empty($item['due_date'])): ?>
|
<?php if (!empty($item['due_date'])): ?>
|
||||||
<span class="flex items-center space-x-1 text-slate-700 dark:text-slate-300 font-semibold">
|
<span class="flex items-center space-x-1 text-slate-700 dark:text-slate-300 font-medium">
|
||||||
<i data-lucide="calendar" class="w-3.5 h-3.5 text-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="calendar" class="w-3.5 h-3.5 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<span>Deadline: <?= date('d-m-Y', strtotime($item['due_date'])) ?></span>
|
<span>Deadline: <?= date('d-m-Y', strtotime($item['due_date'])) ?></span>
|
||||||
</span>
|
</span>
|
||||||
@@ -201,33 +194,33 @@ $quarters = ['Q1', 'Q2', 'Q3', 'Q4'];
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Modal: Nieuw Roadmap Item Handmatig Toevoegen -->
|
<!-- Modal: Nieuw Roadmap Item Handmatig Toevoegen -->
|
||||||
<div id="newItemModal" class="hidden fixed inset-0 z-50 bg-slate-950/70 backdrop-blur-sm flex items-center justify-center p-4">
|
<div id="newItemModal" class="hidden fixed inset-0 z-50 bg-slate-950/60 backdrop-blur-xs flex items-center justify-center p-4">
|
||||||
<div class="fociz-card p-6 sm:p-7 shadow-2xl max-w-lg w-full space-y-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800 rounded-2xl p-6 shadow-xl max-w-lg w-full transition">
|
||||||
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800">
|
<div class="flex items-center justify-between mb-4 pb-3 border-b border-slate-100 dark:border-slate-800">
|
||||||
<h3 class="text-sm font-bold text-slate-900 dark:text-white flex items-center space-x-2">
|
<h3 class="text-sm font-semibold text-slate-900 dark:text-white flex items-center space-x-2">
|
||||||
<i data-lucide="map" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="map" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<span>Nieuw Roadmap Item Toevoegen</span>
|
<span>Nieuw Roadmap Item Toevoegen</span>
|
||||||
</h3>
|
</h3>
|
||||||
<button onclick="document.getElementById('newItemModal').classList.add('hidden')" class="p-1.5 text-slate-400 hover:text-slate-600 dark:hover:text-white rounded-lg hover:bg-slate-100 dark:hover:bg-slate-800 transition cursor-pointer">
|
<button onclick="document.getElementById('newItemModal').classList.add('hidden')" class="text-slate-400 hover:text-slate-600 dark:hover:text-white cursor-pointer">
|
||||||
<i data-lucide="x" class="w-4 h-4"></i>
|
<i data-lucide="x" class="w-5 h-5"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Titel / Doel</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Titel / Doel</label>
|
||||||
<input type="text" id="manualTitle" placeholder="Bijv. 2FA Authenticatie afronden" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3.5 py-2 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<input type="text" id="manualTitle" placeholder="Bijv. 2FA Authenticatie afronden" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3.5 py-2 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Beschrijving / Specificatie</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Beschrijving / Specificatie</label>
|
||||||
<textarea id="manualDescription" rows="3" placeholder="Wat houdt deze milestone of feature in?" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl p-3 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 resize-none shadow-2xs"></textarea>
|
<textarea id="manualDescription" rows="3" placeholder="Wat houdt deze milestone of feature in?" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl p-3 text-slate-900 dark:text-white text-xs placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 resize-none"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-2 gap-3">
|
<div class="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Kwartaal</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Kwartaal</label>
|
||||||
<select id="manualQuarter" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select id="manualQuarter" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="Q1">Q1</option>
|
<option value="Q1">Q1</option>
|
||||||
<option value="Q2">Q2</option>
|
<option value="Q2">Q2</option>
|
||||||
<option value="Q3" selected>Q3</option>
|
<option value="Q3" selected>Q3</option>
|
||||||
@@ -236,7 +229,7 @@ $quarters = ['Q1', 'Q2', 'Q3', 'Q4'];
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Type</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Type</label>
|
||||||
<select id="manualType" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select id="manualType" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="FEATURE" selected>Feature</option>
|
<option value="FEATURE" selected>Feature</option>
|
||||||
<option value="EPIC">Epic</option>
|
<option value="EPIC">Epic</option>
|
||||||
<option value="MILESTONE">Mijlpaal</option>
|
<option value="MILESTONE">Mijlpaal</option>
|
||||||
@@ -248,7 +241,7 @@ $quarters = ['Q1', 'Q2', 'Q3', 'Q4'];
|
|||||||
<div class="grid grid-cols-2 gap-3">
|
<div class="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Prioriteit</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Prioriteit</label>
|
||||||
<select id="manualPriority" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select id="manualPriority" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="CRITICAL">Kritiek</option>
|
<option value="CRITICAL">Kritiek</option>
|
||||||
<option value="HIGH" selected>Hoog</option>
|
<option value="HIGH" selected>Hoog</option>
|
||||||
<option value="MEDIUM">Normaal</option>
|
<option value="MEDIUM">Normaal</option>
|
||||||
@@ -257,23 +250,23 @@ $quarters = ['Q1', 'Q2', 'Q3', 'Q4'];
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Jira Issue Key (optioneel)</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Jira Issue Key (optioneel)</label>
|
||||||
<input type="text" id="manualJiraKey" placeholder="Bijv. FOC-101" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-1.5 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<input type="text" id="manualJiraKey" placeholder="Bijv. FOC-101" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-1.5 text-slate-900 dark:text-white text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Streefdatum</label>
|
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Streefdatum</label>
|
||||||
<input type="date" id="manualDueDate" class="w-full bg-slate-50/70 dark:bg-[#0c0f17]/60 border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-1.5 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<input type="date" id="manualDueDate" class="w-full bg-slate-50 dark:bg-slate-900/60 border border-slate-200 dark:border-slate-800 rounded-xl px-3 py-1.5 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex space-x-2 pt-2 border-t border-slate-100 dark:border-slate-800/80">
|
<div class="flex space-x-2 pt-2">
|
||||||
<button onclick="submitManualItem()" class="flex-1 bg-indigo-600 hover:bg-indigo-500 text-white font-bold py-2.5 px-4 rounded-xl text-xs transition cursor-pointer shadow-xs">
|
<button onclick="submitManualItem()" class="flex-1 bg-indigo-600 hover:bg-indigo-500 text-white font-semibold py-2.5 px-4 rounded-xl text-xs transition cursor-pointer shadow-xs">
|
||||||
Toevoegen aan Roadmap
|
Toevoegen aan Roadmap
|
||||||
</button>
|
</button>
|
||||||
<button onclick="document.getElementById('newItemModal').classList.add('hidden')" class="px-4 py-2.5 bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl text-xs font-semibold transition cursor-pointer">
|
<button onclick="document.getElementById('newItemModal').classList.add('hidden')" class="px-4 py-2.5 bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl text-xs transition cursor-pointer">
|
||||||
Annuleren
|
Annuleren
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
|
|
||||||
<div class="space-y-6 max-w-7xl mx-auto pb-12">
|
<div class="space-y-6 max-w-7xl mx-auto pb-12">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="fociz-card p-6 sm:p-7">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-6 sm:p-7 shadow-xs transition">
|
||||||
<div class="flex items-center space-x-2 text-indigo-600 dark:text-indigo-400 text-xs font-bold uppercase tracking-wider mb-1">
|
<div class="flex items-center space-x-2 text-indigo-600 dark:text-indigo-400 text-xs font-bold uppercase tracking-wider mb-1">
|
||||||
<i data-lucide="shield" class="w-4 h-4"></i>
|
<i data-lucide="shield" class="w-4 h-4"></i>
|
||||||
<span>Beheerderspaneel</span>
|
<span>Beheerderspaneel</span>
|
||||||
@@ -79,7 +79,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
<h1 class="text-2xl sm:text-3xl font-black text-slate-900 dark:text-white tracking-tight">
|
<h1 class="text-2xl sm:text-3xl font-black text-slate-900 dark:text-white tracking-tight">
|
||||||
Team & Uitnodigingen
|
Team & Uitnodigingen
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-slate-500 dark:text-slate-400 text-xs sm:text-sm mt-1 max-w-2xl">
|
<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.
|
Fociz is strikt afgesloten: nieuwe collega's kunnen enkel toegang krijgen na het ontvangen van een uitnodigingslink en verplichte 2FA-activatie.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -111,7 +111,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<!-- Uitnodiging Genereren Kaart -->
|
<!-- Uitnodiging Genereren Kaart -->
|
||||||
<div class="fociz-card p-6 sm:p-7">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-6 sm:p-7 shadow-xs transition">
|
||||||
<h3 class="text-base font-bold text-slate-900 dark:text-white mb-4 flex items-center space-x-2">
|
<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-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="user-plus" class="w-5 h-5 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
<span>Nieuwe Collega Uitnodigen</span>
|
<span>Nieuwe Collega Uitnodigen</span>
|
||||||
@@ -122,12 +122,12 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
|
|
||||||
<div class="md:col-span-6">
|
<div class="md:col-span-6">
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">E-mailadres van collega</label>
|
<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/70 dark:bg-[#0c0f17]/60 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-indigo-500 text-xs shadow-2xs">
|
<input type="email" name="email" required placeholder="collega@bedrijf.nl" class="w-full bg-slate-50 dark:bg-[#0c0f17] 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-indigo-500 text-xs">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="md:col-span-3">
|
<div class="md:col-span-3">
|
||||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Rol</label>
|
<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/70 dark:bg-[#0c0f17]/60 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 focus:ring-1 focus:ring-indigo-500 shadow-2xs">
|
<select name="role" class="w-full bg-slate-50 dark:bg-[#0c0f17] 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 focus:ring-1 focus:ring-indigo-500">
|
||||||
<option value="MEMBER">Collega (Standaard)</option>
|
<option value="MEMBER">Collega (Standaard)</option>
|
||||||
<option value="ADMIN">Mede-beheerder</option>
|
<option value="ADMIN">Mede-beheerder</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -143,7 +143,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Actieve Gebruikers Tabel -->
|
<!-- Actieve Gebruikers Tabel -->
|
||||||
<div class="fociz-card p-6 sm:p-7 space-y-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-6 sm:p-7 shadow-xs space-y-4 transition">
|
||||||
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800">
|
<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">
|
<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-indigo-600 dark:text-indigo-400"></i>
|
<i data-lucide="users" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||||
@@ -200,7 +200,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Uitstaande Uitnodigingen Tabel -->
|
<!-- Uitstaande Uitnodigingen Tabel -->
|
||||||
<div class="fociz-card p-6 sm:p-7 space-y-4">
|
<div class="bg-white dark:bg-[#111622] border border-slate-200 dark:border-slate-800/80 rounded-2xl p-6 sm:p-7 shadow-xs space-y-4 transition">
|
||||||
<div class="flex items-center justify-between pb-3 border-b border-slate-100 dark:border-slate-800">
|
<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">
|
<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>
|
<i data-lucide="mail" class="w-4 h-4 text-amber-500"></i>
|
||||||
|
|||||||
Reference in New Issue
Block a user