feat: Enhance task management with start and end time handling
- Added functionality to calculate task duration based on provided start and end times. - Implemented logic to derive end time from start time and duration if only start time is provided. - Updated task creation and update APIs to handle new time fields. - Introduced a modal for editing tasks with flexible time and duration inputs. - Improved UI for task creation and editing, including better handling of time inputs and duration selection. - Added two-way synchronization with Outlook for task updates.
This commit is contained in:
+111
-19
@@ -38,8 +38,8 @@ try {
|
||||
$title = trim($data['title'] ?? '');
|
||||
$priority = in_array($data['priority'] ?? '', ['P1', 'P2', 'P3']) ? $data['priority'] : 'P2';
|
||||
$timeBlockStart = !empty($data['time_block_start']) ? trim($data['time_block_start']) : null;
|
||||
$durationMinutes = (int)($data['duration_minutes'] ?? 30);
|
||||
if ($durationMinutes <= 0) $durationMinutes = 30;
|
||||
$timeBlockEnd = !empty($data['time_block_end']) ? trim($data['time_block_end']) : null;
|
||||
$durationMinutes = (int)($data['duration_minutes'] ?? 0);
|
||||
$date = !empty($data['date']) ? trim($data['date']) : $today;
|
||||
$syncOutlook = !empty($data['sync_to_outlook']);
|
||||
|
||||
@@ -48,6 +48,30 @@ try {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Als zowel start- als eindtijd zijn opgegeven, bereken exact de minuten
|
||||
if (!empty($timeBlockStart) && !empty($timeBlockEnd)) {
|
||||
$t1 = strtotime("2000-01-01 {$timeBlockStart}");
|
||||
$t2 = strtotime("2000-01-01 {$timeBlockEnd}");
|
||||
if ($t1 !== false && $t2 !== false && $t2 > $t1) {
|
||||
$durationMinutes = (int)(($t2 - $t1) / 60);
|
||||
}
|
||||
}
|
||||
|
||||
if ($durationMinutes <= 0) {
|
||||
$durationMinutes = 30;
|
||||
}
|
||||
|
||||
// Als starttijd bekend is maar eindtijd nog niet, bereken eindtijd
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// Haal of maak daily plan op
|
||||
$stmtPlan = $db->prepare("
|
||||
INSERT INTO daily_plans (user_id, plan_date)
|
||||
@@ -60,7 +84,6 @@ try {
|
||||
$source = !empty($data['source']) ? substr(trim($data['source']), 0, 50) : 'FOCIZ';
|
||||
$externalId = !empty($data['external_id']) ? substr(trim($data['external_id']), 0, 255) : null;
|
||||
$externalUrl = !empty($data['external_url']) ? trim($data['external_url']) : null;
|
||||
$timeBlockEnd = null;
|
||||
$outlookSyncError = null;
|
||||
|
||||
// Als synchronisatie naar Outlook gewenst is (of source is OUTLOOK) en nog geen extern ID heeft
|
||||
@@ -75,6 +98,7 @@ try {
|
||||
'description' => "Gepland via Fociz Dagplanning ({$priority})",
|
||||
'date' => $date,
|
||||
'start_time' => $timeBlockStart,
|
||||
'end_time' => $timeBlockEnd,
|
||||
'duration_minutes' => $durationMinutes,
|
||||
]);
|
||||
|
||||
@@ -83,23 +107,12 @@ try {
|
||||
$externalId = $msResult['event_id'];
|
||||
$externalUrl = $msResult['web_link'] ?? 'https://outlook.office.com';
|
||||
$timeBlockStart = $msResult['start_time'] ?? $timeBlockStart;
|
||||
$timeBlockEnd = $msResult['end_time'] ?? null;
|
||||
$timeBlockEnd = $msResult['end_time'] ?? $timeBlockEnd;
|
||||
} else {
|
||||
$outlookSyncError = $msResult['error'] ?? 'Kon afspraak niet aanmaken in Microsoft Outlook';
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
$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)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, 'TODO', ?, ?, ?)
|
||||
@@ -116,14 +129,91 @@ try {
|
||||
'time_block_start' => $timeBlockStart,
|
||||
'time_block_end' => $timeBlockEnd,
|
||||
'duration_minutes' => $durationMinutes,
|
||||
'is_completed' => 0,
|
||||
'status' => 'TODO',
|
||||
'source' => $source,
|
||||
'external_id' => $externalId,
|
||||
'external_url' => $externalUrl,
|
||||
'external_url' => $externalUrl
|
||||
],
|
||||
'outlook_synced' => ($source === 'OUTLOOK' && !empty($externalId)),
|
||||
'outlook_error' => $outlookSyncError,
|
||||
'outlook_error' => $outlookSyncError
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 2b. Taak bewerken (titel, prioriteit, starttijd, eindtijd, duur)
|
||||
if ($action === 'update_task') {
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
$taskId = (int)($data['task_id'] ?? 0);
|
||||
$title = trim($data['title'] ?? '');
|
||||
$priority = in_array($data['priority'] ?? '', ['P1', 'P2', 'P3']) ? $data['priority'] : 'P2';
|
||||
$timeBlockStart = !empty($data['time_block_start']) ? trim($data['time_block_start']) : null;
|
||||
$timeBlockEnd = !empty($data['time_block_end']) ? trim($data['time_block_end']) : null;
|
||||
$durationMinutes = (int)($data['duration_minutes'] ?? 0);
|
||||
|
||||
if (empty($title)) {
|
||||
echo json_encode(['error' => 'Titel mag niet leeg zijn']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Haal bestaande taak op
|
||||
$stmtTask = $db->prepare("SELECT * FROM tasks WHERE id = ? AND user_id = ?");
|
||||
$stmtTask->execute([$taskId, $user['id']]);
|
||||
$existingTask = $stmtTask->fetch();
|
||||
|
||||
if (!$existingTask) {
|
||||
echo json_encode(['error' => 'Taak niet gevonden']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!empty($timeBlockStart) && !empty($timeBlockEnd)) {
|
||||
$t1 = strtotime("2000-01-01 {$timeBlockStart}");
|
||||
$t2 = strtotime("2000-01-01 {$timeBlockEnd}");
|
||||
if ($t1 !== false && $t2 !== false && $t2 > $t1) {
|
||||
$durationMinutes = (int)(($t2 - $t1) / 60);
|
||||
}
|
||||
}
|
||||
|
||||
if ($durationMinutes <= 0) {
|
||||
$durationMinutes = (int)($existingTask['duration_minutes'] ?: 30);
|
||||
}
|
||||
|
||||
if (!empty($timeBlockStart) && empty($timeBlockEnd)) {
|
||||
try {
|
||||
$dtEnd = new DateTime("2000-01-01 {$timeBlockStart}:00", new DateTimeZone('Europe/Amsterdam'));
|
||||
$dtEnd->modify("+{$durationMinutes} minutes");
|
||||
$timeBlockEnd = $dtEnd->format('H:i');
|
||||
} catch (Throwable $e) {}
|
||||
}
|
||||
|
||||
// Indien gekoppeld aan Outlook, werk afspraak bij via Graph API
|
||||
if (!empty($existingTask['external_id']) && $existingTask['source'] === 'OUTLOOK') {
|
||||
try {
|
||||
$stmtPlan = $db->prepare("SELECT plan_date FROM daily_plans WHERE id = ?");
|
||||
$stmtPlan->execute([$existingTask['daily_plan_id']]);
|
||||
$planDate = $stmtPlan->fetchColumn() ?: date('Y-m-d');
|
||||
|
||||
microsoft_update_event($user['id'], $existingTask['external_id'], [
|
||||
'subject' => $title,
|
||||
'date' => $planDate,
|
||||
'start_time' => $timeBlockStart ?: '09:00',
|
||||
'end_time' => $timeBlockEnd ?: '09:30',
|
||||
]);
|
||||
} catch (Throwable $t) {
|
||||
error_log("Fout bij bijwerken Outlook event: " . $t->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$stmtUpdate = $db->prepare("
|
||||
UPDATE tasks
|
||||
SET title = ?, priority = ?, time_block_start = ?, time_block_end = ?, duration_minutes = ?
|
||||
WHERE id = ? AND user_id = ?
|
||||
");
|
||||
$stmtUpdate->execute([$title, $priority, $timeBlockStart, $timeBlockEnd, $durationMinutes, $taskId, $user['id']]);
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'time_block_start' => $timeBlockStart,
|
||||
'time_block_end' => $timeBlockEnd,
|
||||
'duration_minutes' => $durationMinutes
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
@@ -166,6 +256,7 @@ try {
|
||||
|
||||
$planDate = $task['plan_date'] ?: $today;
|
||||
$startTime = !empty($task['time_block_start']) ? $task['time_block_start'] : ($data['time_block_start'] ?? '09:00');
|
||||
$endTime = !empty($task['time_block_end']) ? $task['time_block_end'] : null;
|
||||
$duration = (int)($task['duration_minutes'] ?: 30);
|
||||
|
||||
$msResult = microsoft_create_event($user['id'], [
|
||||
@@ -173,6 +264,7 @@ try {
|
||||
'description' => "Gepland via Fociz Dagplanning (" . $task['priority'] . ")",
|
||||
'date' => $planDate,
|
||||
'start_time' => $startTime,
|
||||
'end_time' => $endTime,
|
||||
'duration_minutes' => $duration,
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user