diff --git a/package.json b/package.json index c9d925f..74e9580 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.62.2", + "version": "1.62.3", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/components/WeeklyView.tsx b/src/components/WeeklyView.tsx index f59d666..22a9ba9 100644 --- a/src/components/WeeklyView.tsx +++ b/src/components/WeeklyView.tsx @@ -1607,9 +1607,14 @@ export default function WeeklyView() { type WeatherHour = { temp: number; code: number; feelsLike?: number; wind?: number; gusts?: number; precipProb?: number; precip?: number; humidity?: number; uv?: number }; const [weatherData, setWeatherData] = useState>({}); - // Extend events with editable flag from connections + // Extend events with editable flag from connections, deduplicate by id const calendarEvents = useMemo(() => { - return rawCalendarEvents.map((event) => { + const seen = new Set(); + return rawCalendarEvents.filter((event) => { + if (seen.has(event.id)) return false; + seen.add(event.id); + return true; + }).map((event) => { let isEditable = false; if (event.calendarId) { for (const conn of connections) { diff --git a/src/lib/calendar-events.ts b/src/lib/calendar-events.ts index c6e0ce5..2f92398 100644 --- a/src/lib/calendar-events.ts +++ b/src/lib/calendar-events.ts @@ -620,6 +620,8 @@ export const getCalendarEvents = async ( const calendarData = calendars.find(c => c.id === calendarId); + console.log(`[CALENDAR] Outlook calendar ${calendarId}: ${outlookEvents.length} events`, outlookEvents.map((e: any) => ({ id: e.id?.slice(-10), title: e.summary, start: e.start?.dateTime?.slice(0, 16), recurring: e.isRecurring }))); + events = events.concat(outlookEvents.map((event: any) => ({ id: event.id, title: event.summary || '(No Title)', diff --git a/src/lib/outlook-calendar.ts b/src/lib/outlook-calendar.ts index 04c2d9a..f5a32ef 100644 --- a/src/lib/outlook-calendar.ts +++ b/src/lib/outlook-calendar.ts @@ -212,16 +212,21 @@ export const getUpcomingEvents = async ( 'normal': 'default', 'personal': 'default', 'private': 'private', 'confidential': 'confidential', }; + // Outlook returns dateTime without Z suffix even when timeZone is UTC. + // Append Z so JS Date parsing treats it as UTC (not local time). + const fixUtc = (dt: string, tz: string) => + dt && tz === 'UTC' && !dt.endsWith('Z') ? dt + 'Z' : dt; + return { id: event.seriesMasterId ? `${event.seriesMasterId}::${event.id}` : event.id, summary: event.subject, description: event.body?.content || event.bodyPreview, start: { - dateTime: event.start.dateTime, + dateTime: fixUtc(event.start.dateTime, event.start.timeZone), timeZone: event.start.timeZone }, end: { - dateTime: event.end.dateTime, + dateTime: fixUtc(event.end.dateTime, event.end.timeZone), timeZone: event.end.timeZone }, location: event.location?.displayName,