9da056b480
- Implemented roadmap.php for displaying and managing roadmap items with filters for quarter and status. - Created schema.sql to define the database structure for users, invites, daily plans, tasks, brainstorm sessions, brainstorm cards, roadmap items, and integrations. - Developed users.php for admin panel to manage team members and invitations, including functionality to create and revoke invites.
305 lines
15 KiB
PHP
305 lines
15 KiB
PHP
<?php
|
|
/**
|
|
* Fociz Integraties Hub (Outlook, Teams, Jira)
|
|
*/
|
|
|
|
require_once __DIR__ . '/includes/header.php';
|
|
$db = get_db_connection();
|
|
$userId = $currentUser['id'];
|
|
|
|
// Formulierverwerking voor integratie instellingen
|
|
$message = null;
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$provider = $_POST['provider'] ?? '';
|
|
$isDemo = isset($_POST['is_demo_mode']) ? 1 : 0;
|
|
$settings = json_encode([
|
|
'client_id' => $_POST['client_id'] ?? '',
|
|
'client_secret' => $_POST['client_secret'] ?? '',
|
|
'tenant_id' => $_POST['tenant_id'] ?? '',
|
|
'jira_domain' => $_POST['jira_domain'] ?? '',
|
|
'jira_email' => $_POST['jira_email'] ?? '',
|
|
'jira_api_token' => $_POST['jira_api_token'] ?? '',
|
|
]);
|
|
|
|
if (in_array($provider, ['OUTLOOK', 'TEAMS', 'JIRA'])) {
|
|
$stmt = $db->prepare("
|
|
INSERT INTO integrations (user_id, provider, is_enabled, is_demo_mode, settings, last_sync_at)
|
|
VALUES (?, ?, 1, ?, ?, NOW())
|
|
ON DUPLICATE KEY UPDATE is_demo_mode = VALUES(is_demo_mode), settings = VALUES(settings), last_sync_at = NOW()
|
|
");
|
|
$stmt->execute([$userId, $provider, $isDemo, $settings]);
|
|
$message = "Instellingen voor {$provider} succesvol opgeslagen.";
|
|
}
|
|
}
|
|
|
|
// Haal huidige configuraties op
|
|
$stmtConfigs = $db->prepare("SELECT * FROM integrations WHERE user_id = ?");
|
|
$stmtConfigs->execute([$userId]);
|
|
$configsRaw = $stmtConfigs->fetchAll();
|
|
$configs = [];
|
|
foreach ($configsRaw as $c) {
|
|
$configs[$c['provider']] = $c;
|
|
$configs[$c['provider']]['settings_parsed'] = json_decode($c['settings'] ?? '{}', true) ?: [];
|
|
}
|
|
|
|
// Jira demo issues
|
|
$jiraIssues = [
|
|
[
|
|
'key' => 'FOC-101',
|
|
'summary' => 'Tweestapsverificatie (2FA TOTP) flow implementeren',
|
|
'status' => 'In Progress',
|
|
'priority' => 'High',
|
|
'epic' => 'Security & Access',
|
|
],
|
|
[
|
|
'key' => 'FOC-102',
|
|
'summary' => 'Interactief whiteboard canvas voor brainstormsessies',
|
|
'status' => 'To Do',
|
|
'priority' => 'High',
|
|
'epic' => 'Brainstorming Module',
|
|
],
|
|
[
|
|
'key' => 'FOC-103',
|
|
'summary' => 'Koppeling met Microsoft Outlook Calendar & Teams Graph API',
|
|
'status' => 'In Review',
|
|
'priority' => 'Medium',
|
|
'epic' => 'Integrations Hub',
|
|
],
|
|
[
|
|
'key' => 'FOC-104',
|
|
'summary' => 'Roadmap kwartaalweergave en voortgangsindicatoren',
|
|
'status' => 'To Do',
|
|
'priority' => 'Medium',
|
|
'epic' => 'Roadmap Module',
|
|
]
|
|
];
|
|
?>
|
|
|
|
<div class="space-y-6">
|
|
<!-- Header -->
|
|
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-6 shadow-xl">
|
|
<div class="flex items-center space-x-2 text-blue-400 text-xs font-semibold uppercase tracking-wider mb-1">
|
|
<i data-lucide="layers" class="w-4 h-4"></i>
|
|
<span>Connectiviteit & Synchronisatie</span>
|
|
</div>
|
|
<h1 class="text-2xl sm:text-3xl font-black text-white tracking-tight">
|
|
Integraties Hub
|
|
</h1>
|
|
<p class="text-slate-400 text-xs sm:text-sm mt-1">
|
|
Beheer uw koppelingen met Microsoft Outlook (agenda & taken), Microsoft Teams (meetings) en Atlassian Jira (issues & roadmap).
|
|
</p>
|
|
</div>
|
|
|
|
<?php if ($message): ?>
|
|
<div class="p-4 rounded-xl bg-emerald-500/10 border border-emerald-500/30 text-emerald-400 text-xs font-semibold flex items-center space-x-2">
|
|
<i data-lucide="check-circle" class="w-4 h-4"></i>
|
|
<span><?= htmlspecialchars($message) ?></span>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Integratie Cards Grid -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
|
|
<!-- 1. OUTLOOK -->
|
|
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 shadow-xl flex flex-col justify-between">
|
|
<div>
|
|
<div class="flex items-center justify-between mb-4">
|
|
<div class="w-10 h-10 rounded-xl bg-blue-500/10 border border-blue-500/30 text-blue-400 flex items-center justify-center font-bold">
|
|
<i data-lucide="calendar" class="w-5 h-5"></i>
|
|
</div>
|
|
<span class="px-2.5 py-0.5 rounded-full bg-emerald-500/10 border border-emerald-500/20 text-emerald-400 text-xs font-medium flex items-center space-x-1">
|
|
<i data-lucide="check-circle" class="w-3 h-3"></i>
|
|
<span>Actief</span>
|
|
</span>
|
|
</div>
|
|
|
|
<h3 class="text-base font-bold text-white mb-1">Microsoft Outlook</h3>
|
|
<p class="text-xs text-slate-400 mb-4">
|
|
Synchroniseert uw agenda-afspraken en e-mails automatisch naar uw dagplanning en time-blocks.
|
|
</p>
|
|
|
|
<div class="bg-slate-950/60 rounded-xl p-3 border border-slate-800/80 text-xs space-y-2 mb-4">
|
|
<div class="flex items-center justify-between text-slate-400">
|
|
<span>Status:</span>
|
|
<span class="text-emerald-400 font-semibold">Gekoppeld</span>
|
|
</div>
|
|
<div class="flex items-center justify-between text-slate-400">
|
|
<span>Sync frequentie:</span>
|
|
<span class="text-slate-200">Elke 15 min</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Instellingen formulier -->
|
|
<form method="POST" action="/integrations.php" class="pt-3 border-t border-slate-800 space-y-3">
|
|
<input type="hidden" name="provider" value="OUTLOOK">
|
|
|
|
<label class="flex items-center space-x-2 text-xs text-slate-300">
|
|
<input type="checkbox" name="is_demo_mode" value="1" <?= empty($configs['OUTLOOK']) || !empty($configs['OUTLOOK']['is_demo_mode']) ? 'checked' : '' ?> class="rounded bg-slate-900 border-slate-700 text-emerald-500">
|
|
<span>Gebruik interactieve Sandbox data</span>
|
|
</label>
|
|
|
|
<button type="submit" class="w-full py-2 rounded-xl bg-slate-800 hover:bg-slate-700 text-white text-xs font-semibold transition">
|
|
Instellingen Bijwerken
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- 2. MICROSOFT TEAMS -->
|
|
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 shadow-xl flex flex-col justify-between">
|
|
<div>
|
|
<div class="flex items-center justify-between mb-4">
|
|
<div class="w-10 h-10 rounded-xl bg-indigo-500/10 border border-indigo-500/30 text-indigo-400 flex items-center justify-center font-bold">
|
|
<i data-lucide="video" class="w-5 h-5"></i>
|
|
</div>
|
|
<span class="px-2.5 py-0.5 rounded-full bg-emerald-500/10 border border-emerald-500/20 text-emerald-400 text-xs font-medium flex items-center space-x-1">
|
|
<i data-lucide="check-circle" class="w-3 h-3"></i>
|
|
<span>Actief</span>
|
|
</span>
|
|
</div>
|
|
|
|
<h3 class="text-base font-bold text-white mb-1">Microsoft Teams</h3>
|
|
<p class="text-xs text-slate-400 mb-4">
|
|
Toont vandaag geplande Teams meetings met directe 'Deelnemen' links en kanaalupdates.
|
|
</p>
|
|
|
|
<div class="bg-slate-950/60 rounded-xl p-3 border border-slate-800/80 text-xs space-y-2 mb-4">
|
|
<div class="flex items-center justify-between text-slate-400">
|
|
<span>Direct Deelnemen:</span>
|
|
<span class="text-emerald-400 font-semibold">Ondersteund</span>
|
|
</div>
|
|
<div class="flex items-center justify-between text-slate-400">
|
|
<span>Meldingen:</span>
|
|
<span class="text-slate-200">Ingeschakeld</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="POST" action="/integrations.php" class="pt-3 border-t border-slate-800 space-y-3">
|
|
<input type="hidden" name="provider" value="TEAMS">
|
|
|
|
<label class="flex items-center space-x-2 text-xs text-slate-300">
|
|
<input type="checkbox" name="is_demo_mode" value="1" <?= empty($configs['TEAMS']) || !empty($configs['TEAMS']['is_demo_mode']) ? 'checked' : '' ?> class="rounded bg-slate-900 border-slate-700 text-emerald-500">
|
|
<span>Gebruik interactieve Sandbox data</span>
|
|
</label>
|
|
|
|
<button type="submit" class="w-full py-2 rounded-xl bg-slate-800 hover:bg-slate-700 text-white text-xs font-semibold transition">
|
|
Instellingen Bijwerken
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- 3. ATLASSIAN JIRA -->
|
|
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 shadow-xl flex flex-col justify-between">
|
|
<div>
|
|
<div class="flex items-center justify-between mb-4">
|
|
<div class="w-10 h-10 rounded-xl bg-sky-500/10 border border-sky-500/30 text-sky-400 flex items-center justify-center font-bold">
|
|
<i data-lucide="trello" class="w-5 h-5"></i>
|
|
</div>
|
|
<span class="px-2.5 py-0.5 rounded-full bg-emerald-500/10 border border-emerald-500/20 text-emerald-400 text-xs font-medium flex items-center space-x-1">
|
|
<i data-lucide="check-circle" class="w-3 h-3"></i>
|
|
<span>Actief</span>
|
|
</span>
|
|
</div>
|
|
|
|
<h3 class="text-base font-bold text-white mb-1">Atlassian Jira</h3>
|
|
<p class="text-xs text-slate-400 mb-4">
|
|
Koppelt Jira Epics en Issues direct aan uw roadmap items en takenlijst.
|
|
</p>
|
|
|
|
<div class="bg-slate-950/60 rounded-xl p-3 border border-slate-800/80 text-xs space-y-2 mb-4">
|
|
<div class="flex items-center justify-between text-slate-400">
|
|
<span>Two-way Status Sync:</span>
|
|
<span class="text-emerald-400 font-semibold">Ondersteund</span>
|
|
</div>
|
|
<div class="flex items-center justify-between text-slate-400">
|
|
<span>Roadmap Linkage:</span>
|
|
<span class="text-slate-200">Actief</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="POST" action="/integrations.php" class="pt-3 border-t border-slate-800 space-y-2">
|
|
<input type="hidden" name="provider" value="JIRA">
|
|
|
|
<div>
|
|
<label class="block text-[10px] text-slate-400 mb-0.5">Jira Cloud Domein</label>
|
|
<input type="text" name="jira_domain" placeholder="uwbedrijf.atlassian.net" value="<?= htmlspecialchars($configs['JIRA']['settings_parsed']['jira_domain'] ?? '') ?>" class="w-full bg-slate-950 border border-slate-800 rounded-lg px-2.5 py-1 text-xs text-white placeholder-slate-600 focus:outline-none">
|
|
</div>
|
|
|
|
<label class="flex items-center space-x-2 text-xs text-slate-300 pt-1">
|
|
<input type="checkbox" name="is_demo_mode" value="1" <?= empty($configs['JIRA']) || !empty($configs['JIRA']['is_demo_mode']) ? 'checked' : '' ?> class="rounded bg-slate-900 border-slate-700 text-emerald-500">
|
|
<span>Gebruik interactieve Sandbox data</span>
|
|
</label>
|
|
|
|
<button type="submit" class="w-full py-2 rounded-xl bg-slate-800 hover:bg-slate-700 text-white text-xs font-semibold transition">
|
|
Jira Opslaan
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Gesynchroniseerde Jira Issues & 1-Click Import naar Dagplanning -->
|
|
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-6 shadow-xl space-y-4">
|
|
<div class="flex items-center justify-between pb-3 border-b border-slate-800">
|
|
<div class="flex items-center space-x-2">
|
|
<i data-lucide="check-square" class="w-5 h-5 text-sky-400"></i>
|
|
<h3 class="text-sm font-bold text-white uppercase tracking-wider">
|
|
Jira Issues Toegewezen aan U
|
|
</h3>
|
|
</div>
|
|
<span class="text-xs text-slate-400 font-mono"><?= count($jiraIssues) ?> issues</span>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
|
<?php foreach ($jiraIssues as $issue): ?>
|
|
<div class="bg-slate-950/60 border border-slate-800 hover:border-slate-700 rounded-xl p-4 flex flex-col justify-between transition">
|
|
<div>
|
|
<div class="flex items-center justify-between mb-2">
|
|
<span class="font-mono text-xs font-bold text-sky-400 bg-sky-500/10 border border-sky-500/20 px-2 py-0.5 rounded">
|
|
<?= htmlspecialchars($issue['key']) ?>
|
|
</span>
|
|
<span class="text-[10px] font-semibold px-2 py-0.5 rounded bg-slate-800 text-slate-300">
|
|
<?= htmlspecialchars($issue['status']) ?>
|
|
</span>
|
|
</div>
|
|
<h4 class="text-xs font-bold text-white leading-snug">
|
|
<?= htmlspecialchars($issue['summary']) ?>
|
|
</h4>
|
|
<span class="text-[10px] text-slate-500 mt-1 block">Epic: <?= htmlspecialchars($issue['epic']) ?></span>
|
|
</div>
|
|
|
|
<div class="mt-4 pt-3 border-t border-slate-800/80 flex items-center justify-between">
|
|
<span class="text-[10px] font-bold text-amber-400"><?= htmlspecialchars($issue['priority']) ?> Priority</span>
|
|
<button onclick="importJiraToTasks('<?= htmlspecialchars(addslashes($issue['summary'])) ?>', '<?= htmlspecialchars($issue['key']) ?>')" class="flex items-center space-x-1 text-[11px] font-semibold text-emerald-400 hover:text-emerald-300 bg-emerald-500/10 hover:bg-emerald-500/20 border border-emerald-500/20 px-2.5 py-1 rounded-lg transition">
|
|
<i data-lucide="plus" class="w-3 h-3"></i>
|
|
<span>Plan als Dagtaak</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
async function importJiraToTasks(title, jiraKey) {
|
|
const res = await fetch('/api/planner.php?action=add_task', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({
|
|
title: `[${jiraKey}] ${title}`,
|
|
priority: 'P1',
|
|
date: '<?= date('Y-m-d') ?>'
|
|
})
|
|
});
|
|
const data = await res.json();
|
|
if (data.success) {
|
|
alert(`Jira issue ${jiraKey} is toegevoegd aan uw dagplanning!`);
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
|
|