Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 845216e554 | |||
| 797aaa76c7 |
@@ -296,6 +296,71 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$activeTab = 'calendar';
|
||||
}
|
||||
|
||||
// 3c. Brainstorm Categorieën opslaan
|
||||
elseif ($action === 'save_brainstorm_categories') {
|
||||
$rawCategories = $_POST['categories'] ?? [];
|
||||
$sanitizedCategories = [];
|
||||
if (is_array($rawCategories)) {
|
||||
foreach ($rawCategories as $c) {
|
||||
$name = trim((string)($c['name'] ?? ''));
|
||||
$desc = trim((string)($c['description'] ?? ''));
|
||||
$isActive = isset($c['is_active']) && ($c['is_active'] == '1' || $c['is_active'] === 'on') ? 1 : 0;
|
||||
$isDelete = isset($c['is_delete']) && ($c['is_delete'] == '1' || $c['is_delete'] === 'on');
|
||||
|
||||
if ($isDelete || empty($name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sanitizedCategories[] = [
|
||||
'name' => $name,
|
||||
'description' => $desc,
|
||||
'is_active' => $isActive,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Nieuwe categorie toevoegen indien ingevuld
|
||||
$newName = trim((string)($_POST['new_category_name'] ?? ''));
|
||||
$newDesc = trim((string)($_POST['new_category_desc'] ?? ''));
|
||||
if (!empty($newName)) {
|
||||
$exists = false;
|
||||
foreach ($sanitizedCategories as &$sc) {
|
||||
if (strcasecmp($sc['name'], $newName) === 0) {
|
||||
$sc['name'] = $newName;
|
||||
if (!empty($newDesc)) $sc['description'] = $newDesc;
|
||||
$sc['is_active'] = 1;
|
||||
$exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
unset($sc);
|
||||
if (!$exists) {
|
||||
$sanitizedCategories[] = [
|
||||
'name' => $newName,
|
||||
'description' => $newDesc,
|
||||
'is_active' => 1,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($sanitizedCategories)) {
|
||||
$sanitizedCategories = [
|
||||
['name' => 'Product & Strategie', 'description' => 'Strategische richting, nieuwe producten en visie', 'is_active' => 1],
|
||||
['name' => 'Procesverbetering', 'description' => 'Optimalisatie van werkprocessen en efficiëntie', 'is_active' => 1],
|
||||
['name' => 'Klant & Service', 'description' => 'Klanttevredenheid, support en klantervaring', 'is_active' => 1],
|
||||
['name' => 'Technologie & IT', 'description' => 'Architectuur, tooling, infrastructuur en tech stack','is_active' => 1],
|
||||
['name' => 'Marketing & Groei', 'description' => 'Leadgeneratie, branding en marktpositie', 'is_active' => 1],
|
||||
];
|
||||
}
|
||||
|
||||
set_system_setting('brainstorm_categories', $sanitizedCategories);
|
||||
fociz_log_audit($userId, 'SETTINGS_UPDATED', 'brainstorm_categories', null, ['count' => count($sanitizedCategories)], 'SUCCESS', $adminUser['email']);
|
||||
|
||||
$message = "Brainstorm categorieën zijn succesvol opgeslagen.";
|
||||
$messageType = 'success';
|
||||
$activeTab = 'system';
|
||||
}
|
||||
|
||||
// 4. AI Co-Pilot instellingen opslaan (Release v1.5)
|
||||
elseif ($action === 'save_ai_settings') {
|
||||
$activeTab = 'ai';
|
||||
@@ -375,6 +440,7 @@ $workdaySettings = get_workday_settings();
|
||||
$aiSettings = get_ai_settings();
|
||||
$sessionIdleTimeout = get_session_idle_timeout();
|
||||
$calendarBlockReasons = get_calendar_block_reasons();
|
||||
$brainstormCategories = get_brainstorm_categories();
|
||||
|
||||
// Redirect URI
|
||||
$redirectUri = rtrim(APP_URL, '/') . '/auth/callback_microsoft.php';
|
||||
@@ -1925,6 +1991,87 @@ require_once __DIR__ . '/includes/header.php';
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Brainstorm Categorieën Beheer Card -->
|
||||
<div class="fociz-card p-6 sm:p-7 space-y-6">
|
||||
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4 pb-5 border-b border-slate-100 dark:border-slate-800/80">
|
||||
<div class="flex items-center space-x-3.5">
|
||||
<div class="w-12 h-12 rounded-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="lightbulb" class="w-6 h-6"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<h2 class="text-lg font-bold text-slate-900 dark:text-white tracking-tight">Brainstorm Categorieën</h2>
|
||||
<span class="px-2.5 py-0.5 rounded-full bg-indigo-50 dark:bg-indigo-950/40 border border-indigo-200 dark:border-indigo-800/60 text-indigo-700 dark:text-indigo-300 text-[10px] font-bold">
|
||||
Beheerbaar
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-xs text-slate-500 dark:text-slate-400">Beheer de beschikbare categorieën voor nieuwe brainstormsessies</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" class="space-y-5">
|
||||
<input type="hidden" name="action" value="save_brainstorm_categories">
|
||||
<input type="hidden" name="active_tab" value="system">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars(get_csrf_token()) ?>">
|
||||
|
||||
<div class="space-y-2">
|
||||
<div class="grid grid-cols-12 gap-3 px-3 py-1.5 text-[10px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-wider border-b border-slate-100 dark:border-slate-800">
|
||||
<div class="col-span-5 sm:col-span-4">Categorienaam</div>
|
||||
<div class="col-span-5 sm:col-span-6">Omschrijving / Toelichting</div>
|
||||
<div class="col-span-1 text-center">Actief</div>
|
||||
<div class="col-span-1 text-right">Verwijder</div>
|
||||
</div>
|
||||
|
||||
<?php foreach ($brainstormCategories as $bIdx => $bCat): ?>
|
||||
<div class="grid grid-cols-12 gap-3 items-center p-3 rounded-2xl bg-slate-50/70 dark:bg-[#0c0f17] border border-slate-200/70 dark:border-slate-800/70 hover:border-slate-300 dark:hover:border-slate-700 transition">
|
||||
<div class="col-span-5 sm:col-span-4">
|
||||
<input type="text" name="categories[<?= $bIdx ?>][name]" value="<?= htmlspecialchars($bCat['name']) ?>" class="w-full px-3 py-1.5 rounded-xl bg-white dark:bg-[#111624] border border-slate-300 dark:border-slate-700 text-xs font-semibold text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500" required>
|
||||
</div>
|
||||
<div class="col-span-5 sm:col-span-6">
|
||||
<input type="text" name="categories[<?= $bIdx ?>][description]" value="<?= htmlspecialchars($bCat['description'] ?? '') ?>" placeholder="Optionele beschrijving..." class="w-full px-3 py-1.5 rounded-xl bg-white dark:bg-[#111624] border border-slate-300 dark:border-slate-700 text-xs font-medium text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||
</div>
|
||||
<div class="col-span-1 text-center">
|
||||
<label class="relative inline-flex items-center cursor-pointer">
|
||||
<input type="checkbox" name="categories[<?= $bIdx ?>][is_active]" value="1" <?= !empty($bCat['is_active']) ? 'checked' : '' ?> class="w-4 h-4 text-indigo-600 rounded border-slate-300 dark:border-slate-700 focus:ring-indigo-500">
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-span-1 text-right">
|
||||
<label class="cursor-pointer text-slate-400 hover:text-rose-600 dark:hover:text-rose-400 transition" title="Vink aan om deze categorie te verwijderen">
|
||||
<input type="checkbox" name="categories[<?= $bIdx ?>][is_delete]" value="1" class="w-4 h-4 text-rose-600 rounded border-slate-300 dark:border-slate-700 focus:ring-rose-500">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<!-- Nieuwe categorie toevoegen regel -->
|
||||
<div class="p-4 rounded-2xl bg-indigo-50/40 dark:bg-indigo-950/20 border border-dashed border-indigo-300/80 dark:border-indigo-800/60 space-y-3">
|
||||
<div class="flex items-center space-x-2 text-xs font-bold text-indigo-900 dark:text-indigo-200">
|
||||
<i data-lucide="plus-circle" class="w-4 h-4 text-indigo-600 dark:text-indigo-400"></i>
|
||||
<span>Nieuwe Categorie Toevoegen</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-12 gap-3 items-center">
|
||||
<div class="sm:col-span-5">
|
||||
<label class="block text-[10px] font-bold text-slate-500 dark:text-slate-400 mb-1">Categorienaam</label>
|
||||
<input type="text" name="new_category_name" placeholder="Bijv. Duurzaamheid & MVO" class="w-full px-3 py-1.5 rounded-xl bg-white dark:bg-[#111624] border border-slate-300 dark:border-slate-700 text-xs font-semibold text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||
</div>
|
||||
<div class="sm:col-span-7">
|
||||
<label class="block text-[10px] font-bold text-slate-500 dark:text-slate-400 mb-1">Omschrijving</label>
|
||||
<input type="text" name="new_category_desc" placeholder="Doel of richting van deze categorie..." class="w-full px-3 py-1.5 rounded-xl bg-white dark:bg-[#111624] border border-slate-300 dark:border-slate-700 text-xs font-medium text-slate-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end pt-2">
|
||||
<button type="submit" class="px-5 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-bold transition shadow-xs cursor-pointer flex items-center space-x-1.5">
|
||||
<i data-lucide="check" class="w-4 h-4"></i>
|
||||
<span>Brainstorm Categorieën Opslaan</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1047,6 +1047,71 @@ try {
|
||||
exit;
|
||||
}
|
||||
|
||||
// 15. Outlook Agenda-afspraak verwijderen
|
||||
if ($action === 'delete_outlook_event') {
|
||||
$rawInput = json_decode(file_get_contents('php://input'), true);
|
||||
$data = is_array($rawInput) ? $rawInput : $_POST;
|
||||
$eventId = trim($data['event_id'] ?? '');
|
||||
|
||||
if (empty($eventId)) {
|
||||
echo json_encode(['success' => false, 'error' => 'Geen event ID opgegeven']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!function_exists('microsoft_delete_event')) {
|
||||
echo json_encode(['success' => false, 'error' => 'Microsoft integratie niet beschikbaar']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$ok = microsoft_delete_event((int)$user['id'], $eventId);
|
||||
if ($ok) {
|
||||
echo json_encode(['success' => true, 'message' => 'Afspraak succesvol verwijderd uit Outlook']);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'error' => 'Kon afspraak niet verwijderen uit Outlook (mogelijk al verwijderd of geen bevoegdheid)']);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
// 16. Outlook Agenda-afspraak bijwerken
|
||||
if ($action === 'update_outlook_event') {
|
||||
$rawInput = json_decode(file_get_contents('php://input'), true);
|
||||
$data = is_array($rawInput) ? $rawInput : $_POST;
|
||||
$eventId = trim($data['event_id'] ?? '');
|
||||
$subject = trim($data['title'] ?? ($data['subject'] ?? ''));
|
||||
$date = trim($data['date'] ?? date('Y-m-d'));
|
||||
$startTime = trim($data['time_block_start'] ?? ($data['start_time'] ?? '09:00'));
|
||||
$endTime = trim($data['time_block_end'] ?? ($data['end_time'] ?? '09:30'));
|
||||
$description = trim($data['description'] ?? '');
|
||||
|
||||
if (empty($eventId) || empty($subject)) {
|
||||
echo json_encode(['success' => false, 'error' => 'Titel of event ID ontbreekt']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!function_exists('microsoft_update_event')) {
|
||||
echo json_encode(['success' => false, 'error' => 'Microsoft integratie niet beschikbaar']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$updateData = [
|
||||
'subject' => $subject,
|
||||
'date' => $date,
|
||||
'start_time' => $startTime,
|
||||
'end_time' => $endTime,
|
||||
];
|
||||
if ($description !== '') {
|
||||
$updateData['description'] = $description;
|
||||
}
|
||||
|
||||
$ok = microsoft_update_event((int)$user['id'], $eventId, $updateData);
|
||||
if ($ok) {
|
||||
echo json_encode(['success' => true, 'date' => $date, 'message' => 'Afspraak succesvol bijgewerkt in Outlook']);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'error' => 'Kon afspraak niet bijwerken in Microsoft Outlook']);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(['error' => 'Onbekende actie']);
|
||||
} catch (Exception $e) {
|
||||
http_response_code(500);
|
||||
|
||||
+25
-8
@@ -4,16 +4,23 @@
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/includes/auth.php';
|
||||
require_once __DIR__ . '/includes/settings.php';
|
||||
$currentUser = require_auth();
|
||||
$db = get_db_connection();
|
||||
$brainstormCategories = get_brainstorm_categories();
|
||||
|
||||
// Verwerk nieuwe sessie aanmaken
|
||||
$error = null;
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'create_session') {
|
||||
$title = trim($_POST['title'] ?? '');
|
||||
$theme = trim($_POST['theme'] ?? 'Product & Strategie');
|
||||
$theme = trim($_POST['category'] ?? ($_POST['theme'] ?? ''));
|
||||
if (empty($theme) && !empty($brainstormCategories)) {
|
||||
$firstActive = array_values(array_filter($brainstormCategories, fn($c) => !empty($c['is_active'])))[0] ?? null;
|
||||
$theme = $firstActive ? $firstActive['name'] : 'Product & Strategie';
|
||||
}
|
||||
$description = trim($_POST['description'] ?? '');
|
||||
|
||||
|
||||
if (!empty($title)) {
|
||||
$stmt = $db->prepare("
|
||||
INSERT INTO brainstorm_sessions (title, theme, description, created_by_id)
|
||||
@@ -148,13 +155,23 @@ require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
<div>
|
||||
<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">
|
||||
<option value="Product & Strategie">Product & Strategie</option>
|
||||
<option value="Procesverbetering">Procesverbetering</option>
|
||||
<option value="Klant & Service">Klant & Service</option>
|
||||
<option value="Technologie & IT">Technologie & IT</option>
|
||||
<option value="Marketing & Groei">Marketing & Groei</option>
|
||||
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Categorie</label>
|
||||
<select name="category" 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">
|
||||
<?php
|
||||
$hasActiveCategory = false;
|
||||
foreach ($brainstormCategories as $bCat):
|
||||
if (isset($bCat['is_active']) && empty($bCat['is_active'])) continue;
|
||||
$hasActiveCategory = true;
|
||||
?>
|
||||
<option value="<?= htmlspecialchars($bCat['name']) ?>"><?= htmlspecialchars($bCat['name']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
<?php if (!$hasActiveCategory): ?>
|
||||
<option value="Product & Strategie">Product & Strategie</option>
|
||||
<option value="Procesverbetering">Procesverbetering</option>
|
||||
<option value="Klant & Service">Klant & Service</option>
|
||||
<option value="Technologie & IT">Technologie & IT</option>
|
||||
<option value="Marketing & Groei">Marketing & Groei</option>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -722,6 +722,14 @@ async function aiSuggestRoadmapMeta(btn) {
|
||||
btn.innerHTML = origHtml;
|
||||
btn.disabled = false;
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
}
|
||||
} catch(err) {
|
||||
alert('Netwerkfout bij aanroepen van AI');
|
||||
if (btn) {
|
||||
btn.innerHTML = origHtml;
|
||||
btn.disabled = false;
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,6 +618,12 @@ function microsoft_update_event(int $userId, string $eventId, array $eventData):
|
||||
if (!empty($eventData['subject'])) {
|
||||
$payload['subject'] = $eventData['subject'];
|
||||
}
|
||||
if (isset($eventData['description']) && $eventData['description'] !== '') {
|
||||
$payload['body'] = [
|
||||
'contentType' => 'HTML',
|
||||
'content' => nl2br(htmlspecialchars($eventData['description'])),
|
||||
];
|
||||
}
|
||||
|
||||
$date = !empty($eventData['date']) ? $eventData['date'] : date('Y-m-d');
|
||||
$startTime = !empty($eventData['start_time']) ? $eventData['start_time'] : '09:00';
|
||||
|
||||
@@ -239,3 +239,24 @@ function get_calendar_block_reasons(): array {
|
||||
return $defaultReasons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Haalt de beheerbare brainstorm categorieën op.
|
||||
* Standaard voorzien van een duidelijke categorienaam, beschrijving en actief-status.
|
||||
*/
|
||||
function get_brainstorm_categories(): array {
|
||||
$defaultCategories = [
|
||||
['name' => 'Product & Strategie', 'description' => 'Strategische richting, nieuwe producten en visie', 'is_active' => 1],
|
||||
['name' => 'Procesverbetering', 'description' => 'Optimalisatie van werkprocessen en efficiëntie', 'is_active' => 1],
|
||||
['name' => 'Klant & Service', 'description' => 'Klanttevredenheid, support en klantervaring', 'is_active' => 1],
|
||||
['name' => 'Technologie & IT', 'description' => 'Architectuur, tooling, infrastructuur en tech stack','is_active' => 1],
|
||||
['name' => 'Marketing & Groei', 'description' => 'Leadgeneratie, branding en marktpositie', 'is_active' => 1],
|
||||
];
|
||||
|
||||
$saved = get_system_setting('brainstorm_categories', null);
|
||||
if (is_array($saved) && !empty($saved)) {
|
||||
return $saved;
|
||||
}
|
||||
return $defaultCategories;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+562
-172
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user