WithSidebar.tsx87 lines · main
| 1 | import { ArrowLeft } from 'lucide-react' |
| 2 | import Link from 'next/link' |
| 3 | import { PropsWithChildren, ReactNode } from 'react' |
| 4 | import { cn } from 'ui' |
| 5 | |
| 6 | import type { SidebarSection } from './AccountLayout.types' |
| 7 | import { getActiveKey, toSubMenuSections } from './AccountLayout.utils' |
| 8 | import { SubMenu } from '@/components/ui/ProductMenu/SubMenu' |
| 9 | |
| 10 | interface WithSidebarProps { |
| 11 | title?: string |
| 12 | sections: SidebarSection[] |
| 13 | header?: ReactNode |
| 14 | backToDashboardURL?: string |
| 15 | } |
| 16 | |
| 17 | export const WithSidebar = ({ |
| 18 | title, |
| 19 | header, |
| 20 | children, |
| 21 | sections, |
| 22 | backToDashboardURL, |
| 23 | }: PropsWithChildren<WithSidebarProps>) => { |
| 24 | const noContent = !sections |
| 25 | |
| 26 | return ( |
| 27 | <div className="flex flex-col md:flex-row h-full"> |
| 28 | {!noContent && ( |
| 29 | <SidebarContent |
| 30 | title={title} |
| 31 | header={header} |
| 32 | sections={sections} |
| 33 | backToDashboardURL={backToDashboardURL} |
| 34 | className="hidden md:flex" |
| 35 | /> |
| 36 | )} |
| 37 | <div className="flex flex-1 flex-col"> |
| 38 | <div className="flex-1 grow overflow-y-auto">{children}</div> |
| 39 | </div> |
| 40 | </div> |
| 41 | ) |
| 42 | } |
| 43 | |
| 44 | export const SidebarContent = ({ |
| 45 | header, |
| 46 | sections, |
| 47 | backToDashboardURL, |
| 48 | className, |
| 49 | }: PropsWithChildren<Omit<WithSidebarProps, 'breadcrumbs'>> & { className?: string }) => { |
| 50 | const page = getActiveKey(sections) |
| 51 | const subMenuSections = toSubMenuSections(sections) |
| 52 | |
| 53 | return ( |
| 54 | <> |
| 55 | <div |
| 56 | id="with-sidebar" |
| 57 | className={cn( |
| 58 | 'h-full bg-dash-sidebar flex flex-col justify-between', |
| 59 | 'hide-scrollbar w-full md:w-64 md:border-r border-default', |
| 60 | className |
| 61 | )} |
| 62 | > |
| 63 | <div className="flex-1 flex flex-col"> |
| 64 | {backToDashboardURL && ( |
| 65 | <div className="shrink-0 hidden md:block"> |
| 66 | <div className="flex h-12 max-h-12 items-center border-b px-6 border-default"> |
| 67 | <Link |
| 68 | href={backToDashboardURL} |
| 69 | className="flex text-sm flex-row gap-2 items-center text-foreground-lighter focus-visible:text-foreground hover:text-foreground" |
| 70 | > |
| 71 | <ArrowLeft strokeWidth={1.5} size={16} /> |
| 72 | Back to dashboard |
| 73 | </Link> |
| 74 | </div> |
| 75 | </div> |
| 76 | )} |
| 77 | {header && header} |
| 78 | <div className="flex-1 overflow-auto"> |
| 79 | <div className="flex flex-col"> |
| 80 | <SubMenu sections={subMenuSections} page={page} /> |
| 81 | </div> |
| 82 | </div> |
| 83 | </div> |
| 84 | </div> |
| 85 | </> |
| 86 | ) |
| 87 | } |