diff --git a/src/components/layouts/app-sidebar-threads.tsx b/src/components/layouts/app-sidebar-threads.tsx index 4fe66c5b6..fd7ae481a 100644 --- a/src/components/layouts/app-sidebar-threads.tsx +++ b/src/components/layouts/app-sidebar-threads.tsx @@ -108,14 +108,17 @@ export function AppSidebarThreads() { return []; } - const today = new Date(); - today.setHours(0, 0, 0, 0); - - const yesterday = new Date(today); - yesterday.setDate(yesterday.getDate() - 1); + // Get today's date at midnight in local timezone + const now = new Date(); + const todayLocal = new Date( + now.getFullYear(), + now.getMonth(), + now.getDate(), + ); + const todayStart = todayLocal.getTime(); - const lastWeek = new Date(today); - lastWeek.setDate(lastWeek.getDate() - 7); + const yesterdayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1).getTime(); + const lastWeekStart = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7).getTime(); const groups: ThreadGroup[] = [ { label: t("today"), threads: [] }, @@ -125,17 +128,31 @@ export function AppSidebarThreads() { ]; displayThreadList.forEach((thread) => { - const threadDate = - (thread.lastMessageAt - ? new Date(thread.lastMessageAt) - : new Date(thread.createdAt)) || new Date(); - threadDate.setHours(0, 0, 0, 0); + // Get the timestamp - lastMessageAt is already a timestamp, createdAt is a Date + const threadTimestamp = + thread.lastMessageAt || new Date(thread.createdAt).getTime(); + + // Convert timestamp to a date in LOCAL timezone + const threadDate = new Date(threadTimestamp); + + // Get the local date components (this gives us the date in user's timezone) + const localYear = threadDate.getFullYear(); + const localMonth = threadDate.getMonth(); + const localDay = threadDate.getDate(); + + // Create normalized day start using local components + const normalizedThreadDay = new Date( + localYear, + localMonth, + localDay, + ).getTime(); - if (threadDate.getTime() === today.getTime()) { + // Check which group this thread belongs to + if (normalizedThreadDay === todayStart) { groups[0].threads.push(thread); - } else if (threadDate.getTime() === yesterday.getTime()) { + } else if (normalizedThreadDay === yesterdayStart) { groups[1].threads.push(thread); - } else if (threadDate.getTime() >= lastWeek.getTime()) { + } else if (normalizedThreadDay >= lastWeekStart) { groups[2].threads.push(thread); } else { groups[3].threads.push(thread); diff --git a/src/lib/db/pg/repositories/chat-repository.pg.ts b/src/lib/db/pg/repositories/chat-repository.pg.ts index 6d0e398e0..96c755b7f 100644 --- a/src/lib/db/pg/repositories/chat-repository.pg.ts +++ b/src/lib/db/pg/repositories/chat-repository.pg.ts @@ -100,14 +100,21 @@ export const pgChatRepository: ChatRepository = { .orderBy(desc(sql`last_message_at`)); return threadWithLatestMessage.map((row) => { + let timestamp = 0; + if (row.lastMessageAt) { + // PostgreSQL returns timestamp without timezone info in format 'YYYY-MM-DD HH:MM:SS' + // We need to treat it as UTC, not local time + // Add 'Z' suffix to make it explicit UTC, or use Date.UTC + const utcTimestamp = row.lastMessageAt.replace(' ', 'T') + 'Z'; + timestamp = new Date(utcTimestamp).getTime(); + } + return { id: row.threadId, title: row.title, userId: row.userId, createdAt: row.createdAt, - lastMessageAt: row.lastMessageAt - ? new Date(row.lastMessageAt).getTime() - : 0, + lastMessageAt: timestamp, }; }); },