"use client"; import { AnimatePresence, motion, useReducedMotion } from "framer-motion"; import { useEffect, useState } from "react"; import { CheckCircleIcon, PencilIcon, PlusIcon, XIcon } from "@/components/icons"; import { Button } from "@/components/ui"; import { useI18n } from "@/lib/i18n"; import { springSheet } from "@/lib/motion"; import { conversationMatches } from "@/lib/chat"; import type { ChatConversation } from "@/lib/schemas"; import { cn, formatDate } from "@/lib/utils"; type HistoryProps = { conversations: ChatConversation[]; currentId: string | null; query: string; onQueryChange: (value: string) => void; onOpen: (id: string) => void; onRename: (id: string, title: string) => void; onDelete: (conversation: ChatConversation) => void; onNew: () => void; }; /** The conversation list: a column on desktop, a sheet on phones. */ export function ChatHistoryList({ conversations, currentId, query, onQueryChange, onOpen, onRename, onDelete, onNew, }: HistoryProps) { const { t } = useI18n(); const [renaming, setRenaming] = useState(null); const [draft, setDraft] = useState(""); const visible = conversations.filter((conversation) => conversationMatches(conversation.title, conversation.messages, query), ); const startRename = (conversation: ChatConversation) => { setRenaming(conversation.id); setDraft(conversation.title); }; const commit = () => { if (renaming) onRename(renaming, draft); setRenaming(null); }; return (
onQueryChange(event.target.value)} placeholder={t("chat.searchChats")} aria-label={t("chat.searchChats")} className="min-w-0 flex-1 rounded-xl border border-[var(--hairline)] bg-[var(--surface-strong)] px-2.5 py-2 text-[16px] text-[var(--text)] outline-none transition placeholder:text-[var(--text-subtle)] focus:border-accent-400/60 sm:text-[13px]" />
{visible.length === 0 ? (

{query ? t("chat.noResults") : t("chat.noHistory")}

) : ( )}
); } /** Phone sheet wrapper around the list (drag/backdrop close, spring). */ export function HistorySheet({ open, onClose, ...props }: HistoryProps & { open: boolean; onClose: () => void }) { const { t } = useI18n(); const reduceMotion = useReducedMotion(); useEffect(() => { if (!open) return; const onKey = (event: KeyboardEvent) => { if (event.key === "Escape") onClose(); }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [open, onClose]); return ( {open ? (

{t("chat.history")}

) : null} ); }