refactor: update sidebar and dashboard components with user session integration

This commit is contained in:
javayhu 2025-02-23 21:48:23 +08:00
parent a8f331b2bb
commit b8f66e44ea
9 changed files with 103 additions and 97 deletions

View File

@ -19,7 +19,7 @@ export default function Page() {
<SidebarProvider>
<AppSidebar />
<SidebarInset>
<header className="flex h-16 shrink-0 items-center gap-2">
<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">
<SidebarTrigger className="-ml-1" />
<Separator orientation="vertical" className="mr-2 h-4" />

View File

@ -48,7 +48,7 @@ export default function RootLayout({ children }: PropsWithChildren) {
<Toaster richColors position="top-right" offset={64} />
<TailwindIndicator />
{/* <TailwindIndicator /> */}
</ThemeProvider>
</body>
</html>

View File

@ -1,6 +1,6 @@
"use client"
"use client";
import * as React from "react"
import * as React from "react";
import {
BookOpen,
Bot,
@ -12,12 +12,11 @@ import {
Send,
Settings2,
SquareTerminal,
} from "lucide-react"
import { NavMain } from "@/components/nav-main"
import { NavProjects } from "@/components/nav-projects"
import { NavSecondary } from "@/components/nav-secondary"
import { NavUser } from "@/components/nav-user"
} from "lucide-react";
import { NavMain } from "@/components/nav-main";
import { NavProjects } from "@/components/nav-projects";
import { NavSecondary } from "@/components/nav-secondary";
import { NavUser } from "@/components/nav-user";
import {
Sidebar,
SidebarContent,
@ -26,7 +25,9 @@ import {
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar"
} from "@/components/ui/sidebar";
import { siteConfig } from "@/config/site";
import { Logo } from "./logo";
const data = {
user: {
@ -150,22 +151,20 @@ const data = {
icon: Map,
},
],
}
};
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
return (
<Sidebar variant="inset" {...props}>
<Sidebar collapsible="icon" {...props}>
<SidebarHeader>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton size="lg" asChild>
<a href="#">
<div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
<Command className="size-4" />
</div>
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-semibold">Acme Inc</span>
<span className="truncate text-xs">Enterprise</span>
<a href="/">
<Logo className="size-8" />
<div className="grid flex-1 text-left leading-tight">
<span className="truncate font-semibold text-lg">{siteConfig.name}</span>
{/* <span className="truncate text-xs">{siteConfig.description}</span> */}
</div>
</a>
</SidebarMenuButton>
@ -178,8 +177,8 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
<NavSecondary items={data.navSecondary} className="mt-auto" />
</SidebarContent>
<SidebarFooter>
<NavUser user={data.user} />
<NavUser />
</SidebarFooter>
</Sidebar>
)
);
}

View File

@ -1,12 +1,11 @@
"use client"
import { ChevronRight, type LucideIcon } from "lucide-react"
"use client";
import { ChevronRight, type LucideIcon } from "lucide-react";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible"
} from "@/components/ui/collapsible";
import {
SidebarGroup,
SidebarGroupLabel,
@ -17,21 +16,21 @@ import {
SidebarMenuSub,
SidebarMenuSubButton,
SidebarMenuSubItem,
} from "@/components/ui/sidebar"
} from "@/components/ui/sidebar";
export function NavMain({
items,
}: {
items: {
title: string
url: string
icon: LucideIcon
isActive?: boolean
title: string;
url: string;
icon: LucideIcon;
isActive?: boolean;
items?: {
title: string
url: string
}[]
}[]
title: string;
url: string;
}[];
}[];
}) {
return (
<SidebarGroup>
@ -74,5 +73,5 @@ export function NavMain({
))}
</SidebarMenu>
</SidebarGroup>
)
);
}

View File

@ -1,4 +1,4 @@
"use client"
"use client";
import {
Folder,
@ -6,15 +6,14 @@ import {
Share,
Trash2,
type LucideIcon,
} from "lucide-react"
} from "lucide-react";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
} from "@/components/ui/dropdown-menu";
import {
SidebarGroup,
SidebarGroupLabel,
@ -23,18 +22,18 @@ import {
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from "@/components/ui/sidebar"
} from "@/components/ui/sidebar";
export function NavProjects({
projects,
}: {
projects: {
name: string
url: string
icon: LucideIcon
}[]
name: string;
url: string;
icon: LucideIcon;
}[];
}) {
const { isMobile } = useSidebar()
const { isMobile } = useSidebar();
return (
<SidebarGroup className="group-data-[collapsible=icon]:hidden">
@ -85,5 +84,5 @@ export function NavProjects({
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
)
);
}

View File

@ -1,23 +1,22 @@
import * as React from "react"
import { type LucideIcon } from "lucide-react"
import * as React from "react";
import { type LucideIcon } from "lucide-react";
import {
SidebarGroup,
SidebarGroupContent,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar"
} from "@/components/ui/sidebar";
export function NavSecondary({
items,
...props
}: {
items: {
title: string
url: string
icon: LucideIcon
}[]
title: string;
url: string;
icon: LucideIcon;
}[];
} & React.ComponentPropsWithoutRef<typeof SidebarGroup>) {
return (
<SidebarGroup {...props}>
@ -36,5 +35,5 @@ export function NavSecondary({
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
)
);
}

View File

@ -1,4 +1,4 @@
"use client"
"use client";
import {
BadgeCheck,
@ -7,13 +7,12 @@ import {
CreditCard,
LogOut,
Sparkles,
} from "lucide-react"
} from "lucide-react";
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/components/ui/avatar"
} from "@/components/ui/avatar";
import {
DropdownMenu,
DropdownMenuContent,
@ -22,24 +21,41 @@ import {
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
} from "@/components/ui/dropdown-menu";
import {
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from "@/components/ui/sidebar"
} from "@/components/ui/sidebar";
import { authClient } from "@/lib/auth-client";
import { getInitials } from "@/lib/utils";
import { useRouter } from "next/navigation";
export function NavUser({
user,
}: {
user: {
name: string
email: string
avatar: string
export function NavUser() {
const router = useRouter();
const { isMobile } = useSidebar();
const { data: session, error } = authClient.useSession();
const user = session?.user;
console.log('NavUser, user:', user);
if (!user) {
return null;
}
}) {
const { isMobile } = useSidebar()
const handleSignOut = async () => {
await authClient.signOut({
fetchOptions: {
onSuccess: () => {
console.log("sign out success");
router.push("/");
},
onError: (error) => {
console.error("sign out error:", error);
// TODO: show error message
},
},
});
};
return (
<SidebarMenu>
@ -51,8 +67,8 @@ export function NavUser({
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">CN</AvatarFallback>
<AvatarImage src={user.image || undefined} alt={user.name} />
<AvatarFallback className="rounded-lg">{getInitials(user.name)}</AvatarFallback>
</Avatar>
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-semibold">{user.name}</span>
@ -70,8 +86,8 @@ export function NavUser({
<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">CN</AvatarFallback>
<AvatarImage src={user.image || undefined} alt={user.name} />
<AvatarFallback className="rounded-lg">{getInitials(user.name)}</AvatarFallback>
</Avatar>
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-semibold">{user.name}</span>
@ -81,28 +97,37 @@ export function NavUser({
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<DropdownMenuItem
className="cursor-pointer">
<Sparkles />
Upgrade to Pro
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<DropdownMenuItem
className="cursor-pointer">
<BadgeCheck />
Account
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownMenuItem
className="cursor-pointer">
<CreditCard />
Billing
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownMenuItem
className="cursor-pointer">
<Bell />
Notifications
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<DropdownMenuItem
className="cursor-pointer"
onClick={async (event) => {
event.preventDefault();
handleSignOut();
}}>
<LogOut />
Log out
</DropdownMenuItem>
@ -110,5 +135,5 @@ export function NavUser({
</DropdownMenu>
</SidebarMenuItem>
</SidebarMenu>
)
);
}

View File

@ -17,16 +17,6 @@ export const marketingConfig: MarketingConfig = {
href: "/blog",
icon: "blog",
},
{
title: "Documentation",
href: "/docs",
icon: "docs",
},
{
title: "Login",
href: "/auth/login",
icon: "user",
},
{
title: "Dashboard",
href: "/dashboard",

View File

@ -11,11 +11,6 @@ export const userButtonConfig: UserButtonConfig = {
title: "Settings",
href: "/settings",
icon: "settings",
},
{
title: "Submit Directory",
href: "/submit",
icon: "submit",
},
}
],
};