| 1 | import { ChevronLeft, PanelLeftClose, Plus } from "lucide-react"; |
| 2 | import { useTranslation } from "react-i18next"; |
| 3 | |
| 4 | import { ChatList } from "@/components/ChatList"; |
| 5 | import { Button } from "@/components/ui/button"; |
| 6 | import { Separator } from "@/components/ui/separator"; |
| 7 | import type { ChatSummary } from "@/lib/types"; |
| 8 | |
| 9 | interface SidebarProps { |
| 10 | sessions: ChatSummary[]; |
| 11 | activeKey: string | null; |
| 12 | loading: boolean; |
| 13 | onNewChat: () => void; |
| 14 | onSelect: (key: string) => void; |
| 15 | onRequestDelete: (key: string, label: string) => void; |
| 16 | onCollapse: () => void; |
| 17 | } |
| 18 | |
| 19 | export function Sidebar(props: SidebarProps) { |
| 20 | const { t } = useTranslation(); |
| 21 | const goBack = () => { |
| 22 | window.history.back(); |
| 23 | }; |
| 24 | return ( |
| 25 | <aside className="flex h-full w-full flex-col border-r border-sidebar-border/70 bg-sidebar text-sidebar-foreground"> |
| 26 | <div className="flex items-center justify-between px-2 py-2"> |
| 27 | <Button |
| 28 | variant="ghost" |
| 29 | size="icon" |
| 30 | aria-label={t("sidebar.collapse")} |
| 31 | onClick={goBack} |
| 32 | className="h-7 w-7 rounded-lg text-muted-foreground hover:bg-sidebar-accent hover:text-sidebar-foreground" |
| 33 | > |
| 34 | <ChevronLeft className="h-3.5 w-3.5" /> |
| 35 | </Button> |
| 36 | </div> |
| 37 | <div className="flex items-center justify-between px-2 py-2"> |
| 38 | <Button |
| 39 | variant="ghost" |
| 40 | size="icon" |
| 41 | aria-label={t("sidebar.collapse")} |
| 42 | onClick={props.onCollapse} |
| 43 | className="h-7 w-7 rounded-lg text-muted-foreground hover:bg-sidebar-accent hover:text-sidebar-foreground" |
| 44 | > |
| 45 | <PanelLeftClose className="h-3.5 w-3.5" /> |
| 46 | </Button> |
| 47 | </div> |
| 48 | <div className="px-2 pb-2.5"> |
| 49 | <Button |
| 50 | onClick={props.onNewChat} |
| 51 | className="h-8.5 w-full justify-start gap-2 rounded-lg border border-sidebar-border/80 bg-card/25 px-3 text-[13px] font-medium text-sidebar-foreground shadow-none hover:bg-sidebar-accent/80" |
| 52 | variant="outline" |
| 53 | > |
| 54 | <Plus className="h-3.5 w-3.5" /> |
| 55 | {t("sidebar.newChat")} |
| 56 | </Button> |
| 57 | </div> |
| 58 | <Separator className="bg-sidebar-border/70" /> |
| 59 | <div className="flex items-center justify-between px-2.5 py-2 text-[11px] font-medium text-muted-foreground"> |
| 60 | <span>{t("sidebar.recent")}</span> |
| 61 | </div> |
| 62 | <div className="flex-1 overflow-hidden"> |
| 63 | <ChatList |
| 64 | sessions={props.sessions} |
| 65 | activeKey={props.activeKey} |
| 66 | loading={props.loading} |
| 67 | onSelect={props.onSelect} |
| 68 | onRequestDelete={props.onRequestDelete} |
| 69 | /> |
| 70 | </div> |
| 71 | </aside> |
| 72 | ); |
| 73 | } |
| 74 |