From 5ac295f3b743211d353e04a7c4d53225a8579180 Mon Sep 17 00:00:00 2001 From: alma Date: Fri, 16 Jan 2026 10:06:11 +0100 Subject: [PATCH] Notifications corrections --- components/flow.tsx | 4 +++- hooks/use-task-notifications.ts | 39 +++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/components/flow.tsx b/components/flow.tsx index bce29d7..be0bcb4 100644 --- a/components/flow.tsx +++ b/components/flow.tsx @@ -168,7 +168,9 @@ export function Duties() { } // Use local date comparison to avoid timezone issues - const taskDueDate = new Date(dueDate); + // Leantime dates with 'Z' are actually local time, not UTC - remove Z before parsing + const dateStrForParsing = dueDate.endsWith('Z') ? dueDate.slice(0, -1) : dueDate; + const taskDueDate = new Date(dateStrForParsing); const taskYear = taskDueDate.getFullYear(); const taskMonth = taskDueDate.getMonth(); const taskDay = taskDueDate.getDate(); diff --git a/hooks/use-task-notifications.ts b/hooks/use-task-notifications.ts index 8604909..bacee02 100644 --- a/hooks/use-task-notifications.ts +++ b/hooks/use-task-notifications.ts @@ -92,11 +92,46 @@ export function useTaskNotifications() { } // For both Leantime and Twenty CRM tasks: notification at due date time (dateToFinish) - // Note: Twenty CRM doesn't have a separate start date field, so we use dueAt for notifications + // Note: Leantime dates might be in MySQL format (YYYY-MM-DD HH:MM:SS) without timezone + // We need to parse them correctly to avoid timezone issues let notificationDate: Date | null = null; if (task.dateToFinish) { - notificationDate = new Date(task.dateToFinish); + const dateStr = task.dateToFinish; + + console.log('[useTaskNotifications] 📅 Parsing date', { + id: task.id, + title: task.headline, + source: task.source, + rawDate: dateStr, + dateFormat: dateStr.includes('T') ? 'ISO' : dateStr.includes(' ') ? 'MySQL' : 'unknown', + }); + + // Leantime dates are often in format with 'Z' (UTC marker) but actually represent local time + // We need to parse them correctly. If it ends with Z, remove it and treat as local time + if (dateStr.endsWith('Z')) { + // Remove Z and parse as local time (Leantime dates with Z are actually local time, not UTC) + const withoutZ = dateStr.slice(0, -1); + notificationDate = new Date(withoutZ); + } else if (dateStr.includes('T')) { + // ISO format without Z - treat as local time + notificationDate = new Date(dateStr); + } else if (dateStr.includes(' ')) { + // MySQL format: "YYYY-MM-DD HH:MM:SS" - parse as local time + const isoLike = dateStr.replace(' ', 'T'); + notificationDate = new Date(isoLike); + } else { + // Try direct parsing + notificationDate = new Date(dateStr); + } + + console.log('[useTaskNotifications] 📅 Parsed date', { + id: task.id, + rawDate: dateStr, + parsedDate: notificationDate.toISOString(), + localDate: notificationDate.toLocaleString('fr-FR'), + isValid: !isNaN(notificationDate.getTime()), + }); } if (!notificationDate || isNaN(notificationDate.getTime())) {