| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- import { createContext, useContext, useEffect, useState } from 'react'
- import { getCookie, setCookie } from '@/lib/cookies'
- export type Collapsible = 'offcanvas' | 'icon' | 'none'
- export type Variant = 'inset' | 'sidebar' | 'floating'
- // Cookie constants following the pattern from sidebar.tsx
- const LAYOUT_COLLAPSIBLE_COOKIE_NAME = 'layout_collapsible'
- const LAYOUT_VARIANT_COOKIE_NAME = 'layout_variant'
- const LAYOUT_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 // 7 days
- // Default values
- const DEFAULT_VARIANT = 'inset'
- const DEFAULT_COLLAPSIBLE = 'icon'
- interface LayoutContextType {
- resetLayout: () => void
- defaultCollapsible: Collapsible
- collapsible: Collapsible
- setCollapsible: (collapsible: Collapsible) => void
- defaultVariant: Variant
- variant: Variant
- setVariant: (variant: Variant) => void
- }
- const LayoutContext = createContext<LayoutContextType>({
- resetLayout: () => {},
- defaultCollapsible: DEFAULT_COLLAPSIBLE,
- collapsible: DEFAULT_COLLAPSIBLE,
- setCollapsible: () => {},
- defaultVariant: DEFAULT_VARIANT,
- variant: DEFAULT_VARIANT,
- setVariant: () => {},
- })
- interface LayoutProviderProps {
- children: React.ReactNode
- }
- export function LayoutProvider({ children }: LayoutProviderProps) {
- const [collapsible, setCollapsible] = useState<Collapsible>(
- () =>
- (getCookie(LAYOUT_COLLAPSIBLE_COOKIE_NAME) as Collapsible) ||
- DEFAULT_COLLAPSIBLE
- )
- const [variant, setVariant] = useState<Variant>(
- () => (getCookie(LAYOUT_VARIANT_COOKIE_NAME) as Variant) || DEFAULT_VARIANT
- )
- useEffect(() => {
- setCookie(
- LAYOUT_COLLAPSIBLE_COOKIE_NAME,
- collapsible,
- LAYOUT_COOKIE_MAX_AGE
- )
- }, [collapsible])
- useEffect(() => {
- setCookie(LAYOUT_VARIANT_COOKIE_NAME, variant, LAYOUT_COOKIE_MAX_AGE)
- }, [variant])
- const resetLayout = () => {
- setCollapsible(DEFAULT_COLLAPSIBLE)
- setVariant(DEFAULT_VARIANT)
- }
- return (
- <LayoutContext
- value={{
- defaultCollapsible: DEFAULT_COLLAPSIBLE,
- defaultVariant: DEFAULT_VARIANT,
- resetLayout,
- collapsible,
- setCollapsible,
- variant,
- setVariant,
- }}
- >
- {children}
- </LayoutContext>
- )
- }
- // Define the hook for the provider
- // eslint-disable-next-line react-refresh/only-export-components
- export function useLayout() {
- const context = useContext(LayoutContext)
- if (!context) {
- throw new Error('useLayout must be used within a LayoutProvider')
- }
- return context
- }
|