diff --git a/hooks/use-task-notifications.ts b/hooks/use-task-notifications.ts index 6576f93..f573767 100644 --- a/hooks/use-task-notifications.ts +++ b/hooks/use-task-notifications.ts @@ -81,10 +81,35 @@ export function useTaskNotifications() { notifiedCount: notifiedTaskIdsRef.current.size, }); - // Helper function to parse date correctly (handles Leantime dates with Z) - const parseTaskDate = (dateStr: string | null, taskId?: string, taskTitle?: string): Date | null => { + // Helper function to parse date correctly (handles Leantime and Twenty CRM dates) + const parseTaskDate = (dateStr: string | null, taskId?: string, taskTitle?: string, source?: string): Date | null => { if (!dateStr) return null; + // Twenty CRM dates are in ISO format with timezone (usually UTC) + // Unlike Leantime, Twenty CRM stores dates in true UTC + // When a user enters 10:45 (local time) in Twenty CRM, it's stored as UTC (e.g., 09:45 UTC if UTC+1) + // We need to parse it and let JavaScript convert it to local time automatically + if (source === 'twenty-crm') { + // Parse the ISO date string - JavaScript will automatically convert UTC to local time + // If Twenty CRM stores 09:45 UTC (which displays as 10:45 local), new Date() will convert it to 10:45 local + const parsedDate = new Date(dateStr); + + console.log('[useTaskNotifications] 📅 Parsing Twenty CRM date (UTC -> local)', { + taskId, + taskTitle, + rawDate: dateStr, + parsedLocal: parsedDate.toLocaleString('fr-FR'), + parsedISO: parsedDate.toISOString(), + localHour: parsedDate.getHours(), + localMinute: parsedDate.getMinutes(), + utcHour: parsedDate.getUTCHours(), + utcMinute: parsedDate.getUTCMinutes(), + timezoneOffset: new Date().getTimezoneOffset(), + }); + + return parsedDate; + } + // Leantime dates with 'Z' are actually local time stored as UTC // We need to extract the time components and create a local date if (dateStr.endsWith('Z')) { @@ -114,7 +139,7 @@ export function useTaskNotifications() { hour: utcDate.getUTCHours(), minute: utcDate.getUTCMinutes(), }, - parsedLocal: parsedDate.toLocaleString('fr-FR', { timeZone: 'Europe/Paris' }), + parsedLocal: parsedDate.toLocaleString('fr-FR'), parsedISO: parsedDate.toISOString(), }); @@ -148,8 +173,8 @@ export function useTaskNotifications() { continue; } - // Parse the notification date - const notificationDate = parseTaskDate(task.dateToFinish, task.id, task.headline); + // Parse the notification date (pass source to handle Twenty CRM dates correctly) + const notificationDate = parseTaskDate(task.dateToFinish, task.id, task.headline, task.source); if (!notificationDate || isNaN(notificationDate.getTime())) { console.log('[useTaskNotifications] ⏭️ Task has no valid date', {