Refactor Sidebar component for improved layout and user interaction

Updated the Sidebar component to enhance the collapsed state behavior, including a new button for profile navigation with improved styling and animations. Removed the user profile item and adjusted the layout for better responsiveness. Added a ChevronRight icon for visual indication of the profile button and refined the toggle button for collapsing the sidebar.
This commit is contained in:
Xin Wang
2026-06-05 15:13:58 +08:00
parent b74a10b471
commit 4206e29550

View File

@@ -4,11 +4,11 @@ import {
Bot,
Boxes,
ChevronLeft,
ChevronRight,
Clock3,
FileText,
Home,
PlayCircle,
User,
Video,
Workflow,
} from "lucide-react";
@@ -31,7 +31,6 @@ const mainItems: Array<{
{ key: "history", label: "历史记录", icon: Clock3 },
{ key: "test", label: "测试助手", icon: PlayCircle },
{ key: "workflow", label: "工作流", icon: Workflow },
{ key: "profile", label: "个人中心", icon: User },
];
const assistantSubItems: Array<{
@@ -94,16 +93,25 @@ export function Sidebar({
/>
<div className="pt-2">
<div
className={[
"flex h-11 w-full items-center gap-3 rounded-full px-3 text-sm",
assistantActive ? "text-foreground" : "text-muted-foreground",
collapsed ? "justify-center" : "",
].join(" ")}
>
<Bot size={18} />
{!collapsed && <span className="font-medium"></span>}
</div>
{collapsed ? (
<div
className="flex h-8 items-center justify-center"
aria-hidden="true"
title="创建助手"
>
<span className="h-px w-6 rounded-full bg-hairline-strong" />
</div>
) : (
<div
className={[
"flex h-11 w-full items-center gap-3 rounded-full px-3 text-sm",
assistantActive ? "text-foreground" : "text-muted-foreground",
].join(" ")}
>
<Bot size={18} />
<span className="font-medium"></span>
</div>
)}
<div
className={[
@@ -139,15 +147,78 @@ export function Sidebar({
</div>
</nav>
<div className="border-t border-sidebar-border p-3">
<div className="space-y-2 border-t border-sidebar-border p-3">
{/* 个人中心 */}
<button
onClick={() => onNavigate("profile")}
title={collapsed ? "个人中心 · 管理员" : undefined}
className={[
"group relative flex w-full items-center overflow-hidden rounded-2xl border py-2 text-left transition-[background-color,color,border-color,box-shadow,transform] duration-200 active:scale-[0.98]",
active === "profile"
? "border-sidebar-border bg-sidebar-accent text-sidebar-accent-foreground shadow-sm"
: "border-transparent text-muted-foreground hover:border-sidebar-border hover:bg-sidebar-accent/60 hover:text-foreground hover:shadow-sm",
collapsed ? "justify-center gap-0 px-0" : "gap-3 px-2.5",
].join(" ")}
>
<span className="relative shrink-0">
<span
className="flex h-9 w-9 items-center justify-center rounded-full text-sm font-medium text-on-primary shadow-sm transition-transform duration-200 group-hover:scale-105"
style={{
backgroundColor: "var(--primary)",
backgroundImage:
"radial-gradient(circle at 30% 20%, color-mix(in srgb, var(--gradient-sky) 70%, transparent), transparent 60%), radial-gradient(circle at 80% 90%, color-mix(in srgb, var(--gradient-lavender) 65%, transparent), transparent 55%)",
}}
>
<span style={{ color: "var(--primary-foreground)" }}></span>
</span>
<span
className="absolute -bottom-0.5 -right-0.5 h-3 w-3 rounded-full border-2 border-sidebar"
style={{ backgroundColor: "var(--success)" }}
/>
</span>
<span
className={[
"min-w-0 flex-1 overflow-hidden transition-all duration-300 ease-[cubic-bezier(0.22,1,0.36,1)]",
collapsed ? "w-0 opacity-0 -translate-x-2" : "opacity-100 translate-x-0",
].join(" ")}
>
<span className="block truncate text-sm font-medium text-foreground">
</span>
<span className="block truncate text-xs text-muted-soft"></span>
</span>
<ChevronRight
size={16}
className={[
"shrink-0 text-muted-soft transition-all duration-200 group-hover:translate-x-0.5 group-hover:text-foreground",
collapsed ? "hidden" : "opacity-0 group-hover:opacity-100",
].join(" ")}
/>
</button>
{/* 收起 / 展开侧栏 */}
<button
onClick={onToggle}
className="flex h-10 w-full items-center justify-center rounded-full border border-hairline-strong text-muted-foreground transition-[background-color,color,border-color,transform] duration-200 hover:bg-surface-strong hover:text-foreground active:scale-95"
title={collapsed ? "展开侧栏" : "收起侧栏"}
className={[
"group flex h-10 w-full items-center gap-2 overflow-hidden rounded-full border border-hairline-strong text-sm text-muted-foreground transition-[background-color,color,border-color,transform] duration-200 hover:bg-surface-strong hover:text-foreground active:scale-[0.98]",
collapsed ? "justify-center px-0" : "justify-between px-3.5",
].join(" ")}
>
<span
className={[
"min-w-0 truncate transition-all duration-300 ease-[cubic-bezier(0.22,1,0.36,1)]",
collapsed ? "w-0 opacity-0 -translate-x-2" : "opacity-100 translate-x-0",
].join(" ")}
>
</span>
<ChevronLeft
size={18}
className={[
"transition-transform duration-300 ease-[cubic-bezier(0.22,1,0.36,1)]",
"shrink-0 transition-transform duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:scale-110",
collapsed ? "rotate-180" : "rotate-0",
].join(" ")}
/>
@@ -177,12 +248,12 @@ function NavButton({
onClick={onClick}
title={collapsed ? label : undefined}
className={[
"group mt-1 flex w-full items-center gap-3 overflow-hidden rounded-full px-3 text-sm transition-[background-color,color,transform] duration-200 hover:translate-x-0.5 active:scale-[0.98]",
"group mt-1 flex w-full items-center overflow-hidden rounded-full text-sm transition-[background-color,color,transform] duration-200 active:scale-[0.98]",
small ? "h-10" : "h-11",
active
? "bg-sidebar-accent text-sidebar-accent-foreground font-medium"
: "text-muted-foreground hover:bg-sidebar-accent/60 hover:text-foreground",
collapsed ? "justify-center" : "",
collapsed ? "justify-center gap-0 px-0" : "gap-3 px-3 hover:translate-x-0.5",
].join(" ")}
>
<Icon