前端user/me提升到console/layout

This commit is contained in:
2025-06-18 17:26:50 +08:00
parent acaf14c403
commit af0e9c6522
3 changed files with 41 additions and 30 deletions

View File

@@ -1,3 +1,5 @@
'use client';
import { AppSidebar } from "@/components/app-sidebar" import { AppSidebar } from "@/components/app-sidebar"
import { import {
Breadcrumb, Breadcrumb,
@@ -10,15 +12,45 @@ import {
SidebarProvider, SidebarProvider,
SidebarTrigger, SidebarTrigger,
} from "@/components/ui/sidebar" } from "@/components/ui/sidebar"
import { UserApi } from "@/lib/api";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import useSWR from "swr";
export default function ConsoleMenuLayout({ export default function ConsoleMenuLayout({
children, children,
}: { }: {
children: React.ReactNode children: React.ReactNode
}) { }) {
const router = useRouter();
const { data: user, isLoading, error } = useSWR(
'/api/user/me',
() => UserApi.me(),
{
onError: (error) => {
if (error.statusCode === 401) {
localStorage.removeItem('token');
toast.info('登录凭证已失效,请重新登录');
router.replace('/console/login');
}
}
}
);
if (!isLoading && !error && !user) {
router.replace('/console/login');
localStorage.removeItem('token');
toast.error('账户状态异常,请重新登录');
}
return ( return (
<SidebarProvider> <SidebarProvider>
<AppSidebar /> <AppSidebar user={user} isUserLoading={isLoading} />
<SidebarInset> <SidebarInset>
<header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12"> <header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
<div className="flex items-center gap-2 px-4"> <div className="flex items-center gap-2 px-4">

View File

@@ -24,6 +24,7 @@ import {
SidebarRail, SidebarRail,
} from "@/components/ui/sidebar" } from "@/components/ui/sidebar"
import Link from "next/link" import Link from "next/link"
import { User } from "@/lib/types/user"
// This is sample data. // This is sample data.
const data = { const data = {
user: { user: {
@@ -98,7 +99,7 @@ const data = {
], ],
} }
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) { export function AppSidebar({ user, isUserLoading, ...props }: React.ComponentProps<typeof Sidebar> & { user: User | undefined, isUserLoading: boolean }) {
return ( return (
<Sidebar collapsible="icon" {...props}> <Sidebar collapsible="icon" {...props}>
<SidebarHeader> <SidebarHeader>
@@ -124,7 +125,7 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
<NavMain items={data.navMain} /> <NavMain items={data.navMain} />
</SidebarContent> </SidebarContent>
<SidebarFooter> <SidebarFooter>
<NavUser /> <NavUser user={user} isUserLoading={isUserLoading} />
</SidebarFooter> </SidebarFooter>
<SidebarRail /> <SidebarRail />
</Sidebar> </Sidebar>

View File

@@ -26,40 +26,18 @@ import {
SidebarMenuItem, SidebarMenuItem,
useSidebar, useSidebar,
} from "@/components/ui/sidebar" } from "@/components/ui/sidebar"
import useSWR from "swr" import { authApi } from "@/lib/api"
import { authApi, UserApi } from "@/lib/api"
import { Skeleton } from "./ui/skeleton" import { Skeleton } from "./ui/skeleton"
import { toast } from "sonner" import { toast } from "sonner"
import { useRouter } from "next/navigation" import { useRouter } from "next/navigation"
import { ApiError } from "next/dist/server/api-utils"
import SetPassword from "./nav-user/SetPassword" import SetPassword from "./nav-user/SetPassword"
import { useState } from "react" import { useState } from "react"
import { User } from "@/lib/types/user"
export function NavUser({ }: {}) { export function NavUser({ user, isUserLoading }: { user: User | undefined, isUserLoading: boolean }) {
const { isMobile } = useSidebar(); const { isMobile } = useSidebar();
const router = useRouter(); const router = useRouter();
const { data: user, isLoading, error } = useSWR(
'/api/user/me',
() => UserApi.me(),
{
onError: (error) => {
if (error.statusCode === 401) {
localStorage.removeItem('token');
toast.info('登录凭证已失效,请重新登录');
router.replace('/console/login');
}
}
}
);
if (!isLoading && !error && !user) {
console.log(isLoading, error, user)
router.replace('/console/login');
localStorage.removeItem('token');
toast.error('账户状态异常,请重新登录');
}
async function logout() { async function logout() {
try { try {
await authApi.logout(); await authApi.logout();
@@ -96,7 +74,7 @@ export function NavUser({ }: {}) {
</> </>
} }
{ {
isLoading && <div className="w-full flex items-center gap-2"> isUserLoading && <div className="w-full flex items-center gap-2">
<Skeleton className="h-8 w-8 rounded-full" /> <Skeleton className="h-8 w-8 rounded-full" />
<div className="flex-1 flex flex-col gap-1"> <div className="flex-1 flex flex-col gap-1">
<Skeleton className="w-full h-4" /> <Skeleton className="w-full h-4" />
@@ -128,7 +106,7 @@ export function NavUser({ }: {}) {
</div> </div>
} }
{ {
isLoading && <div className="flex items-center gap-2"> isUserLoading && <div className="flex items-center gap-2">
<Skeleton className="h-8 w-8 rounded-full" /> <Skeleton className="h-8 w-8 rounded-full" />
<div className="flex-1 flex flex-col gap-1"> <div className="flex-1 flex flex-col gap-1">
<Skeleton className="w-full h-4" /> <Skeleton className="w-full h-4" />