优化控制台user
This commit is contained in:
@@ -21,7 +21,6 @@ import {
|
||||
SidebarMenuItem,
|
||||
SidebarRail,
|
||||
} from "@/components/ui/sidebar"
|
||||
import { useRouter } from "next/navigation"
|
||||
import Link from "next/link"
|
||||
// This is sample data.
|
||||
const data = {
|
||||
@@ -105,7 +104,7 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
<NavMain items={data.navMain} />
|
||||
</SidebarContent>
|
||||
<SidebarFooter>
|
||||
<NavUser user={data.user} />
|
||||
<NavUser />
|
||||
</SidebarFooter>
|
||||
<SidebarRail />
|
||||
</Sidebar>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
"use client"
|
||||
|
||||
import {
|
||||
BadgeCheck,
|
||||
Bell,
|
||||
ChevronsUpDown,
|
||||
CreditCard,
|
||||
KeyRound,
|
||||
LogOut,
|
||||
Sparkles,
|
||||
UserRoundCog,
|
||||
} from "lucide-react"
|
||||
|
||||
import {
|
||||
@@ -17,7 +15,6 @@ import {
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuGroup,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
@@ -29,17 +26,30 @@ import {
|
||||
SidebarMenuItem,
|
||||
useSidebar,
|
||||
} 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 (
|
||||
<SidebarMenu>
|
||||
@@ -50,14 +60,27 @@ export function NavUser({
|
||||
size="lg"
|
||||
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} />
|
||||
<AvatarFallback className="rounded-lg">U</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<span className="truncate font-medium">{user.name}</span>
|
||||
<span className="truncate text-xs">{user.email}</span>
|
||||
</div>
|
||||
{
|
||||
user && <>
|
||||
<Avatar className="h-8 w-8 rounded-lg">
|
||||
<AvatarImage src={user.avatar} />
|
||||
<AvatarFallback className="rounded-lg">U</AvatarFallback>
|
||||
</Avatar>
|
||||
<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>
|
||||
</>
|
||||
}
|
||||
{
|
||||
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" />
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
@@ -68,43 +91,42 @@ export function NavUser({
|
||||
sideOffset={4}
|
||||
>
|
||||
<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">
|
||||
<AvatarImage src={user.avatar} alt={user.name} />
|
||||
<AvatarFallback className="rounded-lg">U</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<span className="truncate font-medium">{user.name}</span>
|
||||
<span className="truncate text-xs">{user.email}</span>
|
||||
{
|
||||
user &&
|
||||
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
|
||||
<Avatar className="h-8 w-8 rounded-lg">
|
||||
<AvatarImage src={user.avatar} />
|
||||
<AvatarFallback className="rounded-lg">U</AvatarFallback>
|
||||
</Avatar>
|
||||
<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>
|
||||
}
|
||||
{
|
||||
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>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem>
|
||||
<Sparkles />
|
||||
Upgrade to Pro
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem>
|
||||
<BadgeCheck />
|
||||
Account
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<CreditCard />
|
||||
Billing
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Bell />
|
||||
Notifications
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
<DropdownMenuItem>
|
||||
<UserRoundCog />
|
||||
账户信息
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<KeyRound />
|
||||
修改密码
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>
|
||||
<LogOut />
|
||||
Log out
|
||||
登出
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
@@ -2,3 +2,4 @@ export * as authApi from './auth/index';
|
||||
export * as verificationApi from './verification/index';
|
||||
export * as AdminApi from './admin/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