返回 JoyAI-Echo
Sidebar.tsx
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
74 lines Plain Text