This commit is contained in:
27942
2026-01-28 16:00:56 +08:00
parent 03117098c7
commit 6262a67f46
116 changed files with 7821 additions and 5657 deletions

View File

@@ -1,4 +1,4 @@
import { useAuth } from "@/_core/hooks/useAuth";
import { useAuth } from "@/hooks/useAuth";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import {
DropdownMenu,
@@ -20,15 +20,19 @@ import {
useSidebar,
} from "@/components/ui/sidebar";
import { useIsMobile } from "@/hooks/useMobile";
import { LayoutDashboard, LogOut, PanelLeft, Users, Heart, ShieldCheck } from "lucide-react";
import { CSSProperties, useEffect, useRef, useState } from "react";
import { LayoutDashboard, LogOut, PanelLeft, Users, Heart, ShieldCheck, Loader2, Settings, Home } from "lucide-react";
import { CSSProperties, useCallback, useEffect, useRef, useState } from "react";
import { useLocation } from "wouter";
import { DashboardLayoutSkeleton } from './DashboardLayoutSkeleton';
import { Button } from "./ui/button";
import { toast } from "sonner";
import { getErrorCopy } from "@/lib/i18n/errorMessages";
const menuItems = [
{ icon: Home, label: "返回首页", path: "/" },
{ icon: LayoutDashboard, label: "个人中心", path: "/dashboard" },
{ icon: Heart, label: "我的收藏", path: "/favorites" },
{ icon: Settings, label: "账号设置", path: "/settings" },
];
const adminMenuItems = [
@@ -45,11 +49,27 @@ export default function DashboardLayout({
}: {
children: React.ReactNode;
}) {
const [, navigate] = useLocation();
const [isLoggingOut, setIsLoggingOut] = useState(false);
const [sidebarWidth, setSidebarWidth] = useState(() => {
const saved = localStorage.getItem(SIDEBAR_WIDTH_KEY);
return saved ? parseInt(saved, 10) : DEFAULT_WIDTH;
});
const { loading, user } = useAuth();
const { loading, user, logout } = useAuth();
const handleLogout = useCallback(async () => {
setIsLoggingOut(true);
try {
await logout();
toast.success("已退出登录");
navigate("/");
} catch (error: unknown) {
const { title, description } = getErrorCopy(error, { context: "auth.logout" });
toast.error(title, { description });
} finally {
setIsLoggingOut(false);
}
}, [logout, navigate]);
useEffect(() => {
localStorage.setItem(SIDEBAR_WIDTH_KEY, sidebarWidth.toString());
@@ -93,7 +113,11 @@ export default function DashboardLayout({
} as CSSProperties
}
>
<DashboardLayoutContent setSidebarWidth={setSidebarWidth}>
<DashboardLayoutContent
setSidebarWidth={setSidebarWidth}
handleLogout={handleLogout}
isLoggingOut={isLoggingOut}
>
{children}
</DashboardLayoutContent>
</SidebarProvider>
@@ -103,13 +127,17 @@ export default function DashboardLayout({
type DashboardLayoutContentProps = {
children: React.ReactNode;
setSidebarWidth: (width: number) => void;
handleLogout: () => void;
isLoggingOut: boolean;
};
function DashboardLayoutContent({
children,
setSidebarWidth,
handleLogout,
isLoggingOut,
}: DashboardLayoutContentProps) {
const { user, logout } = useAuth();
const { user } = useAuth();
const [location, setLocation] = useLocation();
const { state, toggleSidebar } = useSidebar();
const isCollapsed = state === "collapsed";
@@ -251,11 +279,16 @@ function DashboardLayoutContent({
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-48">
<DropdownMenuItem
onClick={logout}
onClick={handleLogout}
disabled={isLoggingOut}
className="cursor-pointer text-destructive focus:text-destructive"
>
<LogOut className="mr-2 h-4 w-4" />
<span>Sign out</span>
{isLoggingOut ? (
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
) : (
<LogOut className="mr-2 h-4 w-4" />
)}
<span>{isLoggingOut ? "退出中..." : "退出登录"}</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>