11import { Link , Outlet } from "@tanstack/react-router" ;
22
3+ import { isAuthorizationRequired } from "@/components/shared/Authentication/helpers" ;
4+ import { TopBarAuthentication } from "@/components/shared/Authentication/TopBarAuthentication" ;
35import { Icon , type IconName } from "@/components/ui/icon" ;
46import { BlockStack , InlineStack } from "@/components/ui/layout" ;
57import { Heading , Text } from "@/components/ui/typography" ;
68import { cn } from "@/lib/utils" ;
9+ import { DOCUMENTATION_URL } from "@/utils/constants" ;
710
811interface SidebarItem {
912 to : string ;
@@ -19,7 +22,15 @@ const SIDEBAR_ITEMS: SidebarItem[] = [
1922 { to : "/dashboard/recently-viewed" , label : "Recently Viewed" , icon : "Clock" } ,
2023] ;
2124
25+ const navItemClass = ( isActive : boolean ) =>
26+ cn (
27+ "flex items-center gap-2 w-full px-3 py-2 rounded-md text-sm cursor-pointer hover:bg-accent" ,
28+ isActive && "bg-accent font-medium" ,
29+ ) ;
30+
2231export function DashboardLayout ( ) {
32+ const requiresAuthorization = isAuthorizationRequired ( ) ;
33+
2334 return (
2435 < div className = "w-full px-8 py-6" >
2536 < BlockStack gap = "6" >
@@ -36,31 +47,53 @@ export function DashboardLayout() {
3647 </ InlineStack >
3748
3849 < InlineStack gap = "8" blockAlign = "start" className = "w-full min-h-100" >
39- < BlockStack
40- gap = "1"
41- className = "w-48 shrink-0 border-r border-border pr-4"
42- >
43- { SIDEBAR_ITEMS . map ( ( item ) => (
44- < Link
45- key = { item . to }
46- to = { item . to }
47- className = "w-full"
48- activeProps = { { className : "is-active" } }
50+ { /* Sidebar */ }
51+ < div className = "w-48 shrink-0 border-r border-border pr-4 flex flex-col justify-between self-stretch" >
52+ { /* Top nav */ }
53+ < BlockStack gap = "1" >
54+ { SIDEBAR_ITEMS . map ( ( item ) => (
55+ < Link
56+ key = { item . to }
57+ to = { item . to }
58+ className = "w-full"
59+ activeProps = { { className : "is-active" } }
60+ >
61+ { ( { isActive } ) => (
62+ < div className = { navItemClass ( isActive ) } >
63+ < Icon name = { item . icon } size = "sm" />
64+ < Text size = "sm" > { item . label } </ Text >
65+ </ div >
66+ ) }
67+ </ Link >
68+ ) ) }
69+ </ BlockStack >
70+
71+ { /* Bottom utilities */ }
72+ < BlockStack gap = "1" className = "border-t border-border pt-3" >
73+ < a
74+ href = { DOCUMENTATION_URL }
75+ target = "_blank"
76+ rel = "noopener noreferrer"
77+ className = { navItemClass ( false ) }
4978 >
79+ < Icon name = "BookOpen" size = "sm" />
80+ < Text size = "sm" > Docs</ Text >
81+ </ a >
82+ < Link to = "/settings/backend" className = "w-full" >
5083 { ( { isActive } ) => (
51- < div
52- className = { cn (
53- "flex items-center gap-2 w-full px-3 py-2 rounded-md text-sm cursor-pointer hover:bg-accent" ,
54- isActive && "bg-accent font-medium" ,
55- ) }
56- >
57- < Icon name = { item . icon } size = "sm" />
58- < Text size = "sm" > { item . label } </ Text >
84+ < div className = { navItemClass ( isActive ) } >
85+ < Icon name = "Settings" size = "sm" />
86+ < Text size = "sm" > Settings</ Text >
5987 </ div >
6088 ) }
6189 </ Link >
62- ) ) }
63- </ BlockStack >
90+ { requiresAuthorization && (
91+ < div className = "px-3 py-2" >
92+ < TopBarAuthentication />
93+ </ div >
94+ ) }
95+ </ BlockStack >
96+ </ div >
6497
6598 < BlockStack className = "flex-1 min-w-0" >
6699 < Outlet />
0 commit comments