WithSidebar.tsx 2.5 KB

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