优化控制台user
This commit is contained in:
@@ -21,7 +21,6 @@ import {
|
|||||||
SidebarMenuItem,
|
SidebarMenuItem,
|
||||||
SidebarRail,
|
SidebarRail,
|
||||||
} from "@/components/ui/sidebar"
|
} from "@/components/ui/sidebar"
|
||||||
import { useRouter } from "next/navigation"
|
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
// This is sample data.
|
// This is sample data.
|
||||||
const data = {
|
const data = {
|
||||||
@@ -105,7 +104,7 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
|||||||
<NavMain items={data.navMain} />
|
<NavMain items={data.navMain} />
|
||||||
</SidebarContent>
|
</SidebarContent>
|
||||||
<SidebarFooter>
|
<SidebarFooter>
|
||||||
<NavUser user={data.user} />
|
<NavUser />
|
||||||
</SidebarFooter>
|
</SidebarFooter>
|
||||||
<SidebarRail />
|
<SidebarRail />
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BadgeCheck,
|
|
||||||
Bell,
|
|
||||||
ChevronsUpDown,
|
ChevronsUpDown,
|
||||||
CreditCard,
|
KeyRound,
|
||||||
LogOut,
|
LogOut,
|
||||||
Sparkles,
|
UserRoundCog,
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -17,7 +15,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
DropdownMenuGroup,
|
|
||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuLabel,
|
DropdownMenuLabel,
|
||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
@@ -29,17 +26,30 @@ import {
|
|||||||
SidebarMenuItem,
|
SidebarMenuItem,
|
||||||
useSidebar,
|
useSidebar,
|
||||||
} from "@/components/ui/sidebar"
|
} from "@/components/ui/sidebar"
|
||||||
|
import useSWR from "swr"
|
||||||
|
import { UserApi } from "@/lib/api"
|
||||||
|
import { Skeleton } from "./ui/skeleton"
|
||||||
|
import { toast } from "sonner"
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
|
|
||||||
|
export function NavUser({ }: {}) {
|
||||||
|
const { isMobile } = useSidebar();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const { data: user, isLoading, error } = useSWR(
|
||||||
|
'/api/user/me',
|
||||||
|
() => UserApi.me(),
|
||||||
|
{
|
||||||
|
onError: (error) => {
|
||||||
|
if (`${error}`.includes('Unauthorized')) {
|
||||||
|
localStorage.removeItem('token');
|
||||||
|
toast.info('登录凭证已失效,请重新登录');
|
||||||
|
router.replace('/console/login');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export function NavUser({
|
|
||||||
user,
|
|
||||||
}: {
|
|
||||||
user: {
|
|
||||||
name: string
|
|
||||||
email: string
|
|
||||||
avatar: string
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
const { isMobile } = useSidebar()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
@@ -50,14 +60,27 @@ export function NavUser({
|
|||||||
size="lg"
|
size="lg"
|
||||||
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||||
>
|
>
|
||||||
<Avatar className="h-8 w-8 rounded-lg">
|
{
|
||||||
<AvatarImage src={user.avatar} alt={user.name} />
|
user && <>
|
||||||
<AvatarFallback className="rounded-lg">U</AvatarFallback>
|
<Avatar className="h-8 w-8 rounded-lg">
|
||||||
</Avatar>
|
<AvatarImage src={user.avatar} />
|
||||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
<AvatarFallback className="rounded-lg">U</AvatarFallback>
|
||||||
<span className="truncate font-medium">{user.name}</span>
|
</Avatar>
|
||||||
<span className="truncate text-xs">{user.email}</span>
|
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||||
</div>
|
<span className="truncate font-medium">{user.nickname}</span>
|
||||||
|
<span className="truncate text-xs">{user.username}</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
isLoading && <div className="w-full flex items-center gap-2">
|
||||||
|
<Skeleton className="h-8 w-8 rounded-full" />
|
||||||
|
<div className="flex-1 flex flex-col gap-1">
|
||||||
|
<Skeleton className="w-full h-4" />
|
||||||
|
<Skeleton className="w-full h-4" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
<ChevronsUpDown className="ml-auto size-4" />
|
<ChevronsUpDown className="ml-auto size-4" />
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
@@ -68,43 +91,42 @@ export function NavUser({
|
|||||||
sideOffset={4}
|
sideOffset={4}
|
||||||
>
|
>
|
||||||
<DropdownMenuLabel className="p-0 font-normal">
|
<DropdownMenuLabel className="p-0 font-normal">
|
||||||
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
|
{
|
||||||
<Avatar className="h-8 w-8 rounded-lg">
|
user &&
|
||||||
<AvatarImage src={user.avatar} alt={user.name} />
|
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
|
||||||
<AvatarFallback className="rounded-lg">U</AvatarFallback>
|
<Avatar className="h-8 w-8 rounded-lg">
|
||||||
</Avatar>
|
<AvatarImage src={user.avatar} />
|
||||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
<AvatarFallback className="rounded-lg">U</AvatarFallback>
|
||||||
<span className="truncate font-medium">{user.name}</span>
|
</Avatar>
|
||||||
<span className="truncate text-xs">{user.email}</span>
|
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||||
|
<span className="truncate font-medium">{user.nickname}</span>
|
||||||
|
<span className="truncate text-xs">{user.username}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
|
{
|
||||||
|
isLoading && <div className="flex items-center gap-2">
|
||||||
|
<Skeleton className="h-8 w-8 rounded-full" />
|
||||||
|
<div className="flex-1 flex flex-col gap-1">
|
||||||
|
<Skeleton className="w-full h-4" />
|
||||||
|
<Skeleton className="w-full h-4" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</DropdownMenuLabel>
|
</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuItem>
|
||||||
<DropdownMenuItem>
|
<UserRoundCog />
|
||||||
<Sparkles />
|
账户信息
|
||||||
Upgrade to Pro
|
</DropdownMenuItem>
|
||||||
</DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
</DropdownMenuGroup>
|
<KeyRound />
|
||||||
<DropdownMenuSeparator />
|
修改密码
|
||||||
<DropdownMenuGroup>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem>
|
|
||||||
<BadgeCheck />
|
|
||||||
Account
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<CreditCard />
|
|
||||||
Billing
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<Bell />
|
|
||||||
Notifications
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuGroup>
|
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
<LogOut />
|
<LogOut />
|
||||||
Log out
|
登出
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export * as authApi from './auth/index';
|
export * as authApi from './auth/index';
|
||||||
export * as verificationApi from './verification/index';
|
export * as verificationApi from './verification/index';
|
||||||
export * as AdminApi from './admin/index';
|
export * as AdminApi from './admin/index';
|
||||||
export * as ResourceApi from './resource/index';
|
export * as ResourceApi from './resource/index';
|
||||||
|
export * as UserApi from './user/index';
|
||||||
1
tone-page-web/lib/api/user/index.ts
Normal file
1
tone-page-web/lib/api/user/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './me';
|
||||||
6
tone-page-web/lib/api/user/me.ts
Normal file
6
tone-page-web/lib/api/user/me.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { User } from "@/lib/types/user";
|
||||||
|
import fetcher from "../fetcher";
|
||||||
|
|
||||||
|
export async function me() {
|
||||||
|
return fetcher<User>('/api/user/me');
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user