@scripso-homepad/ui 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/web/utils/cn.ts","../../src/web/icons/BellIcon.tsx","../../src/web/icons/BuildingIcon.tsx","../../src/web/hooks/useOnClickOutside.ts","../../src/web/layout/BuildingSelect.tsx","../../src/web/layout/AppHeader.tsx","../../src/web/hooks/useMediaQuery.ts","../../src/web/layout/SidebarNavItem.tsx","../../src/web/layout/SidebarUserCard.tsx","../../src/web/layout/Sidebar.tsx","../../src/web/layout/SidebarMobileHeader.tsx","../../src/web/layout/DashboardLayout.tsx"],"names":["jsx","jsxs","useState","useEffect","useCallback","useRef","Fragment"],"mappings":"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","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import { cn } from '../utils/cn';\n\ntype BellIconProps = {\n className?: string;\n};\n\nexport function BellIcon({ className }: BellIconProps) {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden\n className={cn('shrink-0', className)}\n >\n <path\n d=\"M8.58333 17.4998C8.72282 17.7535 8.92787 17.9651 9.17708 18.1125C9.42628 18.2599 9.71048 18.3376 10 18.3376C10.2895 18.3376 10.5737 18.2599 10.8229 18.1125C11.0721 17.9651 11.2772 17.7535 11.4167 17.4998M5 6.6665C5 5.34042 5.52678 4.06865 6.46447 3.13097C7.40215 2.19329 8.67392 1.6665 10 1.6665C11.3261 1.6665 12.5979 2.19329 13.5355 3.13097C14.4732 4.06865 15 5.34042 15 6.6665C15 12.4998 17.5 14.1665 17.5 14.1665H2.5C2.5 14.1665 5 12.4998 5 6.6665Z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n","import { cn } from '../utils/cn';\n\ntype BuildingIconProps = {\n className?: string;\n};\n\nexport function BuildingIcon({ className }: BuildingIconProps) {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden\n className={cn('shrink-0', className)}\n >\n <path\n d=\"M10 12h4\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M10 8h4\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 21v-3a2 2 0 0 0-4 0v3\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M6 10H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M6 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n","import { useEffect, type RefObject } from 'react';\n\nexport function useOnClickOutside<T extends HTMLElement>(\n ref: RefObject<T | null>,\n handler: () => void,\n enabled = true,\n) {\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n const onPointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!ref.current || !target || ref.current.contains(target)) {\n return;\n }\n\n handler();\n };\n\n document.addEventListener('mousedown', onPointerDown);\n document.addEventListener('touchstart', onPointerDown);\n\n return () => {\n document.removeEventListener('mousedown', onPointerDown);\n document.removeEventListener('touchstart', onPointerDown);\n };\n }, [enabled, handler, ref]);\n}\n","import { ChevronsUpDown } from 'lucide-react';\nimport { useCallback, useId, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\n\nimport { BuildingIcon } from '../icons/BuildingIcon';\nimport { useOnClickOutside } from '../hooks/useOnClickOutside';\nimport { cn } from '../utils/cn';\nimport type { AdminBuildingOption, AdminHeaderLabels } from './types';\n\nexport type BuildingSelectProps = {\n options: AdminBuildingOption[];\n value: string;\n labels: Pick<AdminHeaderLabels, 'selectBuilding'>;\n onChange?: (buildingId: string) => void;\n disabled?: boolean;\n className?: string;\n menuClassName?: string;\n buildingIcon?: ReactNode;\n chevronIcon?: ReactNode;\n};\n\nexport function BuildingSelect({\n options,\n value,\n labels,\n onChange,\n disabled = false,\n className,\n menuClassName,\n buildingIcon,\n chevronIcon,\n}: BuildingSelectProps) {\n const [open, setOpen] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const rootRef = useRef<HTMLDivElement>(null);\n const listboxId = useId();\n\n const selectedOption = options.find((option) => option.value === value);\n const displayLabel = selectedOption?.label ?? labels.selectBuilding;\n const selectableOptions = options.filter((option) => !option.disabled);\n\n const closeMenu = useCallback(() => {\n setOpen(false);\n setHighlightedIndex(-1);\n }, []);\n\n const openMenu = useCallback(() => {\n if (disabled || selectableOptions.length === 0) {\n return;\n }\n\n const selectedIndex = selectableOptions.findIndex((option) => option.value === value);\n setHighlightedIndex(selectedIndex >= 0 ? selectedIndex : 0);\n setOpen(true);\n }, [disabled, selectableOptions, value]);\n\n const selectOption = useCallback(\n (option: AdminBuildingOption) => {\n if (option.disabled) {\n return;\n }\n\n onChange?.(option.value);\n closeMenu();\n },\n [closeMenu, onChange],\n );\n\n useOnClickOutside(rootRef, closeMenu, open);\n\n const handleTriggerKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (disabled) {\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n case 'Enter':\n case ' ':\n event.preventDefault();\n openMenu();\n break;\n case 'Escape':\n closeMenu();\n break;\n default:\n break;\n }\n };\n\n const handleListKeyDown = (event: KeyboardEvent<HTMLUListElement>) => {\n if (!open || selectableOptions.length === 0) {\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n setHighlightedIndex((current) => (current + 1) % selectableOptions.length);\n break;\n case 'ArrowUp':\n event.preventDefault();\n setHighlightedIndex(\n (current) => (current - 1 + selectableOptions.length) % selectableOptions.length,\n );\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n if (highlightedIndex >= 0) {\n selectOption(selectableOptions[highlightedIndex]);\n }\n break;\n case 'Escape':\n event.preventDefault();\n closeMenu();\n break;\n case 'Tab':\n closeMenu();\n break;\n default:\n break;\n }\n };\n\n return (\n <div ref={rootRef} className={cn('relative w-57.5', className)}>\n <button\n type=\"button\"\n disabled={disabled}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={listboxId}\n aria-label={labels.selectBuilding}\n onClick={() => (open ? closeMenu() : openMenu())}\n onKeyDown={handleTriggerKeyDown}\n className={cn(\n 'flex h-11 w-full items-center gap-3 rounded-xl border border-storm-gray-50 bg-white p-3 text-left transition-colors',\n !disabled && 'cursor-pointer hover:bg-storm-gray-50/60',\n open && 'bg-storm-gray-50/60',\n disabled && 'cursor-not-allowed opacity-60',\n )}\n >\n {buildingIcon ?? <BuildingIcon className=\"shrink-0 text-navy\" />}\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium text-slate-blue\">\n {displayLabel}\n </span>\n {chevronIcon ?? (\n <ChevronsUpDown\n size={16}\n strokeWidth={1.75}\n className={cn(\n 'shrink-0 text-storm-gray-100 transition-transform duration-200',\n open && 'rotate-180',\n )}\n aria-hidden\n />\n )}\n </button>\n\n {open ? (\n <ul\n id={listboxId}\n role=\"listbox\"\n aria-label={labels.selectBuilding}\n tabIndex={-1}\n onKeyDown={handleListKeyDown}\n className={cn(\n 'absolute top-[calc(100%+4px)] left-0 z-50 flex w-full flex-col gap-1 overflow-hidden rounded-xl border border-storm-gray-50 bg-white p-2 shadow-[0_8px_24px_rgba(21,26,30,0.08)]',\n menuClassName,\n )}\n >\n {options.map((option) => {\n const selectableIndex = selectableOptions.findIndex(\n (selectable) => selectable.value === option.value,\n );\n const isSelected = option.value === value;\n const isHighlighted = selectableIndex === highlightedIndex;\n\n return (\n <li key={option.value} role=\"presentation\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n disabled={option.disabled}\n onMouseEnter={() => {\n if (!option.disabled && selectableIndex >= 0) {\n setHighlightedIndex(selectableIndex);\n }\n }}\n onClick={() => selectOption(option)}\n className={cn(\n 'flex w-full rounded-lg px-3 py-2.5 text-left text-sm font-medium text-slate-blue transition-colors',\n !option.disabled && 'cursor-pointer hover:bg-storm-gray-50',\n (isSelected || isHighlighted) && !option.disabled && 'bg-storm-gray-50',\n option.disabled && 'cursor-not-allowed opacity-50',\n )}\n >\n <span className=\"truncate\">{option.label}</span>\n </button>\n </li>\n );\n })}\n </ul>\n ) : null}\n </div>\n );\n}\n","import { Search } from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport type { StyleProp, ViewStyle } from 'react-native';\n\nimport { Input } from '../../components/Input';\nimport { BellIcon } from '../icons/BellIcon';\nimport { cn } from '../utils/cn';\nimport { BuildingSelect } from './BuildingSelect';\nimport type { AdminBuildingOption, AdminHeaderLabels } from './types';\n\nexport type AppHeaderProps = {\n title: string;\n labels: AdminHeaderLabels;\n buildingOptions: AdminBuildingOption[];\n selectedBuildingId: string;\n className?: string;\n buildingSelectClassName?: string;\n searchClassName?: string;\n notificationsButtonClassName?: string;\n searchValue?: string;\n searchFieldStyle?: StyleProp<ViewStyle>;\n buildingIcon?: ReactNode;\n notificationsIcon?: ReactNode;\n searchIcon?: ReactNode;\n buildingChevronIcon?: ReactNode;\n buildingSelectDisabled?: boolean;\n searchDisabled?: boolean;\n notificationsDisabled?: boolean;\n onBuildingChange?: (buildingId: string) => void;\n onNotificationsClick?: () => void;\n onSearchChange?: (value: string) => void;\n};\n\nconst defaultSearchFieldStyle: ViewStyle = {\n height: 44,\n minHeight: 44,\n maxHeight: 44,\n backgroundColor: 'transparent',\n padding: 12,\n width: 260,\n borderRadius: 12,\n};\n\nexport function AppHeader({\n title,\n labels,\n buildingOptions,\n selectedBuildingId,\n className,\n buildingSelectClassName,\n searchClassName,\n notificationsButtonClassName,\n searchValue,\n searchFieldStyle,\n buildingIcon,\n notificationsIcon,\n searchIcon,\n buildingChevronIcon,\n buildingSelectDisabled = false,\n searchDisabled = false,\n notificationsDisabled = false,\n onBuildingChange,\n onNotificationsClick,\n onSearchChange,\n}: AppHeaderProps) {\n return (\n <header\n className={cn(\n 'flex shrink-0 items-center justify-between gap-4 border-b border-storm-gray-50 bg-storm-gray-0 px-6 py-3',\n className,\n )}\n >\n <h1 className=\"truncate text-xl font-bold text-slate-blue\">{title}</h1>\n\n <div className=\"flex shrink-0 items-center gap-3\">\n <BuildingSelect\n options={buildingOptions}\n value={selectedBuildingId}\n labels={labels}\n onChange={onBuildingChange}\n disabled={buildingSelectDisabled}\n className={buildingSelectClassName}\n buildingIcon={buildingIcon}\n chevronIcon={buildingChevronIcon}\n />\n\n <Input\n leftIcon={searchIcon ?? <Search strokeWidth={1.75} />}\n placeholder={labels.searchPlaceholder}\n value={searchValue}\n onChangeText={(value) => onSearchChange?.(value)}\n editable={!searchDisabled}\n className={cn('w-65!', searchClassName)}\n containerStyle={{ width: 260, maxWidth: 260, flexShrink: 0 }}\n fieldStyle={searchFieldStyle ?? defaultSearchFieldStyle}\n accessibilityLabel={labels.searchPlaceholder}\n />\n\n <button\n type=\"button\"\n onClick={onNotificationsClick}\n disabled={notificationsDisabled}\n className={cn(\n 'h-11 cursor-pointer rounded-xl border border-storm-gray-50 p-3 text-slate-blue transition-colors hover:bg-storm-gray-50/60',\n notificationsDisabled && 'pointer-events-none opacity-60',\n notificationsButtonClassName,\n )}\n aria-label={labels.notifications}\n >\n {notificationsIcon ?? <BellIcon className=\"text-navy\" />}\n </button>\n </div>\n </header>\n );\n}\n","import { useEffect, useState } from 'react';\n\nexport function useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() => {\n if (typeof window === 'undefined') {\n return false;\n }\n\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n const mediaQuery = window.matchMedia(query);\n const handleChange = () => setMatches(mediaQuery.matches);\n\n handleChange();\n mediaQuery.addEventListener('change', handleChange);\n\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, [query]);\n\n return matches;\n}\n","import { NavLink } from 'react-router-dom';\n\nimport { cn } from '../utils/cn';\nimport type { AdminNavItem } from './types';\n\nexport type SidebarNavItemProps = {\n item: AdminNavItem;\n isOpen: boolean;\n onNavigate?: (item: AdminNavItem) => void;\n};\n\nexport function SidebarNavItem({ item, isOpen, onNavigate }: SidebarNavItemProps) {\n if (item.hidden) {\n return null;\n }\n\n const handleClick = () => {\n item.onClick?.();\n onNavigate?.(item);\n };\n\n return (\n <NavLink\n to={item.to}\n end={item.end}\n onClick={handleClick}\n aria-disabled={item.disabled}\n tabIndex={item.disabled ? -1 : undefined}\n className={({ isActive }) =>\n cn(\n 'relative flex items-center rounded-xl px-4 py-3 transition-[background-color,color,gap,padding] duration-300 ease-in-out',\n isOpen ? 'w-full gap-4' : 'justify-center gap-0 px-3',\n item.disabled && 'pointer-events-none opacity-50',\n isActive ? 'bg-black/12 text-white' : 'text-navy-100 hover:bg-white/5',\n )\n }\n >\n {({ isActive }) => (\n <>\n <span\n aria-hidden\n className={cn(\n 'absolute top-1.5 -left-1 h-8 w-2 rounded-full bg-white transition-[opacity,transform] duration-300 ease-in-out',\n isActive ? 'scale-100 opacity-100' : 'scale-75 opacity-0',\n )}\n />\n <span className=\"flex size-5 shrink-0 items-center justify-center\">{item.icon}</span>\n <span\n className={cn(\n 'overflow-hidden text-sm font-semibold whitespace-nowrap transition-[max-width,opacity] duration-300 ease-in-out',\n isOpen ? 'max-w-[180px] opacity-100' : 'max-w-0 opacity-0',\n )}\n >\n {item.label}\n </span>\n </>\n )}\n </NavLink>\n );\n}\n","import { LogOut } from 'lucide-react';\n\nimport { cn } from '../utils/cn';\nimport type { AdminSidebarUser } from './types';\n\nexport type SidebarUserCardProps = {\n user: AdminSidebarUser;\n isOpen: boolean;\n logoutLabel: string;\n onLogout?: () => void;\n className?: string;\n};\n\nfunction getInitials(fullName: string, email: string): string {\n const parts = fullName.trim().split(/\\s+/).filter(Boolean);\n if (parts.length > 0) {\n return parts\n .slice(0, 2)\n .map((part) => part[0]?.toUpperCase() ?? '')\n .join('');\n }\n\n return email.slice(0, 2).toUpperCase();\n}\n\nexport function SidebarUserCard({\n user,\n isOpen,\n logoutLabel,\n onLogout,\n className,\n}: SidebarUserCardProps) {\n const initials = user.initials ?? getInitials(user.fullName, user.email);\n\n return (\n <div\n className={cn(\n 'flex w-full items-center rounded-xl p-3 transition-[background-color,justify-content,gap] duration-300 ease-in-out',\n isOpen ? 'justify-between gap-3 bg-black/12' : 'justify-center',\n className,\n )}\n >\n <div\n className={cn(\n 'flex min-w-0 items-center transition-[gap,flex] duration-300 ease-in-out',\n isOpen ? 'flex-1 gap-3' : 'gap-0',\n )}\n >\n <div\n className=\"flex size-11 shrink-0 items-center justify-center rounded-full bg-white/5 text-sm font-bold text-white\"\n aria-hidden\n >\n {initials}\n </div>\n <div\n className={cn(\n 'min-w-0 overflow-hidden transition-[max-width,opacity] duration-300 ease-in-out',\n isOpen ? 'max-w-[160px] opacity-100' : 'max-w-0 opacity-0',\n )}\n >\n <p className=\"truncate text-sm font-bold text-white\">{user.fullName}</p>\n <p className=\"truncate text-xs text-storm-gray-100\">{user.email}</p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => onLogout?.()}\n className={cn(\n 'shrink-0 cursor-pointer text-navy-150 transition-[opacity,transform,max-width] duration-300 ease-in-out hover:opacity-80 active:scale-95',\n isOpen ? 'max-w-8 scale-100 opacity-100' : 'pointer-events-none max-w-0 scale-90 opacity-0',\n )}\n aria-label={logoutLabel}\n tabIndex={isOpen ? 0 : -1}\n >\n <LogOut size={20} strokeWidth={1.75} />\n </button>\n </div>\n );\n}\n","import { PanelLeftClose, PanelLeftOpen, X } from 'lucide-react';\nimport { useCallback, useEffect, useRef, useState, type ReactNode } from 'react';\nimport { useLocation } from 'react-router-dom';\n\nimport { useMediaQuery } from '../hooks/useMediaQuery';\nimport { cn } from '../utils/cn';\nimport { SidebarNavItem } from './SidebarNavItem';\nimport { SidebarUserCard } from './SidebarUserCard';\nimport type { AdminNavItem, AdminSidebarBranding, AdminSidebarLabels, AdminSidebarUser } from './types';\n\nexport type SidebarProps = {\n navItems: AdminNavItem[];\n footerNavItems: AdminNavItem[];\n branding: AdminSidebarBranding;\n labels: AdminSidebarLabels;\n sidebarStorageKey: string;\n user?: AdminSidebarUser;\n onLogout?: () => void;\n className?: string;\n mobileOpen: boolean;\n onMobileClose?: () => void;\n onNavItemClick?: (item: AdminNavItem) => void;\n collapseIcon?: ReactNode;\n expandIcon?: ReactNode;\n closeIcon?: ReactNode;\n initialCollapsed?: boolean;\n collapsed?: boolean;\n onCollapsedChange?: (collapsed: boolean) => void;\n};\n\nfunction readInitialCollapsedState(storageKey: string, initialCollapsed?: boolean): boolean {\n if (initialCollapsed !== undefined) {\n return initialCollapsed;\n }\n\n if (typeof window === 'undefined') {\n return false;\n }\n\n const stored = window.localStorage.getItem(storageKey);\n if (stored === null) {\n return false;\n }\n\n return stored !== 'true';\n}\n\nexport function Sidebar({\n navItems,\n footerNavItems,\n branding,\n labels,\n sidebarStorageKey,\n user,\n onLogout,\n className,\n mobileOpen,\n onMobileClose,\n onNavItemClick,\n collapseIcon,\n expandIcon,\n closeIcon,\n initialCollapsed,\n collapsed,\n onCollapsedChange,\n}: SidebarProps) {\n const location = useLocation();\n const isDesktop = useMediaQuery('(min-width: 768px)');\n const [internalCollapsed, setInternalCollapsed] = useState(() =>\n readInitialCollapsedState(sidebarStorageKey, initialCollapsed),\n );\n\n const isCollapsed = collapsed ?? internalCollapsed;\n const isExpanded = isDesktop ? !isCollapsed : true;\n\n const setCollapsed = useCallback(\n (next: boolean) => {\n if (collapsed === undefined) {\n setInternalCollapsed(next);\n window.localStorage.setItem(sidebarStorageKey, String(!next));\n }\n\n onCollapsedChange?.(next);\n },\n [collapsed, onCollapsedChange, sidebarStorageKey],\n );\n\n const toggleCollapsed = useCallback(() => {\n setCollapsed(!isCollapsed);\n }, [isCollapsed, setCollapsed]);\n\n const handleHeaderAction = useCallback(() => {\n if (isDesktop) {\n toggleCollapsed();\n\n return;\n }\n\n onMobileClose?.();\n }, [isDesktop, onMobileClose, toggleCollapsed]);\n\n const handleNavItemNavigate = useCallback(\n (item: AdminNavItem) => {\n onNavItemClick?.(item);\n\n if (!isDesktop) {\n onMobileClose?.();\n }\n },\n [isDesktop, onMobileClose, onNavItemClick],\n );\n\n const pathnameRef = useRef(location.pathname);\n\n useEffect(() => {\n if (pathnameRef.current === location.pathname) {\n return;\n }\n\n pathnameRef.current = location.pathname;\n\n if (!isDesktop) {\n onMobileClose?.();\n }\n }, [location.pathname, isDesktop, onMobileClose]);\n\n useEffect(() => {\n if (!mobileOpen || isDesktop) {\n return;\n }\n\n const previousOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n\n return () => {\n document.body.style.overflow = previousOverflow;\n };\n }, [mobileOpen, isDesktop]);\n\n const visibleNavItems = navItems.filter((item) => !item.hidden);\n const visibleFooterNavItems = footerNavItems.filter((item) => !item.hidden);\n\n return (\n <>\n <button\n type=\"button\"\n aria-label={labels.closeMenu}\n onClick={onMobileClose}\n className={cn(\n 'fixed inset-0 z-40 bg-navy-800/60 backdrop-blur-[1px] transition-opacity duration-300 ease-in-out md:hidden',\n mobileOpen ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n />\n\n <aside\n className={cn(\n 'fixed inset-y-0 left-0 z-50 flex h-screen w-[min(300px,85vw)] flex-col gap-8 overflow-hidden bg-navy p-4 shadow-xl',\n 'transition-[transform,width,padding,gap] duration-300 ease-in-out will-change-[transform,width]',\n mobileOpen ? 'translate-x-0' : '-translate-x-full',\n 'md:relative md:z-auto md:w-[300px] md:translate-x-0 md:shadow-none',\n isExpanded ? 'md:w-[300px]' : 'md:w-[52px] md:items-center md:gap-4 md:px-3 md:py-4',\n className,\n )}\n aria-hidden={!isDesktop && !mobileOpen}\n >\n <div\n className={cn(\n 'flex w-full items-center transition-[justify-content] duration-300 ease-in-out',\n isExpanded ? 'justify-between' : 'justify-center',\n )}\n >\n <div\n className={cn(\n 'flex min-w-0 items-center gap-1.5 overflow-hidden transition-[max-width,opacity] duration-300 ease-in-out',\n isExpanded ? 'max-w-[240px] opacity-100' : 'max-w-0 opacity-0',\n )}\n >\n <img src={branding.logoIconSrc} alt=\"\" className=\"h-5 w-[29px] shrink-0\" />\n <div className=\"flex min-w-0 flex-col leading-none\">\n <span className=\"text-[21px] font-bold tracking-tight whitespace-nowrap text-white\">\n {branding.logoTitle}\n </span>\n <span className=\"text-[6.5px] font-normal tracking-[-0.26px] text-navy-300 uppercase\">\n {branding.logoTagline}\n </span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={handleHeaderAction}\n className=\"shrink-0 cursor-pointer text-white transition-[opacity,transform] duration-200 hover:opacity-80 active:scale-95\"\n aria-label={\n isDesktop\n ? isExpanded\n ? labels.collapse\n : labels.expand\n : labels.closeMenu\n }\n >\n {isDesktop ? (\n isExpanded ? (\n collapseIcon ?? <PanelLeftClose size={20} strokeWidth={1.75} />\n ) : (\n expandIcon ?? <PanelLeftOpen size={20} strokeWidth={1.75} />\n )\n ) : (\n closeIcon ?? <X size={20} strokeWidth={1.75} />\n )}\n </button>\n </div>\n\n <nav className=\"flex flex-1 flex-col gap-2 overflow-y-auto overflow-x-hidden\">\n {visibleNavItems.map((item) => (\n <SidebarNavItem\n key={item.to}\n item={item}\n isOpen={isExpanded}\n onNavigate={handleNavItemNavigate}\n />\n ))}\n </nav>\n\n <div className=\"flex w-full flex-col gap-4\">\n {visibleFooterNavItems.map((item) => (\n <SidebarNavItem\n key={item.to}\n item={item}\n isOpen={isExpanded}\n onNavigate={handleNavItemNavigate}\n />\n ))}\n {user ? (\n <SidebarUserCard\n user={user}\n isOpen={isExpanded}\n logoutLabel={labels.logout}\n onLogout={onLogout}\n />\n ) : null}\n </div>\n </aside>\n </>\n );\n}\n","import { Menu } from 'lucide-react';\n\nimport { cn } from '../utils/cn';\nimport type { AdminSidebarBranding } from './types';\n\nexport type SidebarMobileHeaderProps = {\n branding: Pick<AdminSidebarBranding, 'logoIconSrc' | 'logoTitle' | 'logoTagline'>;\n openMenuLabel: string;\n onOpenMenu: () => void;\n menuOpen?: boolean;\n className?: string;\n};\n\nexport function SidebarMobileHeader({\n branding,\n openMenuLabel,\n onOpenMenu,\n menuOpen = false,\n className,\n}: SidebarMobileHeaderProps) {\n return (\n <header\n className={cn(\n 'sticky top-0 z-30 flex h-14 shrink-0 items-center gap-3 border-b border-storm-gray-50 bg-storm-gray-0 px-4 md:hidden',\n className,\n )}\n >\n <button\n type=\"button\"\n onClick={onOpenMenu}\n className=\"flex size-10 items-center justify-center rounded-xl text-navy transition-colors hover:bg-storm-gray-50\"\n aria-label={openMenuLabel}\n aria-expanded={menuOpen}\n >\n <Menu size={22} strokeWidth={1.75} />\n </button>\n <div className=\"flex min-w-0 items-center gap-2\">\n <img src={branding.logoIconSrc} alt=\"\" className=\"h-[30px] w-[42px] shrink-0\" />\n <div className=\"min-w-0 leading-none\">\n <p className=\"truncate text-base font-bold tracking-tight text-navy\">{branding.logoTitle}</p>\n <p className=\"truncate text-[6.5px] font-normal tracking-[-0.26px] text-navy-300 uppercase\">\n {branding.logoTagline}\n </p>\n </div>\n </div>\n </header>\n );\n}\n","import type { ReactNode } from 'react';\n\nimport { AppHeader } from './AppHeader';\nimport type { AppHeaderProps } from './AppHeader';\nimport { Sidebar } from './Sidebar';\nimport type { SidebarProps } from './Sidebar';\nimport { SidebarMobileHeader } from './SidebarMobileHeader';\nimport type { SidebarMobileHeaderProps } from './SidebarMobileHeader';\n\nexport type DashboardLayoutProps = {\n sidebar: SidebarProps;\n header: AppHeaderProps;\n mobileHeader: SidebarMobileHeaderProps;\n children: ReactNode;\n className?: string;\n mainClassName?: string;\n};\n\nexport function DashboardLayout({\n sidebar,\n header,\n mobileHeader,\n children,\n className,\n mainClassName,\n}: DashboardLayoutProps) {\n return (\n <div className={className ?? 'flex min-h-screen bg-storm-gray-0'}>\n <Sidebar {...sidebar} />\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <SidebarMobileHeader {...mobileHeader} />\n <AppHeader {...header} />\n <main className={mainClassName ?? 'flex-1 overflow-auto p-4 md:p-6'}>{children}</main>\n </div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../../src/web/utils/cn.ts","../../src/web/icons/BellIcon.tsx","../../src/web/icons/BuildingIcon.tsx","../../src/web/hooks/useOnClickOutside.ts","../../src/web/layout/BuildingSelect.tsx","../../src/web/layout/AppHeader.tsx","../../src/web/hooks/useMediaQuery.ts","../../src/web/layout/SidebarNavItem.tsx","../../src/web/layout/SidebarUserCard.tsx","../../src/web/layout/Sidebar.tsx","../../src/web/layout/SidebarMobileHeader.tsx","../../src/web/layout/DashboardLayout.tsx"],"names":["jsx","jsxs","useState","useEffect","Fragment","useCallback","useRef"],"mappings":";;;;;;;;AAGO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACCO,SAAS,QAAA,CAAS,EAAE,SAAA,EAAU,EAAkB;AACrD,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,IAAA;AAAA,MACN,MAAA,EAAO,IAAA;AAAA,MACP,OAAA,EAAQ,WAAA;AAAA,MACR,IAAA,EAAK,MAAA;AAAA,MACL,KAAA,EAAM,4BAAA;AAAA,MACN,aAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,EAAA,CAAG,UAAA,EAAY,SAAS,CAAA;AAAA,MAEnC,QAAA,kBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,CAAA,EAAE,scAAA;AAAA,UACF,MAAA,EAAO,cAAA;AAAA,UACP,WAAA,EAAY,GAAA;AAAA,UACZ,aAAA,EAAc,OAAA;AAAA,UACd,cAAA,EAAe;AAAA;AAAA;AACjB;AAAA,GACF;AAEJ;ACpBO,SAAS,YAAA,CAAa,EAAE,SAAA,EAAU,EAAsB;AAC7D,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,IAAA;AAAA,MACN,MAAA,EAAO,IAAA;AAAA,MACP,OAAA,EAAQ,WAAA;AAAA,MACR,IAAA,EAAK,MAAA;AAAA,MACL,KAAA,EAAM,4BAAA;AAAA,MACN,aAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,EAAA,CAAG,UAAA,EAAY,SAAS,CAAA;AAAA,MAEnC,QAAA,EAAA;AAAA,wBAAAA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,CAAA,EAAE,UAAA;AAAA,YACF,MAAA,EAAO,cAAA;AAAA,YACP,WAAA,EAAY,GAAA;AAAA,YACZ,aAAA,EAAc,OAAA;AAAA,YACd,cAAA,EAAe;AAAA;AAAA,SACjB;AAAA,wBACAA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,CAAA,EAAE,SAAA;AAAA,YACF,MAAA,EAAO,cAAA;AAAA,YACP,WAAA,EAAY,GAAA;AAAA,YACZ,aAAA,EAAc,OAAA;AAAA,YACd,cAAA,EAAe;AAAA;AAAA,SACjB;AAAA,wBACAA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,CAAA,EAAE,2BAAA;AAAA,YACF,MAAA,EAAO,cAAA;AAAA,YACP,WAAA,EAAY,GAAA;AAAA,YACZ,aAAA,EAAc,OAAA;AAAA,YACd,cAAA,EAAe;AAAA;AAAA,SACjB;AAAA,wBACAA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,CAAA,EAAE,2EAAA;AAAA,YACF,MAAA,EAAO,cAAA;AAAA,YACP,WAAA,EAAY,GAAA;AAAA,YACZ,aAAA,EAAc,OAAA;AAAA,YACd,cAAA,EAAe;AAAA;AAAA,SACjB;AAAA,wBACAA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,CAAA,EAAE,0CAAA;AAAA,YACF,MAAA,EAAO,cAAA;AAAA,YACP,WAAA,EAAY,GAAA;AAAA,YACZ,aAAA,EAAc,OAAA;AAAA,YACd,cAAA,EAAe;AAAA;AAAA;AACjB;AAAA;AAAA,GACF;AAEJ;ACpDO,SAAS,iBAAA,CACd,GAAA,EACA,OAAA,EACA,OAAA,GAAU,IAAA,EACV;AACA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,aAAA,GAAgB,CAAC,KAAA,KAAmC;AACxD,MAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,MAAA,IAAI,CAAC,IAAI,OAAA,IAAW,CAAC,UAAU,GAAA,CAAI,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA,EAAG;AAC3D,QAAA;AAAA,MACF;AAEA,MAAA,OAAA,EAAQ;AAAA,IACV,CAAA;AAEA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,aAAa,CAAA;AACpD,IAAA,QAAA,CAAS,gBAAA,CAAiB,cAAc,aAAa,CAAA;AAErD,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,aAAa,aAAa,CAAA;AACvD,MAAA,QAAA,CAAS,mBAAA,CAAoB,cAAc,aAAa,CAAA;AAAA,IAC1D,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,OAAA,EAAS,GAAG,CAAC,CAAA;AAC5B;ACTO,SAAS,cAAA,CAAe;AAAA,EAC7B,OAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,SAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,KAAK,CAAA;AACtC,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAAS,EAAE,CAAA;AAC3D,EAAA,MAAM,OAAA,GAAU,OAAuB,IAAI,CAAA;AAC3C,EAAA,MAAM,YAAY,KAAA,EAAM;AAExB,EAAA,MAAM,iBAAiB,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAA,KAAW,MAAA,CAAO,UAAU,KAAK,CAAA;AACtE,EAAA,MAAM,YAAA,GAAe,cAAA,EAAgB,KAAA,IAAS,MAAA,CAAO,cAAA;AACrD,EAAA,MAAM,oBAAoB,OAAA,CAAQ,MAAA,CAAO,CAAC,MAAA,KAAW,CAAC,OAAO,QAAQ,CAAA;AAErE,EAAA,MAAM,SAAA,GAAY,YAAY,MAAM;AAClC,IAAA,OAAA,CAAQ,KAAK,CAAA;AACb,IAAA,mBAAA,CAAoB,EAAE,CAAA;AAAA,EACxB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,QAAA,GAAW,YAAY,MAAM;AACjC,IAAA,IAAI,QAAA,IAAY,iBAAA,CAAkB,MAAA,KAAW,CAAA,EAAG;AAC9C,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,gBAAgB,iBAAA,CAAkB,SAAA,CAAU,CAAC,MAAA,KAAW,MAAA,CAAO,UAAU,KAAK,CAAA;AACpF,IAAA,mBAAA,CAAoB,aAAA,IAAiB,CAAA,GAAI,aAAA,GAAgB,CAAC,CAAA;AAC1D,IAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,EACd,CAAA,EAAG,CAAC,QAAA,EAAU,iBAAA,EAAmB,KAAK,CAAC,CAAA;AAEvC,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,CAAC,MAAA,KAAgC;AAC/B,MAAA,IAAI,OAAO,QAAA,EAAU;AACnB,QAAA;AAAA,MACF;AAEA,MAAA,QAAA,GAAW,OAAO,KAAK,CAAA;AACvB,MAAA,SAAA,EAAU;AAAA,IACZ,CAAA;AAAA,IACA,CAAC,WAAW,QAAQ;AAAA,GACtB;AAEA,EAAA,iBAAA,CAAkB,OAAA,EAAS,WAAW,IAAI,CAAA;AAE1C,EAAA,MAAM,oBAAA,GAAuB,CAAC,KAAA,KAA4C;AACxE,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA;AAAA,IACF;AAEA,IAAA,QAAQ,MAAM,GAAA;AAAK,MACjB,KAAK,WAAA;AAAA,MACL,KAAK,OAAA;AAAA,MACL,KAAK,GAAA;AACH,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,QAAA,EAAS;AACT,QAAA;AAAA,MACF,KAAK,QAAA;AACH,QAAA,SAAA,EAAU;AACV,QAAA;AAEA;AACJ,EACF,CAAA;AAEA,EAAA,MAAM,iBAAA,GAAoB,CAAC,KAAA,KAA2C;AACpE,IAAA,IAAI,CAAC,IAAA,IAAQ,iBAAA,CAAkB,MAAA,KAAW,CAAA,EAAG;AAC3C,MAAA;AAAA,IACF;AAEA,IAAA,QAAQ,MAAM,GAAA;AAAK,MACjB,KAAK,WAAA;AACH,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,mBAAA,CAAoB,CAAC,OAAA,KAAA,CAAa,OAAA,GAAU,CAAA,IAAK,kBAAkB,MAAM,CAAA;AACzE,QAAA;AAAA,MACF,KAAK,SAAA;AACH,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,mBAAA;AAAA,UACE,CAAC,OAAA,KAAA,CAAa,OAAA,GAAU,CAAA,GAAI,iBAAA,CAAkB,UAAU,iBAAA,CAAkB;AAAA,SAC5E;AACA,QAAA;AAAA,MACF,KAAK,OAAA;AAAA,MACL,KAAK,GAAA;AACH,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,IAAI,oBAAoB,CAAA,EAAG;AACzB,UAAA,YAAA,CAAa,iBAAA,CAAkB,gBAAgB,CAAC,CAAA;AAAA,QAClD;AACA,QAAA;AAAA,MACF,KAAK,QAAA;AACH,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,SAAA,EAAU;AACV,QAAA;AAAA,MACF,KAAK,KAAA;AACH,QAAA,SAAA,EAAU;AACV,QAAA;AAEA;AACJ,EACF,CAAA;AAEA,EAAA,uBACEC,KAAC,KAAA,EAAA,EAAI,GAAA,EAAK,SAAS,SAAA,EAAW,EAAA,CAAG,iBAAA,EAAmB,SAAS,CAAA,EAC3D,QAAA,EAAA;AAAA,oBAAAA,IAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,QAAA;AAAA,QACA,eAAA,EAAc,SAAA;AAAA,QACd,eAAA,EAAe,IAAA;AAAA,QACf,eAAA,EAAe,SAAA;AAAA,QACf,cAAY,MAAA,CAAO,cAAA;AAAA,QACnB,OAAA,EAAS,MAAO,IAAA,GAAO,SAAA,KAAc,QAAA,EAAS;AAAA,QAC9C,SAAA,EAAW,oBAAA;AAAA,QACX,SAAA,EAAW,EAAA;AAAA,UACT,qHAAA;AAAA,UACA,CAAC,QAAA,IAAY,0CAAA;AAAA,UACb,IAAA,IAAQ,qBAAA;AAAA,UACR,QAAA,IAAY;AAAA,SACd;AAAA,QAEC,QAAA,EAAA;AAAA,UAAA,YAAA,oBAAgBD,GAAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAU,oBAAA,EAAqB,CAAA;AAAA,0BAC9DA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+DACb,QAAA,EAAA,YAAA,EACH,CAAA;AAAA,UACC,+BACCA,GAAAA;AAAA,YAAC,cAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAM,EAAA;AAAA,cACN,WAAA,EAAa,IAAA;AAAA,cACb,SAAA,EAAW,EAAA;AAAA,gBACT,gEAAA;AAAA,gBACA,IAAA,IAAQ;AAAA,eACV;AAAA,cACA,aAAA,EAAW;AAAA;AAAA;AACb;AAAA;AAAA,KAEJ;AAAA,IAEC,uBACCA,GAAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,EAAA,EAAI,SAAA;AAAA,QACJ,IAAA,EAAK,SAAA;AAAA,QACL,cAAY,MAAA,CAAO,cAAA;AAAA,QACnB,QAAA,EAAU,EAAA;AAAA,QACV,SAAA,EAAW,iBAAA;AAAA,QACX,SAAA,EAAW,EAAA;AAAA,UACT,kLAAA;AAAA,UACA;AAAA,SACF;AAAA,QAEC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,KAAW;AACvB,UAAA,MAAM,kBAAkB,iBAAA,CAAkB,SAAA;AAAA,YACxC,CAAC,UAAA,KAAe,UAAA,CAAW,KAAA,KAAU,MAAA,CAAO;AAAA,WAC9C;AACA,UAAA,MAAM,UAAA,GAAa,OAAO,KAAA,KAAU,KAAA;AACpC,UAAA,MAAM,gBAAgB,eAAA,KAAoB,gBAAA;AAE1C,UAAA,uBACEA,GAAAA,CAAC,IAAA,EAAA,EAAsB,IAAA,EAAK,gBAC1B,QAAA,kBAAAA,GAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,IAAA,EAAK,QAAA;AAAA,cACL,eAAA,EAAe,UAAA;AAAA,cACf,UAAU,MAAA,CAAO,QAAA;AAAA,cACjB,cAAc,MAAM;AAClB,gBAAA,IAAI,CAAC,MAAA,CAAO,QAAA,IAAY,eAAA,IAAmB,CAAA,EAAG;AAC5C,kBAAA,mBAAA,CAAoB,eAAe,CAAA;AAAA,gBACrC;AAAA,cACF,CAAA;AAAA,cACA,OAAA,EAAS,MAAM,YAAA,CAAa,MAAM,CAAA;AAAA,cAClC,SAAA,EAAW,EAAA;AAAA,gBACT,oGAAA;AAAA,gBACA,CAAC,OAAO,QAAA,IAAY,uCAAA;AAAA,gBAAA,CACnB,UAAA,IAAc,aAAA,KAAkB,CAAC,MAAA,CAAO,QAAA,IAAY,kBAAA;AAAA,gBACrD,OAAO,QAAA,IAAY;AAAA,eACrB;AAAA,cAEA,0BAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,UAAA,EAAY,iBAAO,KAAA,EAAM;AAAA;AAAA,WAC3C,EAAA,EApBO,OAAO,KAqBhB,CAAA;AAAA,QAEJ,CAAC;AAAA;AAAA,KACH,GACE;AAAA,GAAA,EACN,CAAA;AAEJ;AC9KA,IAAM,uBAAA,GAAqC;AAAA,EACzC,MAAA,EAAQ,EAAA;AAAA,EACR,SAAA,EAAW,EAAA;AAAA,EACX,SAAA,EAAW,EAAA;AAAA,EACX,eAAA,EAAiB,aAAA;AAAA,EACjB,OAAA,EAAS,EAAA;AAAA,EACT,KAAA,EAAO,GAAA;AAAA,EACP,YAAA,EAAc;AAChB,CAAA;AAEO,SAAS,SAAA,CAAU;AAAA,EACxB,KAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA;AAAA,EACA,kBAAA;AAAA,EACA,SAAA;AAAA,EACA,uBAAA;AAAA,EACA,eAAA;AAAA,EACA,4BAAA;AAAA,EACA,WAAA;AAAA,EACA,gBAAA;AAAA,EACA,YAAA;AAAA,EACA,iBAAA;AAAA,EACA,UAAA;AAAA,EACA,mBAAA;AAAA,EACA,sBAAA,GAAyB,KAAA;AAAA,EACzB,cAAA,GAAiB,KAAA;AAAA,EACjB,qBAAA,GAAwB,KAAA;AAAA,EACxB,gBAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAA,EAAmB;AACjB,EAAA,uBACEC,IAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,0GAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAD,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,4CAAA,EAA8C,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,wBAElEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kCAAA,EACb,QAAA,EAAA;AAAA,0BAAAD,GAAAA;AAAA,YAAC,cAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,eAAA;AAAA,cACT,KAAA,EAAO,kBAAA;AAAA,cACP,MAAA;AAAA,cACA,QAAA,EAAU,gBAAA;AAAA,cACV,QAAA,EAAU,sBAAA;AAAA,cACV,SAAA,EAAW,uBAAA;AAAA,cACX,YAAA;AAAA,cACA,WAAA,EAAa;AAAA;AAAA,WACf;AAAA,0BAEAA,GAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,UAAU,UAAA,oBAAcA,GAAAA,CAAC,MAAA,EAAA,EAAO,aAAa,IAAA,EAAM,CAAA;AAAA,cACnD,aAAa,MAAA,CAAO,iBAAA;AAAA,cACpB,KAAA,EAAO,WAAA;AAAA,cACP,YAAA,EAAc,CAAC,KAAA,KAAU,cAAA,GAAiB,KAAK,CAAA;AAAA,cAC/C,UAAU,CAAC,cAAA;AAAA,cACX,SAAA,EAAW,EAAA,CAAG,OAAA,EAAS,eAAe,CAAA;AAAA,cACtC,gBAAgB,EAAE,KAAA,EAAO,KAAK,QAAA,EAAU,GAAA,EAAK,YAAY,CAAA,EAAE;AAAA,cAC3D,YAAY,gBAAA,IAAoB,uBAAA;AAAA,cAChC,oBAAoB,MAAA,CAAO;AAAA;AAAA,WAC7B;AAAA,0BAEAA,GAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,oBAAA;AAAA,cACT,QAAA,EAAU,qBAAA;AAAA,cACV,SAAA,EAAW,EAAA;AAAA,gBACT,4HAAA;AAAA,gBACA,qBAAA,IAAyB,gCAAA;AAAA,gBACzB;AAAA,eACF;AAAA,cACA,cAAY,MAAA,CAAO,aAAA;AAAA,cAElB,QAAA,EAAA,iBAAA,oBAAqBA,GAAAA,CAAC,QAAA,EAAA,EAAS,WAAU,WAAA,EAAY;AAAA;AAAA;AACxD,SAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;AChHO,SAAS,cAAc,KAAA,EAAwB;AACpD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIE,SAAS,MAAM;AAC3C,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,OAAO,MAAA,CAAO,UAAA,CAAW,KAAK,CAAA,CAAE,OAAA;AAAA,EAClC,CAAC,CAAA;AAED,EAAAC,UAAU,MAAM;AACd,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,UAAA,CAAW,KAAK,CAAA;AAC1C,IAAA,MAAM,YAAA,GAAe,MAAM,UAAA,CAAW,UAAA,CAAW,OAAO,CAAA;AAExD,IAAA,YAAA,EAAa;AACb,IAAA,UAAA,CAAW,gBAAA,CAAiB,UAAU,YAAY,CAAA;AAElD,IAAA,OAAO,MAAM,UAAA,CAAW,mBAAA,CAAoB,QAAA,EAAU,YAAY,CAAA;AAAA,EACpE,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,OAAO,OAAA;AACT;ACXO,SAAS,cAAA,CAAe,EAAE,IAAA,EAAM,MAAA,EAAQ,YAAW,EAAwB;AAChF,EAAA,IAAI,KAAK,MAAA,EAAQ;AACf,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,IAAA,CAAK,OAAA,IAAU;AACf,IAAA,UAAA,GAAa,IAAI,CAAA;AAAA,EACnB,CAAA;AAEA,EAAA,uBACEH,GAAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAI,IAAA,CAAK,EAAA;AAAA,MACT,KAAK,IAAA,CAAK,GAAA;AAAA,MACV,OAAA,EAAS,WAAA;AAAA,MACT,iBAAe,IAAA,CAAK,QAAA;AAAA,MACpB,QAAA,EAAU,IAAA,CAAK,QAAA,GAAW,EAAA,GAAK,MAAA;AAAA,MAC/B,SAAA,EAAW,CAAC,EAAE,QAAA,EAAS,KACrB,EAAA;AAAA,QACE,0HAAA;AAAA,QACA,SAAS,cAAA,GAAiB,2BAAA;AAAA,QAC1B,KAAK,QAAA,IAAY,gCAAA;AAAA,QACjB,WAAW,wBAAA,GAA2B;AAAA,OACxC;AAAA,MAGD,WAAC,EAAE,QAAA,EAAS,qBACXC,KAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAW,IAAA;AAAA,YACX,SAAA,EAAW,EAAA;AAAA,cACT,gHAAA;AAAA,cACA,WAAW,uBAAA,GAA0B;AAAA;AACvC;AAAA,SACF;AAAA,wBACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kDAAA,EAAoD,eAAK,IAAA,EAAK,CAAA;AAAA,wBAC9EA,GAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,EAAA;AAAA,cACT,iHAAA;AAAA,cACA,SAAS,2BAAA,GAA8B;AAAA,aACzC;AAAA,YAEC,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA;AACR,OAAA,EACF;AAAA;AAAA,GAEJ;AAEJ;AC9CA,SAAS,WAAA,CAAY,UAAkB,KAAA,EAAuB;AAC5D,EAAA,MAAM,KAAA,GAAQ,SAAS,IAAA,EAAK,CAAE,MAAM,KAAK,CAAA,CAAE,OAAO,OAAO,CAAA;AACzD,EAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,IAAA,OAAO,MACJ,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CACV,IAAI,CAAC,IAAA,KAAS,IAAA,CAAK,CAAC,GAAG,WAAA,EAAY,IAAK,EAAE,CAAA,CAC1C,KAAK,EAAE,CAAA;AAAA,EACZ;AAEA,EAAA,OAAO,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,CAAC,EAAE,WAAA,EAAY;AACvC;AAEO,SAAS,eAAA,CAAgB;AAAA,EAC9B,IAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAAyB;AACvB,EAAA,MAAM,WAAW,IAAA,CAAK,QAAA,IAAY,YAAY,IAAA,CAAK,QAAA,EAAU,KAAK,KAAK,CAAA;AAEvE,EAAA,uBACEC,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,wHAAA;AAAA,QACA,SAAS,uCAAA,GAA0C,0BAAA;AAAA,QACnD;AAAA,OACF;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,wGAAA;AAAA,YACV,aAAA,EAAW,IAAA;AAAA,YAEV,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,QACC,MAAA,mBACCC,IAAAA,CAAAG,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,0BAAAH,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8CAAA,EACb,QAAA,EAAA;AAAA,4BAAAD,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,uCAAA,EAAyC,eAAK,QAAA,EAAS,CAAA;AAAA,4BACpEA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sCAAA,EAAwC,eAAK,KAAA,EAAM;AAAA,WAAA,EAClE,CAAA;AAAA,0BACAA,GAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,MAAM,QAAA,IAAW;AAAA,cAC1B,SAAA,EAAU,gIAAA;AAAA,cACV,YAAA,EAAY,WAAA;AAAA,cAEZ,0BAAAA,GAAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAM,EAAA,EAAI,aAAa,IAAA,EAAM;AAAA;AAAA;AACvC,SAAA,EACF,CAAA,GACE;AAAA;AAAA;AAAA,GACN;AAEJ;ACpCA,SAAS,yBAAA,CAA0B,YAAoB,gBAAA,EAAqC;AAC1F,EAAA,IAAI,qBAAqB,MAAA,EAAW;AAClC,IAAA,OAAO,gBAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,UAAU,CAAA;AACrD,EAAA,IAAI,WAAW,IAAA,EAAM;AACnB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OAAO,MAAA,KAAW,MAAA;AACpB;AAEO,SAAS,OAAA,CAAQ;AAAA,EACtB,QAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,iBAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAiB;AACf,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,SAAA,GAAY,cAAc,oBAAoB,CAAA;AACpD,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAIE,QAAAA;AAAA,IAAS,MACzD,yBAAA,CAA0B,iBAAA,EAAmB,gBAAgB;AAAA,GAC/D;AAEA,EAAA,MAAM,cAAc,SAAA,IAAa,iBAAA;AACjC,EAAA,MAAM,UAAA,GAAa,SAAA,GAAY,CAAC,WAAA,GAAc,IAAA;AAE9C,EAAA,MAAM,YAAA,GAAeG,WAAAA;AAAA,IACnB,CAAC,IAAA,KAAkB;AACjB,MAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,QAAA,oBAAA,CAAqB,IAAI,CAAA;AACzB,QAAA,MAAA,CAAO,aAAa,OAAA,CAAQ,iBAAA,EAAmB,MAAA,CAAO,CAAC,IAAI,CAAC,CAAA;AAAA,MAC9D;AAEA,MAAA,iBAAA,GAAoB,IAAI,CAAA;AAAA,IAC1B,CAAA;AAAA,IACA,CAAC,SAAA,EAAW,iBAAA,EAAmB,iBAAiB;AAAA,GAClD;AAEA,EAAA,MAAM,eAAA,GAAkBA,YAAY,MAAM;AACxC,IAAA,YAAA,CAAa,CAAC,WAAW,CAAA;AAAA,EAC3B,CAAA,EAAG,CAAC,WAAA,EAAa,YAAY,CAAC,CAAA;AAE9B,EAAA,MAAM,kBAAA,GAAqBA,YAAY,MAAM;AAC3C,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,eAAA,EAAgB;AAEhB,MAAA;AAAA,IACF;AAEA,IAAA,aAAA,IAAgB;AAAA,EAClB,CAAA,EAAG,CAAC,SAAA,EAAW,aAAA,EAAe,eAAe,CAAC,CAAA;AAE9C,EAAA,MAAM,qBAAA,GAAwBA,WAAAA;AAAA,IAC5B,CAAC,IAAA,KAAuB;AACtB,MAAA,cAAA,GAAiB,IAAI,CAAA;AAErB,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,aAAA,IAAgB;AAAA,MAClB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,SAAA,EAAW,aAAA,EAAe,cAAc;AAAA,GAC3C;AAEA,EAAA,MAAM,WAAA,GAAcC,MAAAA,CAAO,QAAA,CAAS,QAAQ,CAAA;AAE5C,EAAAH,UAAU,MAAM;AACd,IAAA,IAAI,WAAA,CAAY,OAAA,KAAY,QAAA,CAAS,QAAA,EAAU;AAC7C,MAAA;AAAA,IACF;AAEA,IAAA,WAAA,CAAY,UAAU,QAAA,CAAS,QAAA;AAE/B,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,aAAA,IAAgB;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,QAAA,CAAS,QAAA,EAAU,SAAA,EAAW,aAAa,CAAC,CAAA;AAEhD,EAAAA,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,cAAc,SAAA,EAAW;AAC5B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,gBAAA,GAAmB,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,QAAA;AAC7C,IAAA,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,GAAW,QAAA;AAE/B,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,GAAW,gBAAA;AAAA,IACjC,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,UAAA,EAAY,SAAS,CAAC,CAAA;AAE1B,EAAA,MAAM,kBAAkB,QAAA,CAAS,MAAA,CAAO,CAAC,IAAA,KAAS,CAAC,KAAK,MAAM,CAAA;AAC9D,EAAA,MAAM,wBAAwB,cAAA,CAAe,MAAA,CAAO,CAAC,IAAA,KAAS,CAAC,KAAK,MAAM,CAAA;AAE1E,EAAA,uBACEF,IAAAA,CAAAG,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAJ,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,cAAY,MAAA,CAAO,SAAA;AAAA,QACnB,OAAA,EAAS,aAAA;AAAA,QACT,SAAA,EAAW,EAAA;AAAA,UACT,6GAAA;AAAA,UACA,aAAa,aAAA,GAAgB;AAAA;AAC/B;AAAA,KACF;AAAA,oBAEAC,IAAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,oHAAA;AAAA,UACA,iGAAA;AAAA,UACA,aAAa,eAAA,GAAkB,mBAAA;AAAA,UAC/B,oEAAA;AAAA,UACA,aAAa,cAAA,GAAiB,sDAAA;AAAA,UAC9B;AAAA,SACF;AAAA,QACA,aAAA,EAAa,CAAC,SAAA,IAAa,CAAC,UAAA;AAAA,QAE5B,QAAA,EAAA;AAAA,0BAAAA,IAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,EAAA;AAAA,gBACT,gFAAA;AAAA,gBACA,aAAa,iBAAA,GAAoB;AAAA,eACnC;AAAA,cAEA,QAAA,EAAA;AAAA,gCAAAA,IAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAW,EAAA;AAAA,sBACT,2GAAA;AAAA,sBACA,aAAa,2BAAA,GAA8B;AAAA,qBAC7C;AAAA,oBAEA,QAAA,EAAA;AAAA,sCAAAD,GAAAA,CAAC,SAAI,GAAA,EAAK,QAAA,CAAS,aAAa,GAAA,EAAI,EAAA,EAAG,WAAU,uBAAA,EAAwB,CAAA;AAAA,sCACzEC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EACb,QAAA,EAAA;AAAA,wCAAAD,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mEAAA,EACb,mBAAS,SAAA,EACZ,CAAA;AAAA,wCACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qEAAA,EACb,mBAAS,WAAA,EACZ;AAAA,uBAAA,EACF;AAAA;AAAA;AAAA,iBACF;AAAA,gCACAA,GAAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,QAAA;AAAA,oBACL,OAAA,EAAS,kBAAA;AAAA,oBACT,SAAA,EAAU,iHAAA;AAAA,oBACV,cACE,SAAA,GACI,UAAA,GACE,OAAO,QAAA,GACP,MAAA,CAAO,SACT,MAAA,CAAO,SAAA;AAAA,oBAGZ,QAAA,EAAA,SAAA,GACC,UAAA,GACE,YAAA,oBAAgBA,GAAAA,CAAC,cAAA,EAAA,EAAe,IAAA,EAAM,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,CAAA,GAE7D,UAAA,oBAAcA,GAAAA,CAAC,aAAA,EAAA,EAAc,IAAA,EAAM,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,CAAA,GAG5D,SAAA,oBAAaA,GAAAA,CAAC,CAAA,EAAA,EAAE,IAAA,EAAM,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM;AAAA;AAAA;AAEjD;AAAA;AAAA,WACF;AAAA,0BAEAA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gEACZ,QAAA,EAAA,eAAA,CAAgB,GAAA,CAAI,CAAC,IAAA,qBACpBA,GAAAA;AAAA,YAAC,cAAA;AAAA,YAAA;AAAA,cAEC,IAAA;AAAA,cACA,MAAA,EAAQ,UAAA;AAAA,cACR,UAAA,EAAY;AAAA,aAAA;AAAA,YAHP,IAAA,CAAK;AAAA,WAKb,CAAA,EACH,CAAA;AAAA,0BAEAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACZ,QAAA,EAAA;AAAA,YAAA,qBAAA,CAAsB,GAAA,CAAI,CAAC,IAAA,qBAC1BD,GAAAA;AAAA,cAAC,cAAA;AAAA,cAAA;AAAA,gBAEC,IAAA;AAAA,gBACA,MAAA,EAAQ,UAAA;AAAA,gBACR,UAAA,EAAY;AAAA,eAAA;AAAA,cAHP,IAAA,CAAK;AAAA,aAKb,CAAA;AAAA,YACA,uBACCA,GAAAA;AAAA,cAAC,eAAA;AAAA,cAAA;AAAA,gBACC,IAAA;AAAA,gBACA,MAAA,EAAQ,UAAA;AAAA,gBACR,aAAa,MAAA,CAAO,MAAA;AAAA,gBACpB;AAAA;AAAA,aACF,GACE;AAAA,WAAA,EACN;AAAA;AAAA;AAAA;AACF,GAAA,EACF,CAAA;AAEJ;ACtOO,SAAS,mBAAA,CAAoB;AAAA,EAClC,QAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX;AACF,CAAA,EAA6B;AAC3B,EAAA,uBACEC,IAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,sHAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAD,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,UAAA;AAAA,YACT,SAAA,EAAU,wGAAA;AAAA,YACV,YAAA,EAAY,aAAA;AAAA,YACZ,eAAA,EAAe,QAAA;AAAA,YAEf,0BAAAA,GAAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAM,EAAA,EAAI,aAAa,IAAA,EAAM;AAAA;AAAA,SACrC;AAAA,wBACAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iCAAA,EACb,QAAA,EAAA;AAAA,0BAAAD,GAAAA,CAAC,SAAI,GAAA,EAAK,QAAA,CAAS,aAAa,GAAA,EAAI,EAAA,EAAG,WAAU,4BAAA,EAA6B,CAAA;AAAA,0BAC9EC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBAAA,EACb,QAAA,EAAA;AAAA,4BAAAD,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,uDAAA,EAAyD,mBAAS,SAAA,EAAU,CAAA;AAAA,4BACzFA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,8EAAA,EACV,mBAAS,WAAA,EACZ;AAAA,WAAA,EACF;AAAA,SAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;AC3BO,SAAS,eAAA,CAAgB;AAAA,EAC9B,OAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAyB;AACvB,EAAA,uBACEC,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,4CAAA,EAA8C,SAAS,CAAA,EACxE,QAAA,EAAA;AAAA,oBAAAD,GAAAA,CAAC,SAAI,SAAA,EAAU,UAAA,EACb,0BAAAA,GAAAA,CAAC,OAAA,EAAA,EAAS,GAAG,OAAA,EAAS,CAAA,EACxB,CAAA;AAAA,oBACAC,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACb,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,mBAAA,EAAA,EAAqB,GAAG,YAAA,EAAc,CAAA;AAAA,sBACvCA,GAAAA,CAAC,SAAA,EAAA,EAAW,GAAG,MAAA,EAAQ,CAAA;AAAA,sBACvBA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,aAAA,IAAiB,mCAAoC,QAAA,EAAS;AAAA,KAAA,EACjF;AAAA,GAAA,EACF,CAAA;AAEJ","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import { cn } from '../utils/cn';\n\ntype BellIconProps = {\n className?: string;\n};\n\nexport function BellIcon({ className }: BellIconProps) {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden\n className={cn('shrink-0', className)}\n >\n <path\n d=\"M8.58333 17.4998C8.72282 17.7535 8.92787 17.9651 9.17708 18.1125C9.42628 18.2599 9.71048 18.3376 10 18.3376C10.2895 18.3376 10.5737 18.2599 10.8229 18.1125C11.0721 17.9651 11.2772 17.7535 11.4167 17.4998M5 6.6665C5 5.34042 5.52678 4.06865 6.46447 3.13097C7.40215 2.19329 8.67392 1.6665 10 1.6665C11.3261 1.6665 12.5979 2.19329 13.5355 3.13097C14.4732 4.06865 15 5.34042 15 6.6665C15 12.4998 17.5 14.1665 17.5 14.1665H2.5C2.5 14.1665 5 12.4998 5 6.6665Z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n","import { cn } from '../utils/cn';\n\ntype BuildingIconProps = {\n className?: string;\n};\n\nexport function BuildingIcon({ className }: BuildingIconProps) {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden\n className={cn('shrink-0', className)}\n >\n <path\n d=\"M10 12h4\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M10 8h4\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M14 21v-3a2 2 0 0 0-4 0v3\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M6 10H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M6 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n","import { useEffect, type RefObject } from 'react';\n\nexport function useOnClickOutside<T extends HTMLElement>(\n ref: RefObject<T | null>,\n handler: () => void,\n enabled = true,\n) {\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n const onPointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!ref.current || !target || ref.current.contains(target)) {\n return;\n }\n\n handler();\n };\n\n document.addEventListener('mousedown', onPointerDown);\n document.addEventListener('touchstart', onPointerDown);\n\n return () => {\n document.removeEventListener('mousedown', onPointerDown);\n document.removeEventListener('touchstart', onPointerDown);\n };\n }, [enabled, handler, ref]);\n}\n","import { ChevronsUpDown } from 'lucide-react';\nimport { useCallback, useId, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\n\nimport { BuildingIcon } from '../icons/BuildingIcon';\nimport { useOnClickOutside } from '../hooks/useOnClickOutside';\nimport { cn } from '../utils/cn';\nimport type { AdminBuildingOption, AdminHeaderLabels } from './types';\n\nexport type BuildingSelectProps = {\n options: AdminBuildingOption[];\n value: string;\n labels: Pick<AdminHeaderLabels, 'selectBuilding'>;\n onChange?: (buildingId: string) => void;\n disabled?: boolean;\n className?: string;\n menuClassName?: string;\n buildingIcon?: ReactNode;\n chevronIcon?: ReactNode;\n};\n\nexport function BuildingSelect({\n options,\n value,\n labels,\n onChange,\n disabled = false,\n className,\n menuClassName,\n buildingIcon,\n chevronIcon,\n}: BuildingSelectProps) {\n const [open, setOpen] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const rootRef = useRef<HTMLDivElement>(null);\n const listboxId = useId();\n\n const selectedOption = options.find((option) => option.value === value);\n const displayLabel = selectedOption?.label ?? labels.selectBuilding;\n const selectableOptions = options.filter((option) => !option.disabled);\n\n const closeMenu = useCallback(() => {\n setOpen(false);\n setHighlightedIndex(-1);\n }, []);\n\n const openMenu = useCallback(() => {\n if (disabled || selectableOptions.length === 0) {\n return;\n }\n\n const selectedIndex = selectableOptions.findIndex((option) => option.value === value);\n setHighlightedIndex(selectedIndex >= 0 ? selectedIndex : 0);\n setOpen(true);\n }, [disabled, selectableOptions, value]);\n\n const selectOption = useCallback(\n (option: AdminBuildingOption) => {\n if (option.disabled) {\n return;\n }\n\n onChange?.(option.value);\n closeMenu();\n },\n [closeMenu, onChange],\n );\n\n useOnClickOutside(rootRef, closeMenu, open);\n\n const handleTriggerKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (disabled) {\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n case 'Enter':\n case ' ':\n event.preventDefault();\n openMenu();\n break;\n case 'Escape':\n closeMenu();\n break;\n default:\n break;\n }\n };\n\n const handleListKeyDown = (event: KeyboardEvent<HTMLUListElement>) => {\n if (!open || selectableOptions.length === 0) {\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n setHighlightedIndex((current) => (current + 1) % selectableOptions.length);\n break;\n case 'ArrowUp':\n event.preventDefault();\n setHighlightedIndex(\n (current) => (current - 1 + selectableOptions.length) % selectableOptions.length,\n );\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n if (highlightedIndex >= 0) {\n selectOption(selectableOptions[highlightedIndex]);\n }\n break;\n case 'Escape':\n event.preventDefault();\n closeMenu();\n break;\n case 'Tab':\n closeMenu();\n break;\n default:\n break;\n }\n };\n\n return (\n <div ref={rootRef} className={cn('relative w-57.5', className)}>\n <button\n type=\"button\"\n disabled={disabled}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={listboxId}\n aria-label={labels.selectBuilding}\n onClick={() => (open ? closeMenu() : openMenu())}\n onKeyDown={handleTriggerKeyDown}\n className={cn(\n 'flex h-11 w-full items-center gap-3 rounded-xl border border-storm-gray-50 bg-white p-3 text-left transition-colors',\n !disabled && 'cursor-pointer hover:bg-storm-gray-50/60',\n open && 'bg-storm-gray-50/60',\n disabled && 'cursor-not-allowed opacity-60',\n )}\n >\n {buildingIcon ?? <BuildingIcon className=\"shrink-0 text-navy\" />}\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium text-slate-blue\">\n {displayLabel}\n </span>\n {chevronIcon ?? (\n <ChevronsUpDown\n size={16}\n strokeWidth={1.75}\n className={cn(\n 'shrink-0 text-storm-gray-100 transition-transform duration-200',\n open && 'rotate-180',\n )}\n aria-hidden\n />\n )}\n </button>\n\n {open ? (\n <ul\n id={listboxId}\n role=\"listbox\"\n aria-label={labels.selectBuilding}\n tabIndex={-1}\n onKeyDown={handleListKeyDown}\n className={cn(\n 'absolute top-[calc(100%+4px)] left-0 z-50 flex w-full flex-col gap-1 overflow-hidden rounded-xl border border-storm-gray-50 bg-white p-2 shadow-[0_8px_24px_rgba(21,26,30,0.08)]',\n menuClassName,\n )}\n >\n {options.map((option) => {\n const selectableIndex = selectableOptions.findIndex(\n (selectable) => selectable.value === option.value,\n );\n const isSelected = option.value === value;\n const isHighlighted = selectableIndex === highlightedIndex;\n\n return (\n <li key={option.value} role=\"presentation\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n disabled={option.disabled}\n onMouseEnter={() => {\n if (!option.disabled && selectableIndex >= 0) {\n setHighlightedIndex(selectableIndex);\n }\n }}\n onClick={() => selectOption(option)}\n className={cn(\n 'flex w-full rounded-lg px-3 py-2.5 text-left text-sm font-medium text-slate-blue transition-colors',\n !option.disabled && 'cursor-pointer hover:bg-storm-gray-50',\n (isSelected || isHighlighted) && !option.disabled && 'bg-storm-gray-50',\n option.disabled && 'cursor-not-allowed opacity-50',\n )}\n >\n <span className=\"truncate\">{option.label}</span>\n </button>\n </li>\n );\n })}\n </ul>\n ) : null}\n </div>\n );\n}\n","import { Search } from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport type { StyleProp, ViewStyle } from 'react-native';\n\nimport { Input } from '../../components/Input';\nimport { BellIcon } from '../icons/BellIcon';\nimport { cn } from '../utils/cn';\nimport { BuildingSelect } from './BuildingSelect';\nimport type { AdminBuildingOption, AdminHeaderLabels } from './types';\n\nexport type AppHeaderProps = {\n title: string;\n labels: AdminHeaderLabels;\n buildingOptions: AdminBuildingOption[];\n selectedBuildingId: string;\n className?: string;\n buildingSelectClassName?: string;\n searchClassName?: string;\n notificationsButtonClassName?: string;\n searchValue?: string;\n searchFieldStyle?: StyleProp<ViewStyle>;\n buildingIcon?: ReactNode;\n notificationsIcon?: ReactNode;\n searchIcon?: ReactNode;\n buildingChevronIcon?: ReactNode;\n buildingSelectDisabled?: boolean;\n searchDisabled?: boolean;\n notificationsDisabled?: boolean;\n onBuildingChange?: (buildingId: string) => void;\n onNotificationsClick?: () => void;\n onSearchChange?: (value: string) => void;\n};\n\nconst defaultSearchFieldStyle: ViewStyle = {\n height: 44,\n minHeight: 44,\n maxHeight: 44,\n backgroundColor: 'transparent',\n padding: 12,\n width: 260,\n borderRadius: 12,\n};\n\nexport function AppHeader({\n title,\n labels,\n buildingOptions,\n selectedBuildingId,\n className,\n buildingSelectClassName,\n searchClassName,\n notificationsButtonClassName,\n searchValue,\n searchFieldStyle,\n buildingIcon,\n notificationsIcon,\n searchIcon,\n buildingChevronIcon,\n buildingSelectDisabled = false,\n searchDisabled = false,\n notificationsDisabled = false,\n onBuildingChange,\n onNotificationsClick,\n onSearchChange,\n}: AppHeaderProps) {\n return (\n <header\n className={cn(\n 'flex shrink-0 items-center justify-between gap-4 border-b border-storm-gray-50 bg-storm-gray-0 px-6 py-3',\n className,\n )}\n >\n <h1 className=\"truncate text-xl font-bold text-slate-blue\">{title}</h1>\n\n <div className=\"flex shrink-0 items-center gap-3\">\n <BuildingSelect\n options={buildingOptions}\n value={selectedBuildingId}\n labels={labels}\n onChange={onBuildingChange}\n disabled={buildingSelectDisabled}\n className={buildingSelectClassName}\n buildingIcon={buildingIcon}\n chevronIcon={buildingChevronIcon}\n />\n\n <Input\n leftIcon={searchIcon ?? <Search strokeWidth={1.75} />}\n placeholder={labels.searchPlaceholder}\n value={searchValue}\n onChangeText={(value) => onSearchChange?.(value)}\n editable={!searchDisabled}\n className={cn('w-65!', searchClassName)}\n containerStyle={{ width: 260, maxWidth: 260, flexShrink: 0 }}\n fieldStyle={searchFieldStyle ?? defaultSearchFieldStyle}\n accessibilityLabel={labels.searchPlaceholder}\n />\n\n <button\n type=\"button\"\n onClick={onNotificationsClick}\n disabled={notificationsDisabled}\n className={cn(\n 'h-11 cursor-pointer rounded-xl border border-storm-gray-50 p-3 text-slate-blue transition-colors hover:bg-storm-gray-50/60',\n notificationsDisabled && 'pointer-events-none opacity-60',\n notificationsButtonClassName,\n )}\n aria-label={labels.notifications}\n >\n {notificationsIcon ?? <BellIcon className=\"text-navy\" />}\n </button>\n </div>\n </header>\n );\n}\n","import { useEffect, useState } from 'react';\n\nexport function useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() => {\n if (typeof window === 'undefined') {\n return false;\n }\n\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n const mediaQuery = window.matchMedia(query);\n const handleChange = () => setMatches(mediaQuery.matches);\n\n handleChange();\n mediaQuery.addEventListener('change', handleChange);\n\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, [query]);\n\n return matches;\n}\n","import { NavLink } from 'react-router-dom';\n\nimport { cn } from '../utils/cn';\nimport type { AdminNavItem } from './types';\n\nexport type SidebarNavItemProps = {\n item: AdminNavItem;\n isOpen: boolean;\n onNavigate?: (item: AdminNavItem) => void;\n};\n\nexport function SidebarNavItem({ item, isOpen, onNavigate }: SidebarNavItemProps) {\n if (item.hidden) {\n return null;\n }\n\n const handleClick = () => {\n item.onClick?.();\n onNavigate?.(item);\n };\n\n return (\n <NavLink\n to={item.to}\n end={item.end}\n onClick={handleClick}\n aria-disabled={item.disabled}\n tabIndex={item.disabled ? -1 : undefined}\n className={({ isActive }) =>\n cn(\n 'relative flex items-center rounded-xl px-4 py-3 transition-[background-color,color,gap,padding] duration-300 ease-in-out',\n isOpen ? 'w-full gap-4' : 'justify-center gap-0 px-3',\n item.disabled && 'pointer-events-none opacity-50',\n isActive ? 'bg-black/12 text-white' : 'text-navy-100 hover:bg-white/5',\n )\n }\n >\n {({ isActive }) => (\n <>\n <span\n aria-hidden\n className={cn(\n 'absolute top-1.5 -left-1 h-8 w-2 rounded-full bg-white transition-[opacity,transform] duration-300 ease-in-out',\n isActive ? 'scale-100 opacity-100' : 'scale-75 opacity-0',\n )}\n />\n <span className=\"flex size-5 shrink-0 items-center justify-center\">{item.icon}</span>\n <span\n className={cn(\n 'overflow-hidden text-sm font-semibold whitespace-nowrap transition-[max-width,opacity] duration-300 ease-in-out',\n isOpen ? 'max-w-[180px] opacity-100' : 'max-w-0 opacity-0',\n )}\n >\n {item.label}\n </span>\n </>\n )}\n </NavLink>\n );\n}\n","import { LogOut } from 'lucide-react';\n\nimport { cn } from '../utils/cn';\nimport type { AdminSidebarUser } from './types';\n\nexport type SidebarUserCardProps = {\n user: AdminSidebarUser;\n isOpen: boolean;\n logoutLabel: string;\n onLogout?: () => void;\n className?: string;\n};\n\nfunction getInitials(fullName: string, email: string): string {\n const parts = fullName.trim().split(/\\s+/).filter(Boolean);\n if (parts.length > 0) {\n return parts\n .slice(0, 2)\n .map((part) => part[0]?.toUpperCase() ?? '')\n .join('');\n }\n\n return email.slice(0, 2).toUpperCase();\n}\n\nexport function SidebarUserCard({\n user,\n isOpen,\n logoutLabel,\n onLogout,\n className,\n}: SidebarUserCardProps) {\n const initials = user.initials ?? getInitials(user.fullName, user.email);\n\n return (\n <div\n className={cn(\n 'flex w-full items-center rounded-xl transition-[background-color,justify-content,gap,padding] duration-300 ease-in-out',\n isOpen ? 'justify-between gap-3 bg-black/12 p-3' : 'justify-center px-3 py-3',\n className,\n )}\n >\n <div\n className=\"flex size-11 shrink-0 items-center justify-center rounded-full bg-white/5 text-sm font-bold text-white\"\n aria-hidden\n >\n {initials}\n </div>\n {isOpen ? (\n <>\n <div className=\"flex min-w-0 flex-1 flex-col overflow-hidden\">\n <p className=\"truncate text-sm font-bold text-white\">{user.fullName}</p>\n <p className=\"truncate text-xs text-storm-gray-100\">{user.email}</p>\n </div>\n <button\n type=\"button\"\n onClick={() => onLogout?.()}\n className=\"shrink-0 cursor-pointer text-navy-150 transition-[opacity,transform] duration-300 ease-in-out hover:opacity-80 active:scale-95\"\n aria-label={logoutLabel}\n >\n <LogOut size={20} strokeWidth={1.75} />\n </button>\n </>\n ) : null}\n </div>\n );\n}\n","import { PanelLeftClose, PanelLeftOpen, X } from 'lucide-react';\nimport { useCallback, useEffect, useRef, useState, type ReactNode } from 'react';\nimport { useLocation } from 'react-router-dom';\n\nimport { useMediaQuery } from '../hooks/useMediaQuery';\nimport { cn } from '../utils/cn';\nimport { SidebarNavItem } from './SidebarNavItem';\nimport { SidebarUserCard } from './SidebarUserCard';\nimport type { AdminNavItem, AdminSidebarBranding, AdminSidebarLabels, AdminSidebarUser } from './types';\n\nexport type SidebarProps = {\n navItems: AdminNavItem[];\n footerNavItems: AdminNavItem[];\n branding: AdminSidebarBranding;\n labels: AdminSidebarLabels;\n sidebarStorageKey: string;\n user?: AdminSidebarUser;\n onLogout?: () => void;\n className?: string;\n mobileOpen: boolean;\n onMobileClose?: () => void;\n onNavItemClick?: (item: AdminNavItem) => void;\n collapseIcon?: ReactNode;\n expandIcon?: ReactNode;\n closeIcon?: ReactNode;\n initialCollapsed?: boolean;\n collapsed?: boolean;\n onCollapsedChange?: (collapsed: boolean) => void;\n};\n\nfunction readInitialCollapsedState(storageKey: string, initialCollapsed?: boolean): boolean {\n if (initialCollapsed !== undefined) {\n return initialCollapsed;\n }\n\n if (typeof window === 'undefined') {\n return false;\n }\n\n const stored = window.localStorage.getItem(storageKey);\n if (stored === null) {\n return false;\n }\n\n return stored !== 'true';\n}\n\nexport function Sidebar({\n navItems,\n footerNavItems,\n branding,\n labels,\n sidebarStorageKey,\n user,\n onLogout,\n className,\n mobileOpen,\n onMobileClose,\n onNavItemClick,\n collapseIcon,\n expandIcon,\n closeIcon,\n initialCollapsed,\n collapsed,\n onCollapsedChange,\n}: SidebarProps) {\n const location = useLocation();\n const isDesktop = useMediaQuery('(min-width: 768px)');\n const [internalCollapsed, setInternalCollapsed] = useState(() =>\n readInitialCollapsedState(sidebarStorageKey, initialCollapsed),\n );\n\n const isCollapsed = collapsed ?? internalCollapsed;\n const isExpanded = isDesktop ? !isCollapsed : true;\n\n const setCollapsed = useCallback(\n (next: boolean) => {\n if (collapsed === undefined) {\n setInternalCollapsed(next);\n window.localStorage.setItem(sidebarStorageKey, String(!next));\n }\n\n onCollapsedChange?.(next);\n },\n [collapsed, onCollapsedChange, sidebarStorageKey],\n );\n\n const toggleCollapsed = useCallback(() => {\n setCollapsed(!isCollapsed);\n }, [isCollapsed, setCollapsed]);\n\n const handleHeaderAction = useCallback(() => {\n if (isDesktop) {\n toggleCollapsed();\n\n return;\n }\n\n onMobileClose?.();\n }, [isDesktop, onMobileClose, toggleCollapsed]);\n\n const handleNavItemNavigate = useCallback(\n (item: AdminNavItem) => {\n onNavItemClick?.(item);\n\n if (!isDesktop) {\n onMobileClose?.();\n }\n },\n [isDesktop, onMobileClose, onNavItemClick],\n );\n\n const pathnameRef = useRef(location.pathname);\n\n useEffect(() => {\n if (pathnameRef.current === location.pathname) {\n return;\n }\n\n pathnameRef.current = location.pathname;\n\n if (!isDesktop) {\n onMobileClose?.();\n }\n }, [location.pathname, isDesktop, onMobileClose]);\n\n useEffect(() => {\n if (!mobileOpen || isDesktop) {\n return;\n }\n\n const previousOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n\n return () => {\n document.body.style.overflow = previousOverflow;\n };\n }, [mobileOpen, isDesktop]);\n\n const visibleNavItems = navItems.filter((item) => !item.hidden);\n const visibleFooterNavItems = footerNavItems.filter((item) => !item.hidden);\n\n return (\n <>\n <button\n type=\"button\"\n aria-label={labels.closeMenu}\n onClick={onMobileClose}\n className={cn(\n 'fixed inset-0 z-40 bg-navy-800/60 backdrop-blur-[1px] transition-opacity duration-300 ease-in-out md:hidden',\n mobileOpen ? 'opacity-100' : 'pointer-events-none opacity-0',\n )}\n />\n\n <aside\n className={cn(\n 'fixed inset-y-0 left-0 z-50 flex h-screen w-[min(300px,85vw)] flex-col gap-8 overflow-hidden bg-navy p-4 shadow-xl',\n 'transition-[transform,width,padding,gap] duration-300 ease-in-out will-change-[transform,width]',\n mobileOpen ? 'translate-x-0' : '-translate-x-full',\n 'md:relative md:z-auto md:w-[300px] md:translate-x-0 md:shadow-none',\n isExpanded ? 'md:w-[300px]' : 'md:w-[76px] md:items-center md:gap-2 md:px-3 md:py-4',\n className,\n )}\n aria-hidden={!isDesktop && !mobileOpen}\n >\n <div\n className={cn(\n 'flex w-full items-center transition-[justify-content] duration-300 ease-in-out',\n isExpanded ? 'justify-between' : 'justify-center',\n )}\n >\n <div\n className={cn(\n 'flex min-w-0 items-center gap-1.5 overflow-hidden transition-[max-width,opacity] duration-300 ease-in-out',\n isExpanded ? 'max-w-[240px] opacity-100' : 'max-w-0 opacity-0',\n )}\n >\n <img src={branding.logoIconSrc} alt=\"\" className=\"h-5 w-[29px] shrink-0\" />\n <div className=\"flex min-w-0 flex-col leading-none\">\n <span className=\"text-[21px] font-bold tracking-tight whitespace-nowrap text-white\">\n {branding.logoTitle}\n </span>\n <span className=\"text-[6.5px] font-normal tracking-[-0.26px] text-navy-300 uppercase\">\n {branding.logoTagline}\n </span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={handleHeaderAction}\n className=\"shrink-0 cursor-pointer text-white transition-[opacity,transform] duration-200 hover:opacity-80 active:scale-95\"\n aria-label={\n isDesktop\n ? isExpanded\n ? labels.collapse\n : labels.expand\n : labels.closeMenu\n }\n >\n {isDesktop ? (\n isExpanded ? (\n collapseIcon ?? <PanelLeftClose size={20} strokeWidth={1.75} />\n ) : (\n expandIcon ?? <PanelLeftOpen size={20} strokeWidth={1.75} />\n )\n ) : (\n closeIcon ?? <X size={20} strokeWidth={1.75} />\n )}\n </button>\n </div>\n\n <nav className=\"flex flex-1 flex-col gap-2 overflow-y-auto overflow-x-hidden\">\n {visibleNavItems.map((item) => (\n <SidebarNavItem\n key={item.to}\n item={item}\n isOpen={isExpanded}\n onNavigate={handleNavItemNavigate}\n />\n ))}\n </nav>\n\n <div className=\"flex w-full flex-col gap-4\">\n {visibleFooterNavItems.map((item) => (\n <SidebarNavItem\n key={item.to}\n item={item}\n isOpen={isExpanded}\n onNavigate={handleNavItemNavigate}\n />\n ))}\n {user ? (\n <SidebarUserCard\n user={user}\n isOpen={isExpanded}\n logoutLabel={labels.logout}\n onLogout={onLogout}\n />\n ) : null}\n </div>\n </aside>\n </>\n );\n}\n","import { Menu } from 'lucide-react';\n\nimport { cn } from '../utils/cn';\nimport type { AdminSidebarBranding } from './types';\n\nexport type SidebarMobileHeaderProps = {\n branding: Pick<AdminSidebarBranding, 'logoIconSrc' | 'logoTitle' | 'logoTagline'>;\n openMenuLabel: string;\n onOpenMenu: () => void;\n menuOpen?: boolean;\n className?: string;\n};\n\nexport function SidebarMobileHeader({\n branding,\n openMenuLabel,\n onOpenMenu,\n menuOpen = false,\n className,\n}: SidebarMobileHeaderProps) {\n return (\n <header\n className={cn(\n 'sticky top-0 z-30 flex h-14 shrink-0 items-center gap-3 border-b border-storm-gray-50 bg-storm-gray-0 px-4 md:hidden',\n className,\n )}\n >\n <button\n type=\"button\"\n onClick={onOpenMenu}\n className=\"flex size-10 items-center justify-center rounded-xl text-navy transition-colors hover:bg-storm-gray-50\"\n aria-label={openMenuLabel}\n aria-expanded={menuOpen}\n >\n <Menu size={22} strokeWidth={1.75} />\n </button>\n <div className=\"flex min-w-0 items-center gap-2\">\n <img src={branding.logoIconSrc} alt=\"\" className=\"h-[30px] w-[42px] shrink-0\" />\n <div className=\"min-w-0 leading-none\">\n <p className=\"truncate text-base font-bold tracking-tight text-navy\">{branding.logoTitle}</p>\n <p className=\"truncate text-[6.5px] font-normal tracking-[-0.26px] text-navy-300 uppercase\">\n {branding.logoTagline}\n </p>\n </div>\n </div>\n </header>\n );\n}\n","import type { ReactNode } from 'react';\n\nimport { AppHeader } from './AppHeader';\nimport type { AppHeaderProps } from './AppHeader';\nimport { Sidebar } from './Sidebar';\nimport type { SidebarProps } from './Sidebar';\nimport { SidebarMobileHeader } from './SidebarMobileHeader';\nimport type { SidebarMobileHeaderProps } from './SidebarMobileHeader';\n\nimport { cn } from '../utils/cn';\n\nexport type DashboardLayoutProps = {\n sidebar: SidebarProps;\n header: AppHeaderProps;\n mobileHeader: SidebarMobileHeaderProps;\n children: ReactNode;\n className?: string;\n mainClassName?: string;\n};\n\nexport function DashboardLayout({\n sidebar,\n header,\n mobileHeader,\n children,\n className,\n mainClassName,\n}: DashboardLayoutProps) {\n return (\n <div className={cn('flex min-h-screen flex-row bg-storm-gray-0', className)}>\n <div className=\"shrink-0\">\n <Sidebar {...sidebar} />\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <SidebarMobileHeader {...mobileHeader} />\n <AppHeader {...header} />\n <main className={mainClassName ?? 'flex-1 overflow-auto p-4 md:p-6'}>{children}</main>\n </div>\n </div>\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scripso-homepad/ui",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "type": "module",
5
5
  "description": "Cross-platform UI components for Homepad (React Web + React Native)",
6
6
  "license": "MIT",
@@ -56,6 +56,8 @@ export interface InputProps extends TextInputProps {
56
56
  rightIcon?: ReactNode;
57
57
  /** Validation or helper error message. Shown instead of `hint` when set. */
58
58
  error?: string;
59
+ /** Applies error field styling without showing a message (use with a form-level error). */
60
+ invalid?: boolean;
59
61
  /** Helper text shown below the input when there is no error. */
60
62
  hint?: string;
61
63
  containerStyle?: StyleProp<ViewStyle>;
@@ -78,6 +80,7 @@ export function Input({
78
80
  leftIcon,
79
81
  rightIcon,
80
82
  error,
83
+ invalid,
81
84
  hint,
82
85
  containerStyle,
83
86
  style,
@@ -108,6 +111,7 @@ export function Input({
108
111
  useApplyWebClassName(helperRef, error ? errorClassName : hintClassName);
109
112
 
110
113
  const isDisabled = editable === false;
114
+ const hasError = Boolean(error) || Boolean(invalid);
111
115
  const passwordToggleEnabled =
112
116
  secureTextEntry === true && showPasswordToggle !== false && rightIcon == null;
113
117
  const effectiveSecureTextEntry = passwordToggleEnabled
@@ -115,7 +119,7 @@ export function Input({
115
119
  : secureTextEntry;
116
120
  const visualState = resolveInputVisualState({
117
121
  focused,
118
- error: Boolean(error),
122
+ error: hasError,
119
123
  disabled: isDisabled,
120
124
  });
121
125
  const fieldStyles = getInputFieldStyles(visualState);
@@ -0,0 +1,30 @@
1
+ import Svg, { Path } from "react-native-svg";
2
+
3
+ import { LOCK_ICON_PATH } from "./lockIconPaths";
4
+
5
+ export { LOCK_ICON_PATH } from "./lockIconPaths";
6
+
7
+ interface LockIconProps {
8
+ size?: number;
9
+ color?: string;
10
+ strokeWidth?: number;
11
+ }
12
+
13
+ /** Native — react-native-svg (peer dependency). */
14
+ export function LockIcon({
15
+ size = 20,
16
+ color = "#c7cdd1",
17
+ strokeWidth = 2,
18
+ }: LockIconProps) {
19
+ return (
20
+ <Svg width={size} height={size} viewBox="0 0 20 20" fill="none">
21
+ <Path
22
+ d={LOCK_ICON_PATH}
23
+ stroke={color}
24
+ strokeWidth={strokeWidth}
25
+ strokeLinecap="round"
26
+ strokeLinejoin="round"
27
+ />
28
+ </Svg>
29
+ );
30
+ }
@@ -0,0 +1,35 @@
1
+ import { LOCK_ICON_PATH } from "./lockIconPaths";
2
+
3
+ interface LockIconProps {
4
+ size?: number;
5
+ color?: string;
6
+ strokeWidth?: number;
7
+ }
8
+
9
+ /** Web / Storybook — plain SVG (no react-native-svg). */
10
+ export function LockIcon({
11
+ size = 20,
12
+ color = "#c7cdd1",
13
+ strokeWidth = 2,
14
+ }: LockIconProps) {
15
+ return (
16
+ <svg
17
+ width={size}
18
+ height={size}
19
+ viewBox="0 0 20 20"
20
+ fill="none"
21
+ xmlns="http://www.w3.org/2000/svg"
22
+ aria-hidden
23
+ >
24
+ <path
25
+ d={LOCK_ICON_PATH}
26
+ stroke={color}
27
+ strokeWidth={strokeWidth}
28
+ strokeLinecap="round"
29
+ strokeLinejoin="round"
30
+ />
31
+ </svg>
32
+ );
33
+ }
34
+
35
+ export { LOCK_ICON_PATH } from "./lockIconPaths";
@@ -0,0 +1,2 @@
1
+ export const LOCK_ICON_PATH =
2
+ "M5.83333 8.33317V5.83317C5.83333 4.7281 6.27232 3.66829 7.05372 2.88689C7.83512 2.10549 8.89493 1.6665 10 1.6665C11.1051 1.6665 12.1649 2.10549 12.9463 2.88689C13.7277 3.66829 14.1667 4.7281 14.1667 5.83317V8.33317M10.8333 13.3332C10.8333 13.7934 10.4602 14.1665 10 14.1665C9.53976 14.1665 9.16667 13.7934 9.16667 13.3332C9.16667 12.8729 9.53976 12.4998 10 12.4998C10.4602 12.4998 10.8333 12.8729 10.8333 13.3332ZM4.16667 8.33317H15.8333C16.7538 8.33317 17.5 9.07936 17.5 9.99984V16.6665C17.5 17.587 16.7538 18.3332 15.8333 18.3332H4.16667C3.24619 18.3332 2.5 17.587 2.5 16.6665V9.99984C2.5 9.07936 3.24619 8.33317 4.16667 8.33317Z";
package/src/index.ts CHANGED
@@ -24,6 +24,8 @@ export type { Country } from "./data/countries";
24
24
  export { Label } from "./components/Label";
25
25
  export type { LabelProps } from "./components/Label";
26
26
 
27
+ export { LockIcon } from "./icons/LockIcon";
28
+
27
29
  export {
28
30
  colors,
29
31
  brand,
@@ -5,6 +5,10 @@ export const INPUT_HEIGHT = 52;
5
5
  export const INPUT_ICON_SIZE = 20;
6
6
  export const INPUT_ICON_GAP = 10;
7
7
  export const INPUT_OUTLINE_WIDTH = 2;
8
+ /** Native line box; web uses a taller metric for Noto Sans Armenian descenders. */
9
+ export const INPUT_INNER_LINE_HEIGHT = 20;
10
+ export const INPUT_WEB_INNER_LINE_HEIGHT = 22;
11
+ export const INPUT_WEB_VERTICAL_PADDING = 14;
8
12
 
9
13
  export type InputVisualState =
10
14
  | "default"
@@ -125,16 +129,20 @@ export const inputFieldMetrics = StyleSheet.create({
125
129
  padding: 16,
126
130
  gap: INPUT_ICON_GAP,
127
131
  ...(Platform.OS === "web"
128
- ? ({ boxSizing: "border-box" } as ViewStyle)
132
+ ? ({
133
+ boxSizing: "border-box",
134
+ paddingVertical: INPUT_WEB_VERTICAL_PADDING,
135
+ paddingHorizontal: 16,
136
+ } as ViewStyle)
129
137
  : null),
130
138
  },
131
139
  input: {
132
140
  flex: 1,
133
- alignSelf: "stretch",
141
+ minWidth: 0,
134
142
  fontFamily: fonts.sans,
135
143
  fontSize: fontSize.md,
136
144
  fontWeight: fontWeight.medium,
137
- lineHeight: Platform.OS === "web" ? fontSize.md : 20,
145
+ lineHeight: INPUT_INNER_LINE_HEIGHT,
138
146
  paddingVertical: 0,
139
147
  paddingHorizontal: 0,
140
148
  margin: 0,
@@ -145,10 +153,12 @@ export const inputFieldMetrics = StyleSheet.create({
145
153
  : null),
146
154
  ...(Platform.OS === "web"
147
155
  ? ({
148
- height: "100%",
149
- minHeight: 0,
156
+ alignSelf: "center",
157
+ lineHeight: INPUT_WEB_INNER_LINE_HEIGHT,
150
158
  outlineStyle: "none",
151
159
  } as TextStyle)
152
- : null),
160
+ : {
161
+ alignSelf: "stretch",
162
+ }),
153
163
  },
154
164
  });
@@ -7,6 +7,8 @@ import type { SidebarProps } from './Sidebar';
7
7
  import { SidebarMobileHeader } from './SidebarMobileHeader';
8
8
  import type { SidebarMobileHeaderProps } from './SidebarMobileHeader';
9
9
 
10
+ import { cn } from '../utils/cn';
11
+
10
12
  export type DashboardLayoutProps = {
11
13
  sidebar: SidebarProps;
12
14
  header: AppHeaderProps;
@@ -25,8 +27,10 @@ export function DashboardLayout({
25
27
  mainClassName,
26
28
  }: DashboardLayoutProps) {
27
29
  return (
28
- <div className={className ?? 'flex min-h-screen bg-storm-gray-0'}>
29
- <Sidebar {...sidebar} />
30
+ <div className={cn('flex min-h-screen flex-row bg-storm-gray-0', className)}>
31
+ <div className="shrink-0">
32
+ <Sidebar {...sidebar} />
33
+ </div>
30
34
  <div className="flex min-w-0 flex-1 flex-col">
31
35
  <SidebarMobileHeader {...mobileHeader} />
32
36
  <AppHeader {...header} />
@@ -158,7 +158,7 @@ export function Sidebar({
158
158
  'transition-[transform,width,padding,gap] duration-300 ease-in-out will-change-[transform,width]',
159
159
  mobileOpen ? 'translate-x-0' : '-translate-x-full',
160
160
  'md:relative md:z-auto md:w-[300px] md:translate-x-0 md:shadow-none',
161
- isExpanded ? 'md:w-[300px]' : 'md:w-[52px] md:items-center md:gap-4 md:px-3 md:py-4',
161
+ isExpanded ? 'md:w-[300px]' : 'md:w-[76px] md:items-center md:gap-2 md:px-3 md:py-4',
162
162
  className,
163
163
  )}
164
164
  aria-hidden={!isDesktop && !mobileOpen}
@@ -35,45 +35,33 @@ export function SidebarUserCard({
35
35
  return (
36
36
  <div
37
37
  className={cn(
38
- 'flex w-full items-center rounded-xl p-3 transition-[background-color,justify-content,gap] duration-300 ease-in-out',
39
- isOpen ? 'justify-between gap-3 bg-black/12' : 'justify-center',
38
+ 'flex w-full items-center rounded-xl transition-[background-color,justify-content,gap,padding] duration-300 ease-in-out',
39
+ isOpen ? 'justify-between gap-3 bg-black/12 p-3' : 'justify-center px-3 py-3',
40
40
  className,
41
41
  )}
42
42
  >
43
43
  <div
44
- className={cn(
45
- 'flex min-w-0 items-center transition-[gap,flex] duration-300 ease-in-out',
46
- isOpen ? 'flex-1 gap-3' : 'gap-0',
47
- )}
44
+ className="flex size-11 shrink-0 items-center justify-center rounded-full bg-white/5 text-sm font-bold text-white"
45
+ aria-hidden
48
46
  >
49
- <div
50
- className="flex size-11 shrink-0 items-center justify-center rounded-full bg-white/5 text-sm font-bold text-white"
51
- aria-hidden
52
- >
53
- {initials}
54
- </div>
55
- <div
56
- className={cn(
57
- 'min-w-0 overflow-hidden transition-[max-width,opacity] duration-300 ease-in-out',
58
- isOpen ? 'max-w-[160px] opacity-100' : 'max-w-0 opacity-0',
59
- )}
60
- >
61
- <p className="truncate text-sm font-bold text-white">{user.fullName}</p>
62
- <p className="truncate text-xs text-storm-gray-100">{user.email}</p>
63
- </div>
47
+ {initials}
64
48
  </div>
65
- <button
66
- type="button"
67
- onClick={() => onLogout?.()}
68
- className={cn(
69
- 'shrink-0 cursor-pointer text-navy-150 transition-[opacity,transform,max-width] duration-300 ease-in-out hover:opacity-80 active:scale-95',
70
- isOpen ? 'max-w-8 scale-100 opacity-100' : 'pointer-events-none max-w-0 scale-90 opacity-0',
71
- )}
72
- aria-label={logoutLabel}
73
- tabIndex={isOpen ? 0 : -1}
74
- >
75
- <LogOut size={20} strokeWidth={1.75} />
76
- </button>
49
+ {isOpen ? (
50
+ <>
51
+ <div className="flex min-w-0 flex-1 flex-col overflow-hidden">
52
+ <p className="truncate text-sm font-bold text-white">{user.fullName}</p>
53
+ <p className="truncate text-xs text-storm-gray-100">{user.email}</p>
54
+ </div>
55
+ <button
56
+ type="button"
57
+ onClick={() => onLogout?.()}
58
+ className="shrink-0 cursor-pointer text-navy-150 transition-[opacity,transform] duration-300 ease-in-out hover:opacity-80 active:scale-95"
59
+ aria-label={logoutLabel}
60
+ >
61
+ <LogOut size={20} strokeWidth={1.75} />
62
+ </button>
63
+ </>
64
+ ) : null}
77
65
  </div>
78
66
  );
79
67
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/theme/tokens.ts","../src/utils/useApplyWebClassName.ts","../src/components/Label.tsx","../src/icons/eyeIconPaths.ts","../src/icons/EyeIcon.tsx","../src/icons/EyeOffIcon.tsx","../src/theme/input.ts","../src/components/Input.tsx"],"names":["jsxs","jsx","Svg","Path","Platform","StyleSheet","useRef","styles","Text"],"mappings":"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","file":"chunk-C7GHBVMM.js","sourcesContent":["/**\n * HomePad design tokens — aligned with the Figma design system\n * (navy / storm gray / slate-blue palette from HomePad brand).\n */\n\n/** Storm Gray scale — Figma steps 0 → 8.5 */\nexport const stormGray = {\n \"0\": \"#fbfcfc\",\n \"0.5\": \"#eceef0\",\n \"1\": \"#dadde0\",\n \"1.5\": \"#c7cdd1\",\n \"2\": \"#b5bcc1\",\n \"3\": \"#8f9aa3\",\n \"4\": \"#6a7984\",\n \"5\": \"#455765\",\n \"6\": \"#374651\",\n \"7\": \"#29343d\",\n \"8\": \"#1c2328\",\n \"8.5\": \"#151a1e\",\n} as const;\n\nexport type StormGrayStep = keyof typeof stormGray;\n\n/** Navy scale — Figma steps 0 → 8.5 */\nexport const navy = {\n \"0\": \"#f8f9fb\",\n \"0.5\": \"#e5e9ef\",\n \"1\": \"#cdd3df\",\n \"1.5\": \"#b4bece\",\n \"2\": \"#9ca8be\",\n \"3\": \"#6a7d9e\",\n \"4\": \"#39527d\",\n \"5\": \"#08275d\",\n \"6\": \"#061f4a\",\n \"7\": \"#051738\",\n \"8\": \"#031025\",\n \"8.5\": \"#020c1c\",\n} as const;\n\nexport type NavyStep = keyof typeof navy;\n\n/** Ruby Red scale — Figma steps 0 → 8.5 */\nexport const rubyRed = {\n \"0\": \"#fff5f6\",\n \"0.5\": \"#f7dddf\",\n \"1\": \"#efc4c8\",\n \"1.5\": \"#e7acb1\",\n \"2\": \"#df939a\",\n \"3\": \"#ce626d\",\n \"4\": \"#be313f\",\n \"5\": \"#ae0011\",\n \"6\": \"#8b000e\",\n \"7\": \"#68000a\",\n \"8\": \"#460007\",\n \"8.5\": \"#340005\",\n} as const;\n\nexport type RubyRedStep = keyof typeof rubyRed;\n\n/** Emerald Green scale — Figma steps 0 → 8.5 */\nexport const emeraldGreen = {\n \"0\": \"#f0fbf5\",\n \"0.5\": \"#dcf2e5\",\n \"1\": \"#c8e8d5\",\n \"1.5\": \"#b4dfc5\",\n \"2\": \"#a0d5b5\",\n \"3\": \"#77c394\",\n \"4\": \"#4fb074\",\n \"5\": \"#279d54\",\n \"6\": \"#1f7e43\",\n \"7\": \"#175e32\",\n \"8\": \"#103f22\",\n \"8.5\": \"#0c2f19\",\n} as const;\n\nexport type EmeraldGreenStep = keyof typeof emeraldGreen;\n\n/** Figma brand palette — primary swatch per color family */\nexport const brand = {\n slateBlue: \"#182e3c\",\n stormGray: stormGray[\"5\"],\n navy: navy[\"5\"],\n rubyRed: rubyRed[\"5\"],\n emeraldGreen: emeraldGreen[\"5\"],\n} as const;\n\nexport const colors = {\n // Brand colors\n slateBlue: brand.slateBlue,\n\n // Emerald Green — Figma scale + brand swatch\n emeraldGreen0: emeraldGreen[\"0\"],\n emeraldGreen50: emeraldGreen[\"0.5\"],\n emeraldGreen100: emeraldGreen[\"1\"],\n emeraldGreen150: emeraldGreen[\"1.5\"],\n emeraldGreen200: emeraldGreen[\"2\"],\n emeraldGreen300: emeraldGreen[\"3\"],\n emeraldGreen400: emeraldGreen[\"4\"],\n emeraldGreen500: emeraldGreen[\"5\"],\n emeraldGreen600: emeraldGreen[\"6\"],\n emeraldGreen700: emeraldGreen[\"7\"],\n emeraldGreen800: emeraldGreen[\"8\"],\n emeraldGreen850: emeraldGreen[\"8.5\"],\n\n /** Primary brand emerald green — Figma Emerald Green 5 */\n emeraldGreen: brand.emeraldGreen,\n\n // Ruby Red — Figma scale + brand swatch\n rubyRed0: rubyRed[\"0\"],\n rubyRed50: rubyRed[\"0.5\"],\n rubyRed100: rubyRed[\"1\"],\n rubyRed150: rubyRed[\"1.5\"],\n rubyRed200: rubyRed[\"2\"],\n rubyRed300: rubyRed[\"3\"],\n rubyRed400: rubyRed[\"4\"],\n rubyRed500: rubyRed[\"5\"],\n rubyRed600: rubyRed[\"6\"],\n rubyRed700: rubyRed[\"7\"],\n rubyRed800: rubyRed[\"8\"],\n rubyRed850: rubyRed[\"8.5\"],\n\n /** Primary brand ruby red — Figma Ruby Red 5 */\n rubyRed: brand.rubyRed,\n\n // Navy — Figma scale + brand swatch\n navy0: navy[\"0\"],\n navy50: navy[\"0.5\"],\n navy100: navy[\"1\"],\n navy150: navy[\"1.5\"],\n navy200: navy[\"2\"],\n navy300: navy[\"3\"],\n navy400: navy[\"4\"],\n navy500: navy[\"5\"],\n navy600: navy[\"6\"],\n navy700: navy[\"7\"],\n navy800: navy[\"8\"],\n navy850: navy[\"8.5\"],\n\n /** Primary brand navy — Figma Navy 5 */\n navy: brand.navy,\n\n // Storm Gray — Figma scale + brand swatch\n stormGray0: stormGray[\"0\"],\n stormGray50: stormGray[\"0.5\"],\n stormGray100: stormGray[\"1\"],\n stormGray150: stormGray[\"1.5\"],\n stormGray200: stormGray[\"2\"],\n stormGray300: stormGray[\"3\"],\n stormGray400: stormGray[\"4\"],\n stormGray500: stormGray[\"5\"],\n /** Figma brand swatch \"Storm Gray\" — same as `stormGray500` */\n stormGrayBrand: brand.stormGray,\n stormGray600: stormGray[\"6\"],\n stormGray700: stormGray[\"7\"],\n stormGray800: stormGray[\"8\"],\n stormGray850: stormGray[\"8.5\"],\n\n /** @deprecated Use `stormGray0` */\n storm0: stormGray[\"0\"],\n /** @deprecated Use `stormGray50` */\n storm50: stormGray[\"0.5\"],\n /** @deprecated Use `stormGray200` */\n storm200: stormGray[\"2\"],\n /** @deprecated Use `stormGray300` */\n storm300: stormGray[\"3\"],\n /** @deprecated Use `stormGray500` */\n storm500: stormGray[\"5\"],\n /** @deprecated Use `stormGray700` */\n storm700: stormGray[\"7\"],\n /** @deprecated Use `stormGray850` */\n storm900: stormGray[\"8.5\"],\n\n countrySelectorSelectedBg: `${stormGray[\"0.5\"]}99`,\n\n white: \"#ffffff\",\n error: \"#dc2626\",\n errorDark: \"#b3261e\",\n errorLight: \"#fee2e2\",\n /** @deprecated Use `rubyRed` */\n inputError: brand.rubyRed,\n inputOutlineFocus: navy[\"0.5\"],\n inputOutlineError: rubyRed[\"0.5\"],\n warning: \"#92400e\",\n warningBg: \"#fef3c7\",\n success: \"#28a745\",\n successMuted: \"#9fd4a8\",\n /** @deprecated Use `emeraldGreen` */\n green: brand.emeraldGreen,\n transparent: \"transparent\",\n} as const;\n\nexport const radii = {\n sm: 8,\n md: 12,\n lg: 16,\n xl: 20,\n full: 9999,\n} as const;\n\nexport const spacing = {\n xs: 4,\n sm: 8,\n md: 12,\n lg: 16,\n xl: 24,\n xxl: 32,\n} as const;\n\nexport const fontSize = {\n xs: 11,\n sm: 12,\n md: 14,\n base: 16,\n lg: 18,\n xl: 24,\n xxl: 32,\n} as const;\n\nexport const fontWeight = {\n regular: \"400\" as const,\n medium: \"500\" as const,\n semibold: \"600\" as const,\n bold: \"700\" as const,\n};\n\nexport const fonts = {\n sans: \"Noto Sans Armenian\",\n} as const;\n\n/** Input label typography — matches Figma (Medium, 100% line-height). */\nexport const labelTypography = {\n fontFamily: fonts.sans,\n fontSize: fontSize.sm,\n fontWeight: fontWeight.medium,\n lineHeight: fontSize.sm,\n letterSpacing: 0,\n} as const;\n\n/** Button label typography — SemiBold; line-height slightly above 100% for RN clipping. */\nexport const buttonTypography = {\n lg: {\n fontFamily: fonts.sans,\n fontSize: 14,\n fontWeight: fontWeight.semibold,\n lineHeight: 18,\n letterSpacing: 0,\n },\n sm: {\n fontFamily: fonts.sans,\n fontSize: 12,\n fontWeight: fontWeight.semibold,\n lineHeight: 16,\n letterSpacing: 0,\n },\n} as const;\n\nexport const shadows = {\n card: {\n shadowColor: colors.navy,\n shadowOffset: { width: 0, height: 4 },\n shadowOpacity: 0.05,\n shadowRadius: 20,\n elevation: 2,\n },\n cardLg: {\n shadowColor: colors.navy,\n shadowOffset: { width: 0, height: 4 },\n shadowOpacity: 0.1,\n shadowRadius: 20,\n elevation: 4,\n },\n} as const;\n","import { useLayoutEffect } from \"react\";\nimport { Platform } from \"react-native\";\n\ninterface ClassListElement {\n classList: {\n add: (...classes: string[]) => void;\n remove: (...classes: string[]) => void;\n };\n}\n\nfunction hasClassList(node: unknown): node is ClassListElement {\n return (\n typeof node === \"object\" &&\n node !== null &&\n \"classList\" in node &&\n typeof (node as ClassListElement).classList?.add === \"function\"\n );\n}\n\nfunction resolveWebElement(ref: React.RefObject<unknown>): ClassListElement | null {\n const node = ref.current;\n if (!node) return null;\n\n if (hasClassList(node)) return node;\n\n const host = node as {\n _touchableNode?: unknown;\n getScrollableNode?: () => unknown;\n };\n\n if (hasClassList(host._touchableNode)) return host._touchableNode;\n\n if (typeof host.getScrollableNode === \"function\") {\n const scrollNode = host.getScrollableNode();\n if (hasClassList(scrollNode)) return scrollNode;\n }\n\n return null;\n}\n\n/**\n * Applies CSS class names to the underlying DOM node on web.\n * Keeps TouchableOpacity/Text as the render path so default RN styles stay intact.\n */\nexport function useApplyWebClassName(\n ref: React.RefObject<unknown>,\n className?: string,\n enabled = true,\n): void {\n useLayoutEffect(() => {\n if (!enabled || Platform.OS !== \"web\" || !className?.trim()) return;\n\n const element = resolveWebElement(ref);\n if (!element) return;\n\n const classes = className.trim().split(/\\s+/);\n element.classList.add(...classes);\n\n return () => {\n element.classList.remove(...classes);\n };\n }, [ref, className, enabled]);\n}\n","import { useRef, type ComponentRef, type ReactNode } from \"react\";\nimport {\n StyleSheet,\n Text,\n type StyleProp,\n type TextProps,\n type TextStyle,\n} from \"react-native\";\nimport { colors, labelTypography } from \"../theme/tokens\";\nimport { useApplyWebClassName } from \"../utils/useApplyWebClassName\";\n\nexport interface LabelProps extends TextProps {\n children: ReactNode;\n /** Render as a required field indicator. */\n required?: boolean;\n disabled?: boolean;\n style?: StyleProp<TextStyle>;\n className?: string;\n}\n\nexport function Label({\n children,\n required = false,\n disabled = false,\n style,\n className,\n ...props\n}: LabelProps) {\n const ref = useRef<ComponentRef<typeof Text>>(null);\n useApplyWebClassName(ref, className);\n\n return (\n <Text\n ref={ref}\n style={[styles.label, disabled && styles.labelDisabled, style]}\n accessibilityRole=\"text\"\n {...props}\n >\n {children}\n {required ? <Text style={styles.required}> *</Text> : null}\n </Text>\n );\n}\n\nconst styles = StyleSheet.create({\n label: {\n ...labelTypography,\n color: colors.slateBlue,\n },\n labelDisabled: {\n color: colors.stormGray400,\n },\n required: {\n color: colors.inputError,\n },\n});\n","export const EYE_OPEN_OUTLINE_PATH =\n \"M1.71835 10.2898C1.6489 10.1027 1.6489 9.89691 1.71835 9.70981C2.39476 8.06969 3.54294 6.66735 5.01732 5.68056C6.4917 4.69378 8.22588 4.16699 10 4.16699C11.7741 4.16699 13.5083 4.69378 14.9827 5.68056C16.4571 6.66735 17.6053 8.06969 18.2817 9.70981C18.3511 9.89691 18.3511 10.1027 18.2817 10.2898C17.6053 11.9299 16.4571 13.3323 14.9827 14.3191C13.5083 15.3058 11.7741 15.8326 10 15.8326C8.22588 15.8326 6.4917 15.3058 5.01732 14.3191C3.54294 13.3323 2.39476 11.9299 1.71835 10.2898Z\";\n\nexport const EYE_OPEN_PUPIL_PATH =\n \"M10 12.4998C11.3807 12.4998 12.5 11.3805 12.5 9.99981C12.5 8.6191 11.3807 7.49981 10 7.49981C8.6193 7.49981 7.50001 8.6191 7.50001 9.99981C7.50001 11.3805 8.6193 12.4998 10 12.4998Z\";\n\nexport const EYE_OFF_PATH =\n \"M10.733 5.076C13.0624 4.7984 15.4186 5.29082 17.4419 6.47805C19.4651 7.66528 21.0442 9.48208 21.938 11.651C22.0213 11.8755 22.0213 12.1225 21.938 12.347C21.5705 13.238 21.0848 14.0755 20.494 14.837M14.084 14.158C13.5182 14.7045 12.7604 15.0069 11.9738 15C11.1872 14.9932 10.4348 14.6777 9.87854 14.1215C9.32232 13.5652 9.00681 12.8128 8.99998 12.0262C8.99314 11.2396 9.29553 10.4818 9.842 9.916M17.479 17.499C16.1525 18.2848 14.6725 18.776 13.1394 18.9394C11.6063 19.1028 10.056 18.9345 8.59363 18.4459C7.13131 17.9573 5.79119 17.1599 4.66421 16.1077C3.53723 15.0556 2.64975 13.7734 2.062 12.348C1.97866 12.1235 1.97866 11.8765 2.062 11.652C2.94863 9.50186 4.50867 7.69725 6.508 6.509M2 2L22 22\";\n","import Svg, { Path } from \"react-native-svg\";\nimport { EYE_OPEN_OUTLINE_PATH, EYE_OPEN_PUPIL_PATH } from \"./eyeIconPaths\";\n\nexport { EYE_OPEN_OUTLINE_PATH, EYE_OPEN_PUPIL_PATH } from \"./eyeIconPaths\";\n\ninterface EyeIconProps {\n size?: number;\n color?: string;\n strokeWidth?: number;\n}\n\n/** Native — open eye (password hidden). */\nexport function EyeIcon({\n size = 20,\n color = \"#c7cdd1\",\n strokeWidth = 2,\n}: EyeIconProps) {\n return (\n <Svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"none\">\n <Path\n d={EYE_OPEN_OUTLINE_PATH}\n stroke={color}\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <Path\n d={EYE_OPEN_PUPIL_PATH}\n stroke={color}\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </Svg>\n );\n}\n","import Svg, { Path } from \"react-native-svg\";\nimport { EYE_OFF_PATH } from \"./eyeIconPaths\";\n\nexport { EYE_OFF_PATH } from \"./eyeIconPaths\";\n\ninterface EyeOffIconProps {\n size?: number;\n color?: string;\n strokeWidth?: number;\n}\n\n/** Native — slashed eye (password visible). */\nexport function EyeOffIcon({\n size = 20,\n color = \"#c7cdd1\",\n strokeWidth = 2,\n}: EyeOffIconProps) {\n return (\n <Svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\n <Path\n d={EYE_OFF_PATH}\n stroke={color}\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </Svg>\n );\n}\n","import { Platform, StyleSheet, type TextStyle, type ViewStyle } from \"react-native\";\nimport { colors, fonts, fontSize, fontWeight, radii } from \"./tokens\";\n\nexport const INPUT_HEIGHT = 52;\nexport const INPUT_ICON_SIZE = 20;\nexport const INPUT_ICON_GAP = 10;\nexport const INPUT_OUTLINE_WIDTH = 2;\n\nexport type InputVisualState =\n | \"default\"\n | \"focused\"\n | \"error\"\n | \"disabled\";\n\nexport interface InputStateFlags {\n focused?: boolean;\n error?: boolean;\n disabled?: boolean;\n}\n\nexport function resolveInputVisualState({\n focused = false,\n error = false,\n disabled = false,\n}: InputStateFlags): InputVisualState {\n if (disabled) return \"disabled\";\n if (error) return \"error\";\n if (focused) return \"focused\";\n return \"default\";\n}\n\ninterface FieldStyleSet {\n container: ViewStyle;\n outline: ViewStyle;\n text: TextStyle;\n placeholder: string;\n icon: string;\n}\n\nfunction createOutlineStyle(ringColor: string): ViewStyle {\n return {\n borderRadius: radii.lg + INPUT_OUTLINE_WIDTH,\n borderWidth: INPUT_OUTLINE_WIDTH,\n borderColor: ringColor,\n padding: 0,\n backgroundColor: colors.transparent,\n width: \"100%\",\n alignSelf: \"stretch\",\n ...(Platform.OS !== \"web\" ? { overflow: \"hidden\" as const } : null),\n };\n}\n\nconst defaultOutline = createOutlineStyle(colors.transparent);\n\nexport function getInputFieldStyles(state: InputVisualState): FieldStyleSet {\n const containerBase: ViewStyle = {\n borderRadius: radii.lg,\n ...(Platform.OS !== \"web\" ? { overflow: \"hidden\" as const } : null),\n };\n\n switch (state) {\n case \"disabled\":\n return {\n outline: defaultOutline,\n container: {\n ...containerBase,\n borderWidth: 1,\n borderColor: colors.stormGray50,\n backgroundColor: colors.stormGray50,\n },\n text: { color: colors.stormGray300 },\n placeholder: colors.stormGray300,\n icon: colors.stormGray150,\n };\n case \"error\":\n return {\n outline: createOutlineStyle(colors.inputOutlineError),\n container: {\n ...containerBase,\n borderWidth: 1,\n borderColor: colors.inputError,\n backgroundColor: colors.white,\n },\n text: { color: colors.inputError },\n placeholder: colors.stormGray200,\n icon: colors.inputError,\n };\n case \"focused\":\n return {\n outline: createOutlineStyle(colors.inputOutlineFocus),\n container: {\n ...containerBase,\n borderWidth: 1,\n borderColor: colors.navy,\n backgroundColor: colors.white,\n },\n text: { color: colors.slateBlue },\n placeholder: colors.stormGray200,\n icon: colors.navy,\n };\n default:\n return {\n outline: defaultOutline,\n container: {\n ...containerBase,\n borderWidth: 1,\n borderColor: colors.stormGray50,\n backgroundColor: colors.white,\n },\n text: { color: colors.slateBlue },\n placeholder: colors.stormGray200,\n icon: colors.stormGray150,\n };\n }\n}\n\nexport const inputFieldMetrics = StyleSheet.create({\n container: {\n flexDirection: \"row\",\n alignItems: \"center\",\n height: INPUT_HEIGHT,\n minHeight: INPUT_HEIGHT,\n maxHeight: INPUT_HEIGHT,\n borderRadius: radii.lg,\n padding: 16,\n gap: INPUT_ICON_GAP,\n ...(Platform.OS === \"web\"\n ? ({ boxSizing: \"border-box\" } as ViewStyle)\n : null),\n },\n input: {\n flex: 1,\n alignSelf: \"stretch\",\n fontFamily: fonts.sans,\n fontSize: fontSize.md,\n fontWeight: fontWeight.medium,\n lineHeight: Platform.OS === \"web\" ? fontSize.md : 20,\n paddingVertical: 0,\n paddingHorizontal: 0,\n margin: 0,\n borderWidth: 0,\n backgroundColor: colors.transparent,\n ...(Platform.OS === \"android\"\n ? { includeFontPadding: false }\n : null),\n ...(Platform.OS === \"web\"\n ? ({\n height: \"100%\",\n minHeight: 0,\n outlineStyle: \"none\",\n } as TextStyle)\n : null),\n },\n});\n","import {\n cloneElement,\n isValidElement,\n useRef,\n useState,\n type ComponentRef,\n type ReactNode,\n} from \"react\";\nimport {\n Pressable,\n StyleSheet,\n Text,\n TextInput,\n View,\n type NativeSyntheticEvent,\n type StyleProp,\n type TextInputFocusEventData,\n type TextInputProps,\n type TextStyle,\n type ViewStyle,\n} from \"react-native\";\nimport { EyeIcon } from \"../icons/EyeIcon\";\nimport { EyeOffIcon } from \"../icons/EyeOffIcon\";\nimport {\n getInputFieldStyles,\n inputFieldMetrics,\n INPUT_ICON_SIZE,\n resolveInputVisualState,\n} from \"../theme/input\";\nimport { colors, spacing } from \"../theme/tokens\";\nimport { useApplyWebClassName } from \"../utils/useApplyWebClassName\";\nimport { Label } from \"./Label\";\n\ntype InputIconProps = {\n size?: number;\n color?: string;\n};\n\nfunction renderInputIcon(icon: ReactNode, color: string) {\n if (!icon) return null;\n\n if (isValidElement<InputIconProps>(icon)) {\n return cloneElement(icon, {\n size: icon.props.size ?? INPUT_ICON_SIZE,\n color: icon.props.color ?? color,\n });\n }\n\n return icon;\n}\n\nexport interface InputProps extends TextInputProps {\n /** Optional field label rendered above the input. */\n label?: string;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n /** Validation or helper error message. Shown instead of `hint` when set. */\n error?: string;\n /** Helper text shown below the input when there is no error. */\n hint?: string;\n containerStyle?: StyleProp<ViewStyle>;\n style?: StyleProp<TextStyle>;\n className?: string;\n /** CSS classes for the bordered field container (web). */\n fieldClassName?: string;\n /** Styles merged into the bordered field container. */\n fieldStyle?: StyleProp<ViewStyle>;\n labelClassName?: string;\n inputClassName?: string;\n errorClassName?: string;\n hintClassName?: string;\n /** When `secureTextEntry` is set, show a toggleable eye icon. Pass `false` to disable. */\n showPasswordToggle?: boolean;\n}\n\nexport function Input({\n label,\n leftIcon,\n rightIcon,\n error,\n hint,\n containerStyle,\n style,\n className,\n fieldClassName,\n fieldStyle,\n labelClassName,\n inputClassName,\n errorClassName,\n hintClassName,\n editable = true,\n secureTextEntry,\n showPasswordToggle,\n onFocus,\n onBlur,\n ...props\n}: InputProps) {\n const wrapperRef = useRef<ComponentRef<typeof View>>(null);\n const fieldRef = useRef<ComponentRef<typeof View>>(null);\n const inputRef = useRef<ComponentRef<typeof TextInput>>(null);\n const helperRef = useRef<ComponentRef<typeof Text>>(null);\n const [focused, setFocused] = useState(false);\n const [passwordVisible, setPasswordVisible] = useState(false);\n\n useApplyWebClassName(wrapperRef, className);\n useApplyWebClassName(fieldRef, fieldClassName);\n useApplyWebClassName(inputRef, inputClassName);\n useApplyWebClassName(helperRef, error ? errorClassName : hintClassName);\n\n const isDisabled = editable === false;\n const passwordToggleEnabled =\n secureTextEntry === true && showPasswordToggle !== false && rightIcon == null;\n const effectiveSecureTextEntry = passwordToggleEnabled\n ? !passwordVisible\n : secureTextEntry;\n const visualState = resolveInputVisualState({\n focused,\n error: Boolean(error),\n disabled: isDisabled,\n });\n const fieldStyles = getInputFieldStyles(visualState);\n const iconColor = fieldStyles.icon;\n\n function handleFocus(event: NativeSyntheticEvent<TextInputFocusEventData>) {\n setFocused(true);\n onFocus?.(event);\n }\n\n function handleBlur(event: NativeSyntheticEvent<TextInputFocusEventData>) {\n setFocused(false);\n onBlur?.(event);\n }\n\n const helperMessage = error ?? hint;\n\n function togglePasswordVisibility() {\n if (!isDisabled) {\n setPasswordVisible((visible) => !visible);\n }\n }\n\n const trailingIcon = passwordToggleEnabled ? (\n <Pressable\n onPress={togglePasswordVisibility}\n disabled={isDisabled}\n accessibilityRole=\"button\"\n accessibilityLabel={passwordVisible ? \"Hide password\" : \"Show password\"}\n hitSlop={8}\n style={styles.iconPressable}\n >\n {renderInputIcon(\n passwordVisible ? <EyeOffIcon /> : <EyeIcon />,\n iconColor,\n )}\n </Pressable>\n ) : rightIcon ? (\n renderInputIcon(rightIcon, iconColor)\n ) : null;\n\n return (\n <View ref={wrapperRef} style={[styles.wrapper, containerStyle]}>\n {label ? (\n <Label disabled={isDisabled} className={labelClassName}>\n {label}\n </Label>\n ) : null}\n <View style={fieldStyles.outline}>\n <View\n ref={fieldRef}\n style={[inputFieldMetrics.container, fieldStyles.container, fieldStyle]}\n >\n {leftIcon ? (\n <View style={styles.iconSlot}>{renderInputIcon(leftIcon, iconColor)}</View>\n ) : null}\n <TextInput\n ref={inputRef}\n style={[\n inputFieldMetrics.input,\n fieldStyles.text,\n style,\n ]}\n placeholderTextColor={fieldStyles.placeholder}\n editable={editable}\n secureTextEntry={effectiveSecureTextEntry}\n onFocus={handleFocus}\n onBlur={handleBlur}\n accessibilityState={{ disabled: isDisabled }}\n {...props}\n />\n {trailingIcon ? (\n <View style={styles.iconSlot}>{trailingIcon}</View>\n ) : null}\n </View>\n </View>\n {helperMessage ? (\n <Text ref={helperRef} style={error ? styles.error : styles.hint}>\n {helperMessage}\n </Text>\n ) : null}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n wrapper: {\n width: \"100%\",\n gap: spacing.sm,\n },\n iconSlot: {\n width: INPUT_ICON_SIZE,\n height: INPUT_ICON_SIZE,\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n },\n iconPressable: {\n width: INPUT_ICON_SIZE,\n height: INPUT_ICON_SIZE,\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n error: {\n fontSize: 12,\n lineHeight: 16,\n color: colors.inputError,\n },\n hint: {\n fontSize: 12,\n lineHeight: 16,\n color: colors.stormGray300,\n },\n});\n"]}