添加控制台菜单加载态

This commit is contained in:
2025-06-19 14:55:58 +08:00
parent 304a3073b9
commit 2fece3e558
3 changed files with 34 additions and 31 deletions

View File

@@ -14,6 +14,7 @@ import {
} from "@/components/ui/sidebar"
import { UserApi } from "@/lib/api";
import { useRouter } from "next/navigation";
import { useEffect, useLayoutEffect } from "react";
import { toast } from "sonner";
import useSWR from "swr";
@@ -22,41 +23,22 @@ export default function ConsoleMenuLayout({
}: {
children: React.ReactNode
}) {
const isClientSide = typeof window !== 'undefined';
const router = useRouter();
const getInitialData = () => {
if (!window || !window.localStorage) return null;
const cache = localStorage.getItem(UserApi.USER_ME_CACHE_KEY);
if (!cache) return;
try {
const user = JSON.parse(cache);
if (!user || !user.userId) throw new Error();
return user;
} catch (error) {
localStorage.removeItem(UserApi.USER_ME_CACHE_KEY);
}
return undefined;
}
const { data: user, isLoading, error } = useSWR(
const { data: user, isLoading, error, mutate } = useSWR(
'/api/user/me',
async () => {
const data = await UserApi.me();
localStorage.setItem(UserApi.USER_ME_CACHE_KEY, JSON.stringify(data));
return data;
},
async () => UserApi.me(),
{
onError: (error) => {
if (error.statusCode === 401) {
if (isClientSide) {
localStorage.removeItem('token');
localStorage.removeItem(UserApi.USER_ME_CACHE_KEY);
}
toast.info('登录凭证已失效,请重新登录');
router.replace('/console/login');
}
},
fallbackData: getInitialData(),
revalidateIfStale: false,
revalidateOnFocus: false,
revalidateOnReconnect: false,

View File

@@ -4,6 +4,7 @@ import * as React from "react"
import {
CloudUpload,
Inbox,
LucideIcon,
Mail,
Server,
SquareTerminal,
@@ -34,7 +35,22 @@ export function AppSidebar({ user, isUserLoading, ...props }: React.ComponentPro
email: "m@example.com",
avatar: "/avatars/shadcn.jpg",
},
navMain: [
navMain: null as null | {
title: string
url: string
icon?: LucideIcon
isActive?: boolean
isHidden?: boolean
items?: {
title: string
url: string
isHidden?: boolean
}[]
}[],
}
if (!isUserLoading) {
data.navMain = [
{
title: "网站管理",
url: "/console/web",
@@ -101,7 +117,7 @@ export function AppSidebar({ user, isUserLoading, ...props }: React.ComponentPro
url: "/",
icon: Undo2,
},
],
]
}
return (

View File

@@ -18,13 +18,12 @@ import {
SidebarMenuSubItem,
} from "@/components/ui/sidebar"
import Link from "next/link"
import { usePathname } from "next/navigation"
import { useState, useEffect } from "react"
import { Skeleton } from "./ui/skeleton"
export function NavMain({
items,
}: {
items: {
items: null | {
title: string
url: string
icon?: LucideIcon
@@ -41,7 +40,13 @@ export function NavMain({
<SidebarGroup>
<SidebarGroupLabel></SidebarGroupLabel>
<SidebarMenu>
{items.filter(i => !i.isHidden).map((item) => (
{
!items && Array(5).fill(null).map((_, i) => (
<Skeleton key={i} className="w-full h-7 mt-1" />
))
}
{items && items.filter(i => !i.isHidden).map((item) => (
(item.items && item.items.length > 0)
? (
<Collapsible