60 lines
2.2 KiB
TypeScript
60 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { useApp } from "@/lib/app-context";
|
|
import { TagFilter } from "./tag-filter";
|
|
import { SessionList } from "./session-list";
|
|
|
|
export function Sidebar() {
|
|
const { sidebarCollapsed, setSidebarCollapsed } = useApp();
|
|
|
|
return (
|
|
<>
|
|
{/* 移动端遮罩 */}
|
|
{!sidebarCollapsed && (
|
|
<div
|
|
className="fixed inset-0 z-30 bg-black/60 sidebar-overlay md:hidden"
|
|
onClick={() => setSidebarCollapsed(true)}
|
|
/>
|
|
)}
|
|
|
|
<aside
|
|
className={`
|
|
fixed inset-y-0 left-0 z-40 w-[280px]
|
|
md:relative md:inset-auto md:z-auto
|
|
flex-shrink-0 border-r border-[var(--border)]
|
|
bg-[var(--bg-secondary)]/80 backdrop-blur-xl
|
|
flex flex-col transition-transform duration-250 ease-in-out
|
|
${sidebarCollapsed ? "-translate-x-full md:-translate-x-0 md:w-0 md:border-r-0" : "translate-x-0 md:w-[280px]"}
|
|
${sidebarCollapsed ? "md:overflow-hidden" : ""}
|
|
`}
|
|
>
|
|
<div className="flex items-center justify-between px-4 py-3 border-b border-[var(--border)]">
|
|
<div className="flex items-center gap-2.5">
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" strokeWidth="2"
|
|
style={{ filter: "drop-shadow(0 0 4px rgba(77, 184, 164, 0.35))" }}>
|
|
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" />
|
|
</svg>
|
|
<span className="text-sm font-semibold text-[var(--text-primary)]">
|
|
对话
|
|
</span>
|
|
</div>
|
|
<button
|
|
onClick={() => setSidebarCollapsed(true)}
|
|
className="text-[var(--text-secondary)] hover:text-[var(--accent)]
|
|
transition-colors cursor-pointer p-1 rounded-md
|
|
hover:bg-[var(--accent)]/5"
|
|
title="折叠侧边栏"
|
|
>
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
<path d="M11 17l-5-5 5-5M18 17l-5-5 5-5" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<TagFilter />
|
|
<SessionList />
|
|
</aside>
|
|
</>
|
|
);
|
|
}
|