feat(dashboard): integrate SessionProvider and update NavUser for session data

- Integrated `SessionProvider` from `next-auth/react` to manage user sessions.
- Updated `AppSidebar` to use `SessionProvider` and reflect user data.
- Modified `NavUser` to display user info based on session, with default fallback.
This commit is contained in:
ngc2207 2024-12-09 00:37:35 +08:00
parent 474c71bf96
commit 5f427a5032
3 changed files with 124 additions and 83 deletions

View File

@ -11,6 +11,7 @@ import {
BreadcrumbPage, BreadcrumbPage,
BreadcrumbSeparator, BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"; } from "@/components/ui/breadcrumb";
import { SessionProvider } from "next-auth/react";
import { AppSidebar } from "@/components/app-sidebar"; import { AppSidebar } from "@/components/app-sidebar";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
@ -18,6 +19,7 @@ export default function DashboardLayout({
children, children,
}: Readonly<{ children: React.ReactNode }>) { }: Readonly<{ children: React.ReactNode }>) {
return ( return (
<SessionProvider>
<SidebarProvider> <SidebarProvider>
<AppSidebar /> <AppSidebar />
<SidebarInset> <SidebarInset>
@ -43,5 +45,6 @@ export default function DashboardLayout({
{children} {children}
</SidebarInset> </SidebarInset>
</SidebarProvider> </SidebarProvider>
</SessionProvider>
); );
} }

View File

@ -29,9 +29,9 @@ import { NavSecondary } from "@/components/nav-secondary";
const data = { const data = {
user: { user: {
name: "shadcn", name: "gitea",
email: "m@example.com", email: "about@gitea.com",
avatar: "/avatars/shadcn.jpg", avatar: "/gitea.svg",
}, },
navMain: [ navMain: [
{ {

View File

@ -1,31 +1,41 @@
"use client"; "use client";
import { import {
BadgeCheck,
Bell, Bell,
ChevronsUpDown, LogIn,
CreditCard,
LogOut, LogOut,
Sparkles, Sparkles,
BadgeCheck,
CreditCard,
ChevronsUpDown,
} from "lucide-react"; } from "lucide-react";
import { useMemo } from "react";
import { import {
useSidebar,
SidebarMenu, SidebarMenu,
SidebarMenuButton, SidebarMenuButton,
SidebarMenuItem, SidebarMenuItem,
useSidebar,
} from "@/components/ui/sidebar"; } from "@/components/ui/sidebar";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem, DropdownMenuItem,
DropdownMenuGroup,
DropdownMenuLabel, DropdownMenuLabel,
DropdownMenuSeparator, DropdownMenuContent,
DropdownMenuTrigger, DropdownMenuTrigger,
DropdownMenuSeparator,
} from "@/components/ui/dropdown-menu"; } from "@/components/ui/dropdown-menu";
import { useSession } from "next-auth/react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
export function NavUser({ const UserAvatar = ({ src, alt }: { src: string; alt: string }) => (
<Avatar className="h-8 w-8 rounded-lg">
<AvatarImage src={src} alt={alt} />
<AvatarFallback className="rounded-lg">CN</AvatarFallback>
</Avatar>
);
export const NavUser = ({
user, user,
}: { }: {
user: { user: {
@ -33,8 +43,20 @@ export function NavUser({
email: string; email: string;
avatar: string; avatar: string;
}; };
}) { }) => {
const { isMobile } = useSidebar(); const { isMobile } = useSidebar();
const { data: session } = useSession();
const currentUser = useMemo(() => {
if (session?.user) {
return {
name: session.user.name ?? "Unknown",
email: session.user.email ?? "Unknown",
avatar: session.user.image ?? "/gitea.svg",
};
}
return user;
}, [session, user]);
return ( return (
<SidebarMenu> <SidebarMenu>
@ -45,13 +67,12 @@ 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"> <UserAvatar src={currentUser.avatar} alt={currentUser.name} />
<AvatarImage src={user.avatar} alt={user.name} />
<AvatarFallback className="rounded-lg">CN</AvatarFallback>
</Avatar>
<div className="grid flex-1 text-left text-sm leading-tight"> <div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-semibold">{user.name}</span> <span className="truncate font-semibold">
<span className="truncate text-xs">{user.email}</span> {currentUser.name}
</span>
<span className="truncate text-xs">{currentUser.email}</span>
</div> </div>
<ChevronsUpDown className="ml-auto size-4" /> <ChevronsUpDown className="ml-auto size-4" />
</SidebarMenuButton> </SidebarMenuButton>
@ -62,15 +83,21 @@ export function NavUser({
align="end" align="end"
sideOffset={4} sideOffset={4}
> >
{session?.user ? (
<>
<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"> <div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
<Avatar className="h-8 w-8 rounded-lg"> <UserAvatar
<AvatarImage src={user.avatar} alt={user.name} /> src={currentUser.avatar}
<AvatarFallback className="rounded-lg">CN</AvatarFallback> alt={currentUser.name}
</Avatar> />
<div className="grid flex-1 text-left text-sm leading-tight"> <div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-semibold">{user.name}</span> <span className="truncate font-semibold">
<span className="truncate text-xs">{user.email}</span> {currentUser.name}
</span>
<span className="truncate text-xs">
{currentUser.email}
</span>
</div> </div>
</div> </div>
</DropdownMenuLabel> </DropdownMenuLabel>
@ -97,13 +124,24 @@ export function NavUser({
</DropdownMenuItem> </DropdownMenuItem>
</DropdownMenuGroup> </DropdownMenuGroup>
<DropdownMenuSeparator /> <DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem> <DropdownMenuItem>
<LogOut /> <LogOut />
Log out Log out
</DropdownMenuItem> </DropdownMenuItem>
</DropdownMenuGroup>
</>
) : (
<DropdownMenuGroup>
<DropdownMenuItem>
<LogIn />
Log in
</DropdownMenuItem>
</DropdownMenuGroup>
)}
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
</SidebarMenuItem> </SidebarMenuItem>
</SidebarMenu> </SidebarMenu>
); );
} };