import { MoreHorizontal, Trash2 } from "lucide-react"; import { useTranslation } from "react-i18next"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { ScrollArea } from "@/components/ui/scroll-area"; import { cn } from "@/lib/utils"; import type { ChatSummary } from "@/lib/types"; interface ChatListProps { sessions: ChatSummary[]; activeKey: string | null; onSelect: (key: string) => void; onRequestDelete: (key: string, label: string) => void; loading?: boolean; emptyLabel?: string; } function titleFor(s: ChatSummary, fallbackTitle: string): string { const p = (s.title || s.preview)?.trim(); if (p) return p.length > 48 ? `${p.slice(0, 45)}…` : p; return fallbackTitle; } export function ChatList({ sessions, activeKey, onSelect, onRequestDelete, loading, emptyLabel, }: ChatListProps) { const { t } = useTranslation(); if (loading && sessions.length === 0) { return (
{t("chat.loading")}
); } if (sessions.length === 0) { return (
{emptyLabel ?? t("chat.noSessions")}
); } const groups = groupSessions(sessions, { today: t("chat.groups.today"), yesterday: t("chat.groups.yesterday"), earlier: t("chat.groups.earlier"), }); return (
{groups.map((group) => (
{group.label}
    {group.sessions.map((s) => { const active = s.key === activeKey; const title = titleFor( s, t("chat.fallbackTitle", { id: s.chatId.slice(0, 6) }), ); return (
  • event.preventDefault()} > { window.setTimeout(() => onRequestDelete(s.key, title), 0); }} className="text-destructive focus:text-destructive" > {t("chat.delete")}
  • ); })}
))}
); } function groupSessions( sessions: ChatSummary[], labels: { today: string; yesterday: string; earlier: string }, ): Array<{ label: string; sessions: ChatSummary[] }> { const now = new Date(); const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime(); const startOfYesterday = startOfToday - 24 * 60 * 60 * 1000; const buckets = new Map(); for (const session of sessions) { const timestamp = Date.parse(session.updatedAt ?? session.createdAt ?? ""); const label = Number.isFinite(timestamp) && timestamp >= startOfToday ? labels.today : Number.isFinite(timestamp) && timestamp >= startOfYesterday ? labels.yesterday : labels.earlier; const bucket = buckets.get(label) ?? []; bucket.push(session); buckets.set(label, bucket); } return [labels.today, labels.yesterday, labels.earlier] .map((label) => ({ label, sessions: buckets.get(label) ?? [] })) .filter((group) => group.sessions.length > 0); }