@innosolutions/inno-calendar 1.0.21 → 1.0.23

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.
Files changed (49) hide show
  1. package/dist/{agenda-dropdown-D8rfvI3Q.js → agenda-dropdown-B76IBhmH.js} +777 -769
  2. package/dist/agenda-dropdown-B76IBhmH.js.map +1 -0
  3. package/dist/agenda-dropdown-DMtt0PMz.cjs +2 -0
  4. package/dist/agenda-dropdown-DMtt0PMz.cjs.map +1 -0
  5. package/dist/{agenda-view-CRI1J_KB.js → agenda-view-5sPzr1GA.js} +795 -733
  6. package/dist/{agenda-view-CRI1J_KB.js.map → agenda-view-5sPzr1GA.js.map} +1 -1
  7. package/dist/agenda-view-BhD-XJn-.cjs +11 -0
  8. package/dist/{agenda-view-BotvTTEB.cjs.map → agenda-view-BhD-XJn-.cjs.map} +1 -1
  9. package/dist/components/index.cjs +1 -1
  10. package/dist/components/index.mjs +2 -2
  11. package/dist/components/inno-calendar.d.ts +7 -1
  12. package/dist/components/inno-calendar.d.ts.map +1 -1
  13. package/dist/components/views/month-view.d.ts +7 -1
  14. package/dist/components/views/month-view.d.ts.map +1 -1
  15. package/dist/components/views/timeline-view.d.ts +1 -1
  16. package/dist/components/views/timeline-view.d.ts.map +1 -1
  17. package/dist/core/index.cjs +1 -1
  18. package/dist/core/index.mjs +3 -3
  19. package/dist/core/utils/date-utils.d.ts +2 -0
  20. package/dist/core/utils/date-utils.d.ts.map +1 -1
  21. package/dist/index.cjs +1 -1
  22. package/dist/index.mjs +6 -6
  23. package/dist/{inno-calendar-provider-BAcxjBGI.cjs → inno-calendar-provider-CEO8ZyR2.cjs} +2 -2
  24. package/dist/{inno-calendar-provider-BAcxjBGI.cjs.map → inno-calendar-provider-CEO8ZyR2.cjs.map} +1 -1
  25. package/dist/{inno-calendar-provider-Cy72EfJy.js → inno-calendar-provider-CbnwQSuI.js} +2 -2
  26. package/dist/{inno-calendar-provider-Cy72EfJy.js.map → inno-calendar-provider-CbnwQSuI.js.map} +1 -1
  27. package/dist/presets/index.cjs +1 -1
  28. package/dist/presets/index.mjs +1 -1
  29. package/dist/slot-selection-context-BnE5w6aV.cjs +2 -0
  30. package/dist/slot-selection-context-BnE5w6aV.cjs.map +1 -0
  31. package/dist/{slot-selection-context-CZjfJAcp.js → slot-selection-context-CMaE5Bc5.js} +103 -103
  32. package/dist/slot-selection-context-CMaE5Bc5.js.map +1 -0
  33. package/dist/styles/index.css +1 -1
  34. package/dist/{tailwind-calendar-Y9dn5uKm.js → tailwind-calendar-BEf7QDjd.js} +3 -3
  35. package/dist/{tailwind-calendar-Y9dn5uKm.js.map → tailwind-calendar-BEf7QDjd.js.map} +1 -1
  36. package/dist/{tailwind-calendar-CQBD-ljO.cjs → tailwind-calendar-Cur19bSK.cjs} +2 -2
  37. package/dist/{tailwind-calendar-CQBD-ljO.cjs.map → tailwind-calendar-Cur19bSK.cjs.map} +1 -1
  38. package/dist/{use-calendar-time-config-CLYhL81Z.js → use-calendar-time-config-C_ZU8YAc.js} +3 -3
  39. package/dist/{use-calendar-time-config-CLYhL81Z.js.map → use-calendar-time-config-C_ZU8YAc.js.map} +1 -1
  40. package/dist/{use-calendar-time-config-BQ1Yni0n.cjs → use-calendar-time-config-bm7Fn31s.cjs} +2 -2
  41. package/dist/{use-calendar-time-config-BQ1Yni0n.cjs.map → use-calendar-time-config-bm7Fn31s.cjs.map} +1 -1
  42. package/package.json +1 -1
  43. package/dist/agenda-dropdown-D8rfvI3Q.js.map +0 -1
  44. package/dist/agenda-dropdown-oY4qocpp.cjs +0 -2
  45. package/dist/agenda-dropdown-oY4qocpp.cjs.map +0 -1
  46. package/dist/agenda-view-BotvTTEB.cjs +0 -11
  47. package/dist/slot-selection-context-B_YLI-x7.cjs +0 -2
  48. package/dist/slot-selection-context-B_YLI-x7.cjs.map +0 -1
  49. package/dist/slot-selection-context-CZjfJAcp.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"inno-calendar-provider-BAcxjBGI.cjs","sources":["../src/core/hooks/use-calendar.ts","../src/core/context/calendar-context.tsx","../src/core/preferences/types.ts","../src/core/preferences/use-preferences.ts","../src/core/context/inno-calendar-provider.tsx"],"sourcesContent":["/**\r\n * useCalendar - Main Calendar Hook\r\n *\r\n * This hook provides all the state and methods needed to build a calendar.\r\n * It is fully generic, allowing consumers to define their own event data types.\r\n *\r\n * @example\r\n * ```tsx\r\n * interface MyEventData {\r\n * projectId: number;\r\n * priority: 'low' | 'medium' | 'high';\r\n * }\r\n *\r\n * const calendar = useCalendar<MyEventData>({\r\n * events: myEvents,\r\n * onEventClick: (event) => {\r\n * console.log(event.data?.projectId);\r\n * },\r\n * });\r\n * ```\r\n */\r\n\r\nimport { useState, useMemo, useCallback } from 'react';\r\nimport type {\r\n\tCalendarEvent,\r\n\tTCalendarView,\r\n\tICalendarPreferences,\r\n\tICalendarFilters,\r\n\tIResource,\r\n\tIScheduleType,\r\n\tISelectionResult,\r\n\tIDateRange,\r\n} from '../types';\r\nimport { DEFAULT_PREFERENCES } from '../constants';\r\nimport {\r\n\tgetViewDateRange,\r\n\tnavigateNext,\r\n\tnavigatePrev,\r\n\tnavigateToday,\r\n\tgetViewTitle,\r\n} from '../utils/grid-utils';\r\nimport {\r\n\tfilterEventsByDateRange,\r\n\tfilterEventsByScheduleType,\r\n\tfilterEventsByResource,\r\n\tfilterEventsBySearch,\r\n\tfilterOutCanceled,\r\n\tsortEventsByStart,\r\n} from '../utils/event-utils';\r\n\r\n// ============================================================================\r\n// TYPES\r\n// ============================================================================\r\n\r\n/**\r\n * Options for useCalendar hook\r\n */\r\nexport interface UseCalendarOptions<\r\n\tTEventData = Record<string, unknown>,\r\n\tTScheduleTypeData = Record<string, unknown>,\r\n\tTResourceData = Record<string, unknown>,\r\n> {\r\n\t/** Events to display */\r\n\tevents: CalendarEvent<TEventData>[];\r\n\r\n\t/** Available resources (for resource views) */\r\n\tresources?: IResource<TResourceData>[] | undefined;\r\n\r\n\t/** Available schedule types */\r\n\tscheduleTypes?: IScheduleType<TScheduleTypeData>[] | undefined;\r\n\r\n\t/** Initial view */\r\n\tinitialView?: TCalendarView | undefined;\r\n\r\n\t/** Initial date */\r\n\tinitialDate?: Date | undefined;\r\n\r\n\t/** Initial filters */\r\n\tinitialFilters?: ICalendarFilters | undefined;\r\n\r\n\t/** User preferences */\r\n\tpreferences?: Partial<ICalendarPreferences> | undefined;\r\n\r\n\t/** Locked preferences (cannot be changed by user) */\r\n\tlockedPreferences?: Partial<ICalendarPreferences> | undefined;\r\n\r\n\t/** Locale for formatting */\r\n\tlocale?: string | undefined;\r\n\r\n\t/** Callback when view changes */\r\n\tonViewChange?: ((view: TCalendarView) => void) | undefined;\r\n\r\n\t/** Callback when date changes */\r\n\tonDateChange?: ((date: Date) => void) | undefined;\r\n\r\n\t/** Callback when event is clicked */\r\n\tonEventClick?: ((event: CalendarEvent<TEventData>) => void) | undefined;\r\n\r\n\t/** Callback when slot is selected */\r\n\tonSlotSelect?: ((selection: ISelectionResult) => void) | undefined;\r\n\r\n\t/** Callback when filters change */\r\n\tonFiltersChange?: ((filters: ICalendarFilters) => void) | undefined;\r\n}\r\n\r\n/**\r\n * Return type for useCalendar hook\r\n */\r\nexport interface UseCalendarReturn<\r\n\tTEventData = Record<string, unknown>,\r\n\tTScheduleTypeData = Record<string, unknown>,\r\n\tTResourceData = Record<string, unknown>,\r\n> {\r\n\t// State\r\n\tview: TCalendarView;\r\n\tcurrentDate: Date;\r\n\tdateRange: IDateRange;\r\n\tfilters: ICalendarFilters;\r\n\tpreferences: ICalendarPreferences;\r\n\r\n\t// Computed\r\n\tfilteredEvents: CalendarEvent<TEventData>[];\r\n\tviewTitle: string;\r\n\r\n\t// Data\r\n\tevents: CalendarEvent<TEventData>[];\r\n\tresources: IResource<TResourceData>[];\r\n\tscheduleTypes: IScheduleType<TScheduleTypeData>[];\r\n\r\n\t// Actions\r\n\tsetView: (view: TCalendarView) => void;\r\n\tsetCurrentDate: (date: Date) => void;\r\n\tgoToNext: () => void;\r\n\tgoToPrev: () => void;\r\n\tgoToToday: () => void;\r\n\tgoToDate: (date: Date) => void;\r\n\r\n\t// Filters\r\n\tsetFilters: (filters: ICalendarFilters) => void;\r\n\tupdateFilters: (updates: Partial<ICalendarFilters>) => void;\r\n\tclearFilters: () => void;\r\n\r\n\t// Preferences\r\n\tsetPreferences: (prefs: Partial<ICalendarPreferences>) => void;\r\n\r\n\t// Event handlers\r\n\thandleEventClick: (event: CalendarEvent<TEventData>) => void;\r\n\thandleSlotSelect: (selection: ISelectionResult) => void;\r\n}\r\n\r\n// ============================================================================\r\n// HOOK\r\n// ============================================================================\r\n\r\nexport function useCalendar<\r\n\tTEventData = Record<string, unknown>,\r\n\tTScheduleTypeData = Record<string, unknown>,\r\n\tTResourceData = Record<string, unknown>,\r\n>(\r\n\toptions: UseCalendarOptions<TEventData, TScheduleTypeData, TResourceData>,\r\n): UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData> {\r\n\tconst {\r\n\t\tevents,\r\n\t\tresources = [],\r\n\t\tscheduleTypes = [],\r\n\t\tinitialView = 'week',\r\n\t\tinitialDate,\r\n\t\tinitialFilters = {},\r\n\t\tpreferences: userPreferences = {},\r\n\t\tlockedPreferences = {},\r\n\t\tlocale = 'en-US',\r\n\t\tonViewChange,\r\n\t\tonDateChange,\r\n\t\tonEventClick,\r\n\t\tonSlotSelect,\r\n\t\tonFiltersChange,\r\n\t} = options;\r\n\r\n\t// ========================================================================\r\n\t// STATE\r\n\t// ========================================================================\r\n\r\n\tconst [view, setViewState] = useState<TCalendarView>(initialView);\r\n\tconst [currentDate, setCurrentDateState] = useState<Date>(() => initialDate ?? new Date());\r\n\tconst [filters, setFiltersState] = useState<ICalendarFilters>(initialFilters);\r\n\tconst [preferences, setPreferencesState] = useState<ICalendarPreferences>(() => ({\r\n\t\t...DEFAULT_PREFERENCES,\r\n\t\t...userPreferences,\r\n\t\t...lockedPreferences,\r\n\t}));\r\n\r\n\t// ========================================================================\r\n\t// COMPUTED\r\n\t// ========================================================================\r\n\r\n\tconst dateRange = useMemo(\r\n\t\t() => getViewDateRange(currentDate, view, preferences.firstDayOfWeek),\r\n\t\t[currentDate, view, preferences.firstDayOfWeek],\r\n\t);\r\n\r\n\tconst viewTitle = useMemo(\r\n\t\t() => getViewTitle(currentDate, view, locale),\r\n\t\t[currentDate, view, locale],\r\n\t);\r\n\r\n\tconst filteredEvents = useMemo(() => {\r\n\t\tlet result = [...events];\r\n\r\n\t\t// Filter by date range\r\n\t\tresult = filterEventsByDateRange(result, dateRange.startDate, dateRange.endDate);\r\n\r\n\t\t// Filter by schedule types\r\n\t\tconst scheduleTypeIds = filters.scheduleTypeIds;\r\n\t\tif (scheduleTypeIds && scheduleTypeIds.length > 0) {\r\n\t\t\tresult = filterEventsByScheduleType(result, scheduleTypeIds);\r\n\t\t}\r\n\r\n\t\t// Filter by resources\r\n\t\tconst resourceIds = filters.resourceIds;\r\n\t\tif (resourceIds && resourceIds.length > 0) {\r\n\t\t\tresult = filterEventsByResource(result, resourceIds);\r\n\t\t}\r\n\r\n\t\t// Filter by search\r\n\t\tconst search = filters.search;\r\n\t\tif (search) {\r\n\t\t\tresult = filterEventsBySearch(result, search);\r\n\t\t}\r\n\r\n\t\t// Filter canceled\r\n\t\tif (!preferences.showCanceledEvents) {\r\n\t\t\tresult = filterOutCanceled(result);\r\n\t\t}\r\n\r\n\t\t// Sort by start date\r\n\t\treturn sortEventsByStart(result);\r\n\t}, [events, dateRange, filters, preferences.showCanceledEvents]);\r\n\r\n\t// ========================================================================\r\n\t// ACTIONS\r\n\t// ========================================================================\r\n\r\n\tconst setView = useCallback(\r\n\t\t(newView: TCalendarView) => {\r\n\t\t\tsetViewState(newView);\r\n\t\t\tonViewChange?.(newView);\r\n\t\t},\r\n\t\t[onViewChange],\r\n\t);\r\n\r\n\tconst setCurrentDate = useCallback(\r\n\t\t(date: Date) => {\r\n\t\t\tsetCurrentDateState(date);\r\n\t\t\tonDateChange?.(date);\r\n\t\t},\r\n\t\t[onDateChange],\r\n\t);\r\n\r\n\tconst goToNext = useCallback(() => {\r\n\t\tconst newDate = navigateNext(currentDate, view);\r\n\t\tsetCurrentDate(newDate);\r\n\t}, [currentDate, view, setCurrentDate]);\r\n\r\n\tconst goToPrev = useCallback(() => {\r\n\t\tconst newDate = navigatePrev(currentDate, view);\r\n\t\tsetCurrentDate(newDate);\r\n\t}, [currentDate, view, setCurrentDate]);\r\n\r\n\tconst goToToday = useCallback(() => {\r\n\t\tsetCurrentDate(navigateToday());\r\n\t}, [setCurrentDate]);\r\n\r\n\tconst goToDate = useCallback(\r\n\t\t(date: Date) => {\r\n\t\t\tsetCurrentDate(date);\r\n\t\t},\r\n\t\t[setCurrentDate],\r\n\t);\r\n\r\n\t// ========================================================================\r\n\t// FILTERS\r\n\t// ========================================================================\r\n\r\n\tconst setFilters = useCallback(\r\n\t\t(newFilters: ICalendarFilters) => {\r\n\t\t\tsetFiltersState(newFilters);\r\n\t\t\tonFiltersChange?.(newFilters);\r\n\t\t},\r\n\t\t[onFiltersChange],\r\n\t);\r\n\r\n\tconst updateFilters = useCallback(\r\n\t\t(updates: Partial<ICalendarFilters>) => {\r\n\t\t\tsetFiltersState((prev) => {\r\n\t\t\t\tconst next = { ...prev, ...updates };\r\n\t\t\t\tonFiltersChange?.(next);\r\n\t\t\t\treturn next;\r\n\t\t\t});\r\n\t\t},\r\n\t\t[onFiltersChange],\r\n\t);\r\n\r\n\tconst clearFilters = useCallback(() => {\r\n\t\tconst emptyFilters: ICalendarFilters = {};\r\n\t\tsetFiltersState(emptyFilters);\r\n\t\tonFiltersChange?.(emptyFilters);\r\n\t}, [onFiltersChange]);\r\n\r\n\t// ========================================================================\r\n\t// PREFERENCES\r\n\t// ========================================================================\r\n\r\n\tconst setPreferences = useCallback(\r\n\t\t(prefs: Partial<ICalendarPreferences>) => {\r\n\t\t\tsetPreferencesState((prev) => ({\r\n\t\t\t\t...prev,\r\n\t\t\t\t...prefs,\r\n\t\t\t\t...lockedPreferences, // Locked prefs always override\r\n\t\t\t}));\r\n\t\t},\r\n\t\t[lockedPreferences],\r\n\t);\r\n\r\n\t// ========================================================================\r\n\t// EVENT HANDLERS\r\n\t// ========================================================================\r\n\r\n\tconst handleEventClick = useCallback(\r\n\t\t(event: CalendarEvent<TEventData>) => {\r\n\t\t\tonEventClick?.(event);\r\n\t\t},\r\n\t\t[onEventClick],\r\n\t);\r\n\r\n\tconst handleSlotSelect = useCallback(\r\n\t\t(selection: ISelectionResult) => {\r\n\t\t\tonSlotSelect?.(selection);\r\n\t\t},\r\n\t\t[onSlotSelect],\r\n\t);\r\n\r\n\t// ========================================================================\r\n\t// RETURN\r\n\t// ========================================================================\r\n\r\n\treturn {\r\n\t\t// State\r\n\t\tview,\r\n\t\tcurrentDate,\r\n\t\tdateRange,\r\n\t\tfilters,\r\n\t\tpreferences,\r\n\r\n\t\t// Computed\r\n\t\tfilteredEvents,\r\n\t\tviewTitle,\r\n\r\n\t\t// Data\r\n\t\tevents,\r\n\t\tresources,\r\n\t\tscheduleTypes,\r\n\r\n\t\t// Actions\r\n\t\tsetView,\r\n\t\tsetCurrentDate,\r\n\t\tgoToNext,\r\n\t\tgoToPrev,\r\n\t\tgoToToday,\r\n\t\tgoToDate,\r\n\r\n\t\t// Filters\r\n\t\tsetFilters,\r\n\t\tupdateFilters,\r\n\t\tclearFilters,\r\n\r\n\t\t// Preferences\r\n\t\tsetPreferences,\r\n\r\n\t\t// Event handlers\r\n\t\thandleEventClick,\r\n\t\thandleSlotSelect,\r\n\t};\r\n}\r\n","/**\r\n * CalendarContext - React Context for Calendar State\r\n *\r\n * Provides calendar state to deeply nested components without prop drilling.\r\n */\r\n\r\nimport { createContext, useContext, type ReactNode } from 'react';\r\nimport type { UseCalendarReturn } from '../hooks/use-calendar';\r\n\r\n// ============================================================================\r\n// CONTEXT\r\n// ============================================================================\r\n\r\n/**\r\n * Calendar context type - generic to support any event data type\r\n * We use `any` here because context consumers may not know the exact type\r\n * Use the typed hooks below for type-safe access\r\n */\r\n// biome-ignore lint/suspicious/noExplicitAny: Context needs to be flexible for different event types\r\nconst CalendarContext = createContext<UseCalendarReturn<any, any, any> | undefined>(undefined);\r\n\r\n// ============================================================================\r\n// PROVIDER\r\n// ============================================================================\r\n\r\nexport interface CalendarProviderProps<\r\n TEventData = Record<string, unknown>,\r\n TScheduleTypeData = Record<string, unknown>,\r\n TResourceData = Record<string, unknown>,\r\n> {\r\n children: ReactNode;\r\n value: UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData>;\r\n}\r\n\r\nexport function CalendarProvider<\r\n TEventData = Record<string, unknown>,\r\n TScheduleTypeData = Record<string, unknown>,\r\n TResourceData = Record<string, unknown>,\r\n>({ children, value }: CalendarProviderProps<TEventData, TScheduleTypeData, TResourceData>) {\r\n return <CalendarContext.Provider value={value}>{children}</CalendarContext.Provider>;\r\n}\r\n\r\n// ============================================================================\r\n// HOOKS\r\n// ============================================================================\r\n\r\n/**\r\n * Get the full calendar context (throws if not in provider)\r\n */\r\nexport function useCalendarContext<\r\n TEventData = Record<string, unknown>,\r\n TScheduleTypeData = Record<string, unknown>,\r\n TResourceData = Record<string, unknown>,\r\n>(): UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData> {\r\n const context = useContext(CalendarContext);\r\n if (!context) {\r\n throw new Error('useCalendarContext must be used within a CalendarProvider');\r\n }\r\n return context as UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData>;\r\n}\r\n\r\n/**\r\n * Get the calendar context or undefined (safe version)\r\n */\r\nexport function useOptionalCalendarContext<\r\n TEventData = Record<string, unknown>,\r\n TScheduleTypeData = Record<string, unknown>,\r\n TResourceData = Record<string, unknown>,\r\n>(): UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData> | undefined {\r\n const context = useContext(CalendarContext);\r\n return context as UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData> | undefined;\r\n}\r\n\r\n// ============================================================================\r\n// CONVENIENCE HOOKS\r\n// ============================================================================\r\n\r\n/**\r\n * Get current view\r\n */\r\nexport function useCalendarView() {\r\n const { view, setView } = useCalendarContext();\r\n return { view, setView };\r\n}\r\n\r\n/**\r\n * Get current date and navigation\r\n */\r\nexport function useCalendarDate() {\r\n const { currentDate, setCurrentDate, goToNext, goToPrev, goToToday, goToDate } =\r\n useCalendarContext();\r\n return { currentDate, setCurrentDate, goToNext, goToPrev, goToToday, goToDate };\r\n}\r\n\r\n/**\r\n * Get filtered events\r\n */\r\nexport function useCalendarEvents<TEventData = Record<string, unknown>>() {\r\n const { events, filteredEvents } = useCalendarContext<TEventData>();\r\n return { events, filteredEvents };\r\n}\r\n\r\n/**\r\n * Get filters\r\n */\r\nexport function useCalendarFilters() {\r\n const { filters, setFilters, updateFilters, clearFilters } = useCalendarContext();\r\n return { filters, setFilters, updateFilters, clearFilters };\r\n}\r\n\r\n/**\r\n * Get preferences\r\n */\r\nexport function useCalendarPreferences() {\r\n const { preferences, setPreferences } = useCalendarContext();\r\n return { preferences, setPreferences };\r\n}\r\n\r\n// ============================================================================\r\n// ALIASES (for agenda-v2 naming convention compatibility)\r\n// ============================================================================\r\n\r\n/**\r\n * Alias for useCalendarContext - matches agenda-v2 naming convention\r\n */\r\nexport { useCalendarContext as useCalendar };\r\n\r\n/**\r\n * Alias for useOptionalCalendarContext - matches agenda-v2 naming convention\r\n */\r\nexport { useOptionalCalendarContext as useOptionalCalendar };\r\n","/**\r\n * Calendar Preferences Types\r\n *\r\n * Type definitions for the calendar preferences system.\r\n * This module enables:\r\n * - Persistent user preferences via localStorage\r\n * - Developer-controlled defaults and overrides\r\n * - Locking preferences to prevent user modifications\r\n * - Complete customization for different deployment scenarios\r\n */\r\n\r\nimport type { TBadgeVariant, TCalendarView, TSlotDuration } from '../types';\r\n\r\n// ============================================================================\r\n// PREFERENCE KEYS\r\n// ============================================================================\r\n\r\n/**\r\n * All available preference keys\r\n */\r\nexport type TPreferenceKey =\r\n\t| 'view'\r\n\t| 'badgeVariant'\r\n\t| 'slotDuration'\r\n\t| 'visibleHours'\r\n\t| 'workingHours'\r\n\t| 'showWorkingHoursOnly'\r\n\t| 'showWeekends'\r\n\t| 'firstDayOfWeek';\r\n\r\n/**\r\n * Storage key for localStorage\r\n */\r\nexport const PREFERENCES_STORAGE_KEY = 'inno-calendar-preferences';\r\n\r\n// ============================================================================\r\n// PREFERENCE VALUE TYPES\r\n// ============================================================================\r\n\r\n/**\r\n * Visible hours configuration\r\n */\r\nexport interface IVisibleHoursConfig {\r\n\tfrom: number;\r\n\tto: number;\r\n}\r\n\r\n/**\r\n * Working hours configuration per day of week\r\n * Key: 0 = Sunday, 1 = Monday, ..., 6 = Saturday\r\n */\r\nexport type TWorkingHoursConfig = {\r\n\t[dayIndex: number]: { from: number; to: number };\r\n};\r\n\r\n// ============================================================================\r\n// PREFERENCE VALUES\r\n// ============================================================================\r\n\r\n/**\r\n * Complete preferences object structure\r\n */\r\nexport interface IPreferences {\r\n\t/** Default calendar view */\r\n\tview: TCalendarView;\r\n\t/** Event badge display style */\r\n\tbadgeVariant: TBadgeVariant;\r\n\t/** Time slot duration in minutes (15, 30, 60) */\r\n\tslotDuration: TSlotDuration;\r\n\t/** Visible hours range for day/week views */\r\n\tvisibleHours: IVisibleHoursConfig;\r\n\t/** Working hours configuration per day */\r\n\tworkingHours: TWorkingHoursConfig;\r\n\t/** Show only working hours in day/week views */\r\n\tshowWorkingHoursOnly: boolean;\r\n\t/** Show weekend days */\r\n\tshowWeekends: boolean;\r\n\t/** First day of week (0 = Sunday, 1 = Monday, etc.) */\r\n\tfirstDayOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6;\r\n}\r\n\r\n/**\r\n * Partial preferences for updates\r\n */\r\nexport type TPartialPreferences = Partial<IPreferences>;\r\n\r\n// ============================================================================\r\n// PREFERENCE CONTROL\r\n// ============================================================================\r\n\r\n/**\r\n * Control mode for each preference\r\n * - 'user': User can modify, persisted to localStorage\r\n * - 'locked': Developer-controlled, cannot be modified by user\r\n * - 'session': User can modify during session, not persisted\r\n */\r\nexport type TPreferenceMode = 'user' | 'locked' | 'session';\r\n\r\n/**\r\n * Configuration for preference control\r\n * Allows developers to lock certain preferences to specific values\r\n */\r\nexport type TPreferenceModes = {\r\n\t[K in TPreferenceKey]?: TPreferenceMode;\r\n};\r\n\r\n/**\r\n * Locked values for preferences\r\n * When a preference mode is 'locked', this value is used\r\n */\r\nexport type TLockedPreferences = TPartialPreferences;\r\n\r\n// ============================================================================\r\n// PREFERENCES CONFIG\r\n// ============================================================================\r\n\r\n/**\r\n * Complete preferences configuration for developers\r\n *\r\n * @example\r\n * // Allow all preferences to be user-controlled (default)\r\n * const config: IPreferencesConfig = {};\r\n *\r\n * @example\r\n * // Lock slot duration to 30 minutes, let users control the rest\r\n * const config: IPreferencesConfig = {\r\n * modes: { slotDuration: 'locked' },\r\n * locked: { slotDuration: 30 }\r\n * };\r\n *\r\n * @example\r\n * // Completely override all preferences (no user control)\r\n * const config: IPreferencesConfig = {\r\n * modes: {\r\n * view: 'locked',\r\n * badgeVariant: 'locked',\r\n * slotDuration: 'locked',\r\n * visibleHours: 'locked',\r\n * workingHours: 'locked',\r\n * showWorkingHoursOnly: 'locked'\r\n * },\r\n * locked: {\r\n * view: 'week',\r\n * badgeVariant: 'colored',\r\n * slotDuration: 30,\r\n * visibleHours: { from: 8, to: 18 },\r\n * workingHours: { ... },\r\n * showWorkingHoursOnly: true\r\n * }\r\n * };\r\n */\r\nexport interface IPreferencesConfig {\r\n\t/**\r\n\t * Control mode for each preference\r\n\t * Defaults to 'user' for all preferences\r\n\t */\r\n\tmodes?: TPreferenceModes;\r\n\r\n\t/**\r\n\t * Values to use when preference mode is 'locked'\r\n\t */\r\n\tlocked?: TLockedPreferences;\r\n\r\n\t/**\r\n\t * Custom default values (used when no stored preference exists)\r\n\t * These override the system defaults\r\n\t */\r\n\tdefaults?: TPartialPreferences;\r\n\r\n\t/**\r\n\t * Custom localStorage key (default: 'inno-calendar-preferences')\r\n\t * Useful when multiple calendar instances need separate storage\r\n\t */\r\n\tstorageKey?: string;\r\n\r\n\t/**\r\n\t * Disable localStorage entirely\r\n\t * All preferences will reset on page reload\r\n\t */\r\n\tdisableStorage?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// HOOK RETURN TYPE\r\n// ============================================================================\r\n\r\n/**\r\n * Return type for useCalendarPreferences hook\r\n */\r\nexport interface IUsePreferencesReturn {\r\n\t/** Current preference values */\r\n\tpreferences: IPreferences;\r\n\r\n\t/** Update a single preference */\r\n\tsetPreference: <K extends TPreferenceKey>(key: K, value: IPreferences[K]) => void;\r\n\r\n\t/** Update multiple preferences at once */\r\n\tsetPreferences: (updates: TPartialPreferences) => void;\r\n\r\n\t/** Reset preferences to defaults */\r\n\tresetPreferences: () => void;\r\n\r\n\t/** Reset a single preference to default */\r\n\tresetPreference: (key: TPreferenceKey) => void;\r\n\r\n\t/** Check if a preference is locked */\r\n\tisLocked: (key: TPreferenceKey) => boolean;\r\n\r\n\t/** Check if a preference is persisted */\r\n\tisPersisted: (key: TPreferenceKey) => boolean;\r\n\r\n\t/** Get the mode for a preference */\r\n\tgetMode: (key: TPreferenceKey) => TPreferenceMode;\r\n}\r\n","/**\r\n * Calendar Preferences Hook\r\n *\r\n * Manages calendar preferences with localStorage persistence and developer control.\r\n *\r\n * Features:\r\n * - Automatic localStorage persistence\r\n * - Developer-controlled defaults and overrides\r\n * - Preference locking for controlled deployments\r\n * - Session-only preferences that don't persist\r\n * - Type-safe preference access and updates\r\n *\r\n * @example Basic usage\r\n * ```tsx\r\n * const { preferences, setPreference } = useCalendarPreferences();\r\n * setPreference('slotDuration', 30);\r\n * ```\r\n *\r\n * @example With developer configuration\r\n * ```tsx\r\n * const { preferences } = useCalendarPreferences({\r\n * modes: { slotDuration: 'locked' },\r\n * locked: { slotDuration: 60 },\r\n * defaults: { view: 'week' }\r\n * });\r\n * ```\r\n */\r\n\r\nimport { useCallback, useEffect, useMemo, useState } from 'react';\r\nimport type { TWorkingHours } from '../types';\r\nimport {\r\n\tPREFERENCES_STORAGE_KEY,\r\n\ttype IPreferences,\r\n\ttype IPreferencesConfig,\r\n\ttype IUsePreferencesReturn,\r\n\ttype TPartialPreferences,\r\n\ttype TPreferenceKey,\r\n\ttype TPreferenceMode,\r\n} from './types';\r\n\r\n// ============================================================================\r\n// SYSTEM DEFAULTS\r\n// ============================================================================\r\n\r\n/**\r\n * Default visible hours\r\n */\r\nexport const DEFAULT_VISIBLE_HOURS = {\r\n\tfrom: 0,\r\n\tto: 24,\r\n};\r\n\r\n/**\r\n * Default working hours (Monday-Friday, 8am-6pm)\r\n */\r\nexport const DEFAULT_WORKING_HOURS: TWorkingHours = {\r\n\t0: { enabled: false, from: 8, to: 18 }, // Sunday - disabled\r\n\t1: { enabled: true, from: 8, to: 18 }, // Monday\r\n\t2: { enabled: true, from: 8, to: 18 }, // Tuesday\r\n\t3: { enabled: true, from: 8, to: 18 }, // Wednesday\r\n\t4: { enabled: true, from: 8, to: 18 }, // Thursday\r\n\t5: { enabled: true, from: 8, to: 18 }, // Friday\r\n\t6: { enabled: false, from: 8, to: 18 }, // Saturday - disabled\r\n};\r\n\r\n/**\r\n * Default slot duration in minutes\r\n */\r\nexport const DEFAULT_SLOT_DURATION = 30;\r\n\r\n/**\r\n * System default preferences\r\n * These are used when no stored preference or custom default exists\r\n */\r\nconst SYSTEM_DEFAULTS: IPreferences = {\r\n\tview: 'month',\r\n\tbadgeVariant: 'colored',\r\n\tslotDuration: DEFAULT_SLOT_DURATION,\r\n\tvisibleHours: DEFAULT_VISIBLE_HOURS,\r\n\tworkingHours: DEFAULT_WORKING_HOURS,\r\n\tshowWorkingHoursOnly: false,\r\n\tshowWeekends: true,\r\n\tfirstDayOfWeek: 1,\r\n};\r\n\r\n// ============================================================================\r\n// STORAGE HELPERS\r\n// ============================================================================\r\n\r\n/**\r\n * Load preferences from localStorage\r\n */\r\nfunction loadFromStorage(key: string): TPartialPreferences {\r\n\tif (typeof window === 'undefined') return {};\r\n\r\n\ttry {\r\n\t\tconst stored = localStorage.getItem(key);\r\n\t\tif (!stored) return {};\r\n\r\n\t\tconst parsed = JSON.parse(stored);\r\n\r\n\t\t// Validate and sanitize stored values\r\n\t\tconst sanitized: TPartialPreferences = {};\r\n\r\n\t\tif (parsed.view && typeof parsed.view === 'string') {\r\n\t\t\tsanitized.view = parsed.view;\r\n\t\t}\r\n\r\n\t\tif (parsed.badgeVariant && typeof parsed.badgeVariant === 'string') {\r\n\t\t\tsanitized.badgeVariant = parsed.badgeVariant;\r\n\t\t}\r\n\r\n\t\tif (parsed.slotDuration && typeof parsed.slotDuration === 'number') {\r\n\t\t\tsanitized.slotDuration = parsed.slotDuration;\r\n\t\t}\r\n\r\n\t\tif (parsed.visibleHours && typeof parsed.visibleHours === 'object') {\r\n\t\t\tsanitized.visibleHours = parsed.visibleHours;\r\n\t\t}\r\n\r\n\t\tif (parsed.workingHours && typeof parsed.workingHours === 'object') {\r\n\t\t\tsanitized.workingHours = parsed.workingHours;\r\n\t\t}\r\n\r\n\t\tif (typeof parsed.showWorkingHoursOnly === 'boolean') {\r\n\t\t\tsanitized.showWorkingHoursOnly = parsed.showWorkingHoursOnly;\r\n\t\t}\r\n\r\n\t\tif (typeof parsed.showWeekends === 'boolean') {\r\n\t\t\tsanitized.showWeekends = parsed.showWeekends;\r\n\t\t}\r\n\r\n\t\tif (typeof parsed.firstDayOfWeek === 'number') {\r\n\t\t\tsanitized.firstDayOfWeek = parsed.firstDayOfWeek;\r\n\t\t}\r\n\r\n\t\treturn sanitized;\r\n\t} catch {\r\n\t\tconsole.warn('[InnoCalendar] Failed to load preferences from localStorage');\r\n\t\treturn {};\r\n\t}\r\n}\r\n\r\n/**\r\n * Save preferences to localStorage\r\n */\r\nfunction saveToStorage(key: string, preferences: TPartialPreferences): void {\r\n\tif (typeof window === 'undefined') return;\r\n\r\n\ttry {\r\n\t\tlocalStorage.setItem(key, JSON.stringify(preferences));\r\n\t} catch {\r\n\t\tconsole.warn('[InnoCalendar] Failed to save preferences to localStorage');\r\n\t}\r\n}\r\n\r\n// ============================================================================\r\n// HOOK\r\n// ============================================================================\r\n\r\n/**\r\n * Calendar preferences hook with localStorage persistence\r\n *\r\n * @param config - Optional configuration for preferences behavior\r\n * @returns Preferences state and control functions\r\n */\r\nexport function useCalendarPreferences(config: IPreferencesConfig = {}): IUsePreferencesReturn {\r\n\tconst {\r\n\t\tmodes = {},\r\n\t\tlocked = {},\r\n\t\tdefaults = {},\r\n\t\tstorageKey = PREFERENCES_STORAGE_KEY,\r\n\t\tdisableStorage = false,\r\n\t} = config;\r\n\r\n\t// Compute effective defaults (system + custom)\r\n\tconst effectiveDefaults = useMemo<IPreferences>(\r\n\t\t() => ({\r\n\t\t\t...SYSTEM_DEFAULTS,\r\n\t\t\t...defaults,\r\n\t\t}),\r\n\t\t[defaults],\r\n\t);\r\n\r\n\t// Initialize state with stored + defaults\r\n\tconst [storedPreferences, setStoredPreferences] = useState<TPartialPreferences>(() => {\r\n\t\tif (disableStorage) return {};\r\n\t\treturn loadFromStorage(storageKey);\r\n\t});\r\n\r\n\t// Session-only preferences (not persisted)\r\n\tconst [sessionPreferences, setSessionPreferences] = useState<TPartialPreferences>({});\r\n\r\n\t// Save to localStorage when stored preferences change\r\n\tuseEffect(() => {\r\n\t\tif (disableStorage) return;\r\n\t\tsaveToStorage(storageKey, storedPreferences);\r\n\t}, [storedPreferences, storageKey, disableStorage]);\r\n\r\n\t// Get mode for a preference\r\n\tconst getMode = useCallback(\r\n\t\t(key: TPreferenceKey): TPreferenceMode => {\r\n\t\t\treturn modes[key] ?? 'user';\r\n\t\t},\r\n\t\t[modes],\r\n\t);\r\n\r\n\t// Check if preference is locked\r\n\tconst isLocked = useCallback(\r\n\t\t(key: TPreferenceKey): boolean => {\r\n\t\t\treturn getMode(key) === 'locked';\r\n\t\t},\r\n\t\t[getMode],\r\n\t);\r\n\r\n\t// Check if preference is persisted\r\n\tconst isPersisted = useCallback(\r\n\t\t(key: TPreferenceKey): boolean => {\r\n\t\t\tconst mode = getMode(key);\r\n\t\t\treturn mode === 'user' && !disableStorage;\r\n\t\t},\r\n\t\t[getMode, disableStorage],\r\n\t);\r\n\r\n\t// Compute final preferences (locked > session > stored > defaults)\r\n\tconst preferences = useMemo<IPreferences>(() => {\r\n\t\tconst result = { ...effectiveDefaults };\r\n\r\n\t\t// Apply stored preferences (for 'user' mode)\r\n\t\tfor (const key of Object.keys(result) as TPreferenceKey[]) {\r\n\t\t\tconst mode = getMode(key);\r\n\r\n\t\t\tif (mode === 'locked' && key in locked) {\r\n\t\t\t\t// Use locked value\r\n\t\t\t\t(result as Record<string, unknown>)[key] = locked[key];\r\n\t\t\t} else if (mode === 'session' && key in sessionPreferences) {\r\n\t\t\t\t// Use session value\r\n\t\t\t\t(result as Record<string, unknown>)[key] = sessionPreferences[key];\r\n\t\t\t} else if (mode === 'user' && key in storedPreferences) {\r\n\t\t\t\t// Use stored value\r\n\t\t\t\t(result as Record<string, unknown>)[key] = storedPreferences[key];\r\n\t\t\t}\r\n\t\t\t// Otherwise, keep default\r\n\t\t}\r\n\r\n\t\treturn result;\r\n\t}, [effectiveDefaults, storedPreferences, sessionPreferences, locked, getMode]);\r\n\r\n\t// Set a single preference\r\n\tconst setPreference = useCallback(\r\n\t\t<K extends TPreferenceKey>(key: K, value: IPreferences[K]) => {\r\n\t\t\tconst mode = getMode(key);\r\n\r\n\t\t\t// Can't modify locked preferences\r\n\t\t\tif (mode === 'locked') {\r\n\t\t\t\tconsole.warn(`[InnoCalendar] Preference \"${key}\" is locked and cannot be modified`);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (mode === 'session') {\r\n\t\t\t\tsetSessionPreferences((prev) => ({ ...prev, [key]: value }));\r\n\t\t\t} else {\r\n\t\t\t\tsetStoredPreferences((prev) => ({ ...prev, [key]: value }));\r\n\t\t\t}\r\n\t\t},\r\n\t\t[getMode],\r\n\t);\r\n\r\n\t// Set multiple preferences at once\r\n\tconst setPreferences = useCallback(\r\n\t\t(updates: TPartialPreferences) => {\r\n\t\t\tconst sessionUpdates: TPartialPreferences = {};\r\n\t\t\tconst storedUpdates: TPartialPreferences = {};\r\n\r\n\t\t\tfor (const key of Object.keys(updates) as TPreferenceKey[]) {\r\n\t\t\t\tconst mode = getMode(key);\r\n\t\t\t\tconst value = updates[key];\r\n\r\n\t\t\t\tif (value === undefined) continue;\r\n\r\n\t\t\t\tif (mode === 'locked') {\r\n\t\t\t\t\tconsole.warn(`[InnoCalendar] Preference \"${key}\" is locked and cannot be modified`);\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (mode === 'session') {\r\n\t\t\t\t\t(sessionUpdates as Record<string, unknown>)[key] = value;\r\n\t\t\t\t} else {\r\n\t\t\t\t\t(storedUpdates as Record<string, unknown>)[key] = value;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (Object.keys(sessionUpdates).length > 0) {\r\n\t\t\t\tsetSessionPreferences((prev) => ({ ...prev, ...sessionUpdates }));\r\n\t\t\t}\r\n\r\n\t\t\tif (Object.keys(storedUpdates).length > 0) {\r\n\t\t\t\tsetStoredPreferences((prev) => ({ ...prev, ...storedUpdates }));\r\n\t\t\t}\r\n\t\t},\r\n\t\t[getMode],\r\n\t);\r\n\r\n\t// Reset all preferences to defaults\r\n\tconst resetPreferences = useCallback(() => {\r\n\t\tsetStoredPreferences({});\r\n\t\tsetSessionPreferences({});\r\n\r\n\t\tif (!disableStorage) {\r\n\t\t\tlocalStorage.removeItem(storageKey);\r\n\t\t}\r\n\t}, [storageKey, disableStorage]);\r\n\r\n\t// Reset a single preference to default\r\n\tconst resetPreference = useCallback(\r\n\t\t(key: TPreferenceKey) => {\r\n\t\t\tconst mode = getMode(key);\r\n\r\n\t\t\tif (mode === 'locked') {\r\n\t\t\t\tconsole.warn(`[InnoCalendar] Preference \"${key}\" is locked and cannot be reset`);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (mode === 'session') {\r\n\t\t\t\tsetSessionPreferences((prev) => {\r\n\t\t\t\t\tconst { [key]: _, ...rest } = prev;\r\n\t\t\t\t\treturn rest;\r\n\t\t\t\t});\r\n\t\t\t} else {\r\n\t\t\t\tsetStoredPreferences((prev) => {\r\n\t\t\t\t\tconst { [key]: _, ...rest } = prev;\r\n\t\t\t\t\treturn rest;\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t\t[getMode],\r\n\t);\r\n\r\n\treturn {\r\n\t\tpreferences,\r\n\t\tsetPreference,\r\n\t\tsetPreferences,\r\n\t\tresetPreferences,\r\n\t\tresetPreference,\r\n\t\tisLocked,\r\n\t\tisPersisted,\r\n\t\tgetMode,\r\n\t};\r\n}\r\n\r\nexport default useCalendarPreferences;\r\n","/**\r\n * InnoCalendar Provider\r\n *\r\n * A CalendarProvider that matches agenda-v2's API exactly.\r\n * This is an all-in-one provider that manages state internally\r\n * rather than requiring consumers to use useCalendar separately.\r\n *\r\n * Features:\r\n * - Automatic preference persistence to localStorage\r\n * - Developer-controlled preference locking\r\n * - Same prop interface as agenda-v2's CalendarProvider\r\n * - Same context shape for component compatibility\r\n */\r\n\r\nimport {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useState,\r\n type Dispatch,\r\n type ReactNode,\r\n type SetStateAction,\r\n} from 'react';\r\nimport {\r\n useCalendarPreferences,\r\n type IPreferencesConfig,\r\n type TPreferenceKey,\r\n} from '../preferences';\r\nimport type {\r\n CalendarEvent,\r\n ICalendarUser,\r\n IScheduleType,\r\n TBadgeVariant,\r\n TCalendarView,\r\n TSlotDuration,\r\n TWorkingHours,\r\n} from '../types';\r\n\r\n// ============================================================================\r\n// TYPES\r\n// ============================================================================\r\n\r\n// Re-export types from core/types for convenience\r\nexport type { TSlotDuration, TWorkingHours, IWorkingHoursDay } from '../types';\r\n\r\n/**\r\n * Visible hours configuration\r\n * Using start/end to match agenda-v2 naming\r\n */\r\nexport interface TVisibleHours {\r\n start: number;\r\n end: number;\r\n}\r\n\r\n// ============================================================================\r\n// CONTEXT INTERFACE - Matches agenda-v2 exactly\r\n// ============================================================================\r\n\r\nexport interface IInnoCalendarContext<TEventData = Record<string, unknown>> {\r\n // View & Navigation\r\n view: TCalendarView;\r\n setView: (view: TCalendarView) => void;\r\n selectedDate: Date;\r\n /** Set selected date. Pass optional forView to use that view for date range calculation. */\r\n setSelectedDate: (date: Date, forView?: TCalendarView) => void;\r\n\r\n // User/Participant Filtering\r\n selectedUserId: string | 'all';\r\n setSelectedUserId: (userId: string | 'all') => void;\r\n\r\n // Visual Customization\r\n badgeVariant: TBadgeVariant;\r\n setBadgeVariant: (variant: TBadgeVariant) => void;\r\n\r\n // Time Configuration\r\n workingHours: TWorkingHours;\r\n setWorkingHours: Dispatch<SetStateAction<TWorkingHours>>;\r\n visibleHours: TVisibleHours;\r\n setVisibleHours: Dispatch<SetStateAction<TVisibleHours>>;\r\n showWorkingHoursOnly: boolean;\r\n setShowWorkingHoursOnly: (show: boolean) => void;\r\n slotDuration: TSlotDuration;\r\n setSlotDuration: (duration: TSlotDuration) => void;\r\n\r\n // Preferences\r\n /**\r\n * Check if a specific preference is locked by the developer.\r\n * Useful for conditionally disabling UI controls.\r\n */\r\n isPreferenceLocked: (key: TPreferenceKey) => boolean;\r\n\r\n // Data\r\n events: CalendarEvent<TEventData>[];\r\n setEvents: Dispatch<SetStateAction<CalendarEvent<TEventData>[]>>;\r\n users: ICalendarUser[];\r\n scheduleTypes: IScheduleType[];\r\n\r\n // Filter state (schedule types)\r\n selectedScheduleTypeIds: number[];\r\n setSelectedScheduleTypeIds: Dispatch<SetStateAction<number[]>>;\r\n\r\n // Search\r\n searchQuery: string;\r\n setSearchQuery: (query: string) => void;\r\n\r\n // Computed / Filtered Events\r\n filteredEvents: CalendarEvent<TEventData>[];\r\n}\r\n\r\n// ============================================================================\r\n// CONTEXT\r\n// ============================================================================\r\n\r\n// biome-ignore lint/suspicious/noExplicitAny: Context needs flexibility for different event types\r\nconst InnoCalendarContext = createContext<IInnoCalendarContext<any> | undefined>(undefined);\r\n\r\n// ============================================================================\r\n// DEFAULT WORKING HOURS\r\n// ============================================================================\r\n\r\nconst DEFAULT_WORKING_HOURS: TWorkingHours = {\r\n 0: { enabled: false, from: 8, to: 17 }, // Sunday\r\n 1: { enabled: true, from: 8, to: 17 }, // Monday\r\n 2: { enabled: true, from: 8, to: 17 }, // Tuesday\r\n 3: { enabled: true, from: 8, to: 17 }, // Wednesday\r\n 4: { enabled: true, from: 8, to: 17 }, // Thursday\r\n 5: { enabled: true, from: 8, to: 17 }, // Friday\r\n 6: { enabled: true, from: 8, to: 12 }, // Saturday\r\n};\r\n\r\nconst DEFAULT_VISIBLE_HOURS: TVisibleHours = { start: 0, end: 24 };\r\n\r\n// ============================================================================\r\n// PROVIDER PROPS - Matches agenda-v2 exactly\r\n// ============================================================================\r\n\r\nexport interface InnoCalendarProviderProps<TEventData = Record<string, unknown>> {\r\n children: ReactNode;\r\n\r\n // Initial data from server/loader\r\n initialEvents?: CalendarEvent<TEventData>[];\r\n initialUsers?: ICalendarUser[];\r\n initialScheduleTypes?: IScheduleType[];\r\n\r\n // Initial filter state (from URL)\r\n initialView?: TCalendarView;\r\n initialDate?: Date;\r\n initialSelectedUserId?: string | 'all';\r\n initialScheduleTypeIds?: number[];\r\n initialParticipantIds?: string[];\r\n initialWorkingHoursView?: 'default' | 'enabled' | 'disabled';\r\n initialSearchQuery?: string;\r\n\r\n /**\r\n * Preferences configuration for developer control\r\n */\r\n preferencesConfig?: IPreferencesConfig;\r\n\r\n // Callbacks for parent sync\r\n onDateChange?: (date: Date, view: TCalendarView) => void;\r\n onViewChange?: (view: TCalendarView) => void;\r\n}\r\n\r\n// ============================================================================\r\n// PROVIDER COMPONENT\r\n// ============================================================================\r\n\r\nexport function InnoCalendarProvider<TEventData = Record<string, unknown>>({\r\n children,\r\n initialEvents = [],\r\n initialUsers = [],\r\n initialScheduleTypes = [],\r\n initialView,\r\n initialDate,\r\n initialSelectedUserId = 'all',\r\n initialScheduleTypeIds = [],\r\n initialParticipantIds = [],\r\n initialWorkingHoursView = 'default',\r\n initialSearchQuery = '',\r\n preferencesConfig,\r\n onDateChange,\r\n onViewChange,\r\n}: InnoCalendarProviderProps<TEventData>) {\r\n // ========================================================================\r\n // PREFERENCES (persisted to localStorage)\r\n // ========================================================================\r\n const { preferences, setPreference, isLocked } =\r\n useCalendarPreferences(preferencesConfig);\r\n\r\n // ========================================================================\r\n // VIEW & NAVIGATION\r\n // ========================================================================\r\n const [view, setViewInternal] = useState<TCalendarView>(\r\n initialView ?? (preferences.view as TCalendarView) ?? 'week',\r\n );\r\n const [selectedDate, setSelectedDateInternal] = useState<Date>(\r\n initialDate ?? new Date(),\r\n );\r\n\r\n // User Filtering\r\n const [selectedUserId, setSelectedUserId] = useState<string | 'all'>(\r\n initialSelectedUserId,\r\n );\r\n\r\n // ========================================================================\r\n // PREFERENCE-BACKED STATE\r\n // ========================================================================\r\n const badgeVariant = (preferences.badgeVariant as TBadgeVariant) ?? 'colored';\r\n const setBadgeVariant = useCallback(\r\n (variant: TBadgeVariant) => {\r\n if (!isLocked('badgeVariant')) {\r\n setPreference('badgeVariant', variant);\r\n }\r\n },\r\n [setPreference, isLocked],\r\n );\r\n\r\n const workingHours = (preferences.workingHours as TWorkingHours) ?? DEFAULT_WORKING_HOURS;\r\n const setWorkingHours: Dispatch<SetStateAction<TWorkingHours>> = useCallback(\r\n (action) => {\r\n if (!isLocked('workingHours')) {\r\n const current = (preferences.workingHours as TWorkingHours) ?? DEFAULT_WORKING_HOURS;\r\n const newValue = typeof action === 'function' ? action(current) : action;\r\n setPreference('workingHours', newValue);\r\n }\r\n },\r\n [setPreference, isLocked, preferences.workingHours],\r\n );\r\n\r\n // Convert preferences format (from/to) to our format (start/end)\r\n const prefVisibleHours = preferences.visibleHours as { from?: number; to?: number; start?: number; end?: number } | undefined;\r\n const visibleHours: TVisibleHours = useMemo(() => {\r\n if (!prefVisibleHours) return DEFAULT_VISIBLE_HOURS;\r\n // Handle both formats\r\n return {\r\n start: prefVisibleHours.start ?? prefVisibleHours.from ?? 0,\r\n end: prefVisibleHours.end ?? prefVisibleHours.to ?? 24,\r\n };\r\n }, [prefVisibleHours]);\r\n\r\n const setVisibleHours: Dispatch<SetStateAction<TVisibleHours>> = useCallback(\r\n (action) => {\r\n if (!isLocked('visibleHours')) {\r\n const newValue = typeof action === 'function' ? action(visibleHours) : action;\r\n // Store in preferences format (from/to)\r\n setPreference('visibleHours', { from: newValue.start, to: newValue.end });\r\n }\r\n },\r\n [setPreference, isLocked, visibleHours],\r\n );\r\n\r\n // showWorkingHoursOnly can be overridden by URL param\r\n const [showWorkingHoursOnlyState, setShowWorkingHoursOnlyState] = useState(\r\n initialWorkingHoursView === 'enabled'\r\n ? true\r\n : initialWorkingHoursView === 'disabled'\r\n ? false\r\n : (preferences.showWorkingHoursOnly as boolean) ?? false,\r\n );\r\n const showWorkingHoursOnly = showWorkingHoursOnlyState;\r\n const setShowWorkingHoursOnly = useCallback(\r\n (show: boolean) => {\r\n setShowWorkingHoursOnlyState(show);\r\n if (!isLocked('showWorkingHoursOnly')) {\r\n setPreference('showWorkingHoursOnly', show);\r\n }\r\n },\r\n [setPreference, isLocked],\r\n );\r\n\r\n const slotDuration = (preferences.slotDuration as TSlotDuration) ?? 30;\r\n const setSlotDuration = useCallback(\r\n (duration: TSlotDuration) => {\r\n if (!isLocked('slotDuration')) {\r\n setPreference('slotDuration', duration);\r\n }\r\n },\r\n [setPreference, isLocked],\r\n );\r\n\r\n // ========================================================================\r\n // DATA\r\n // ========================================================================\r\n const [events, setEvents] = useState<CalendarEvent<TEventData>[]>(initialEvents);\r\n\r\n // Sync events when initialEvents changes (e.g., after navigation/refetch)\r\n useEffect(() => {\r\n setEvents(initialEvents);\r\n }, [initialEvents]);\r\n\r\n // Filter State\r\n const [selectedScheduleTypeIds, setSelectedScheduleTypeIds] = useState<number[]>(\r\n initialScheduleTypeIds,\r\n );\r\n const [selectedParticipantIds, _setSelectedParticipantIds] = useState<string[]>(\r\n initialParticipantIds,\r\n );\r\n\r\n // Search\r\n const [searchQuery, setSearchQuery] = useState(initialSearchQuery);\r\n\r\n // ========================================================================\r\n // VIEW & DATE SETTERS\r\n // ========================================================================\r\n const setView = useCallback(\r\n (newView: TCalendarView) => {\r\n setViewInternal(newView);\r\n if (!isLocked('view')) {\r\n setPreference('view', newView);\r\n }\r\n onViewChange?.(newView);\r\n },\r\n [onViewChange, setPreference, isLocked],\r\n );\r\n\r\n const setSelectedDate = useCallback(\r\n (newDate: Date, forView?: TCalendarView) => {\r\n setSelectedDateInternal(newDate);\r\n onDateChange?.(newDate, forView ?? view);\r\n },\r\n [onDateChange, view],\r\n );\r\n\r\n // ========================================================================\r\n // FILTERED EVENTS\r\n // ========================================================================\r\n const filteredEvents = useMemo(() => {\r\n let result = events;\r\n\r\n // Filter by schedule type\r\n if (selectedScheduleTypeIds.length > 0) {\r\n result = result.filter(\r\n (event) =>\r\n event.scheduleTypeId !== undefined &&\r\n selectedScheduleTypeIds.includes(event.scheduleTypeId),\r\n );\r\n }\r\n\r\n // Filter by participant\r\n if (selectedParticipantIds.length > 0) {\r\n result = result.filter((event) => {\r\n // Check participants array (includes primary user in this model)\r\n if (event.participants?.length) {\r\n return event.participants.some((p) =>\r\n selectedParticipantIds.includes(p.id),\r\n );\r\n }\r\n return false;\r\n });\r\n }\r\n\r\n // Filter by selected user (single user view)\r\n if (selectedUserId !== 'all') {\r\n result = result.filter((event) =>\r\n event.participants?.some((p) => p.id === selectedUserId),\r\n );\r\n }\r\n\r\n // Filter by search query\r\n if (searchQuery.trim()) {\r\n const query = searchQuery.toLowerCase();\r\n result = result.filter(\r\n (event) =>\r\n event.title.toLowerCase().includes(query) ||\r\n event.description?.toLowerCase().includes(query) ||\r\n event.scheduleTypeName?.toLowerCase().includes(query) ||\r\n event.participants?.some((p) => p.name.toLowerCase().includes(query)),\r\n );\r\n }\r\n\r\n return result;\r\n }, [\r\n events,\r\n selectedScheduleTypeIds,\r\n selectedParticipantIds,\r\n selectedUserId,\r\n searchQuery,\r\n ]);\r\n\r\n // ========================================================================\r\n // CONTEXT VALUE\r\n // ========================================================================\r\n const value = useMemo<IInnoCalendarContext<TEventData>>(\r\n () => ({\r\n // View & Navigation\r\n view,\r\n setView,\r\n selectedDate,\r\n setSelectedDate,\r\n\r\n // User Filtering\r\n selectedUserId,\r\n setSelectedUserId,\r\n\r\n // Visual Customization\r\n badgeVariant,\r\n setBadgeVariant,\r\n\r\n // Time Configuration\r\n workingHours,\r\n setWorkingHours,\r\n visibleHours,\r\n setVisibleHours,\r\n showWorkingHoursOnly,\r\n setShowWorkingHoursOnly,\r\n slotDuration,\r\n setSlotDuration,\r\n\r\n // Preferences\r\n isPreferenceLocked: isLocked,\r\n\r\n // Data\r\n events,\r\n setEvents,\r\n users: initialUsers,\r\n scheduleTypes: initialScheduleTypes,\r\n\r\n // Filters\r\n selectedScheduleTypeIds,\r\n setSelectedScheduleTypeIds,\r\n\r\n // Search\r\n searchQuery,\r\n setSearchQuery,\r\n\r\n // Computed\r\n filteredEvents,\r\n }),\r\n [\r\n view,\r\n setView,\r\n selectedDate,\r\n setSelectedDate,\r\n selectedUserId,\r\n badgeVariant,\r\n setBadgeVariant,\r\n workingHours,\r\n setWorkingHours,\r\n visibleHours,\r\n setVisibleHours,\r\n showWorkingHoursOnly,\r\n setShowWorkingHoursOnly,\r\n slotDuration,\r\n setSlotDuration,\r\n isLocked,\r\n events,\r\n initialUsers,\r\n initialScheduleTypes,\r\n selectedScheduleTypeIds,\r\n searchQuery,\r\n filteredEvents,\r\n ],\r\n );\r\n\r\n return (\r\n <InnoCalendarContext.Provider value={value}>\r\n {children}\r\n </InnoCalendarContext.Provider>\r\n );\r\n}\r\n\r\n// ============================================================================\r\n// HOOKS\r\n// ============================================================================\r\n\r\n/**\r\n * Get the full calendar context\r\n * This is the primary hook - use this in most components\r\n */\r\nexport function useInnoCalendar<\r\n TEventData = Record<string, unknown>,\r\n>(): IInnoCalendarContext<TEventData> {\r\n const context = useContext(InnoCalendarContext);\r\n if (!context) {\r\n throw new Error(\r\n 'useInnoCalendar must be used within an InnoCalendarProvider',\r\n );\r\n }\r\n return context as IInnoCalendarContext<TEventData>;\r\n}\r\n\r\n/**\r\n * Optional calendar context hook\r\n */\r\nexport function useOptionalInnoCalendar<\r\n TEventData = Record<string, unknown>,\r\n>(): IInnoCalendarContext<TEventData> | undefined {\r\n return useContext(InnoCalendarContext) as\r\n | IInnoCalendarContext<TEventData>\r\n | undefined;\r\n}\r\n\r\n// ============================================================================\r\n// SELECTIVE HOOKS (for performance optimization)\r\n// ============================================================================\r\n\r\n/**\r\n * Access only view-related state\r\n */\r\nexport function useInnoCalendarView() {\r\n const { view, setView, selectedDate, setSelectedDate, slotDuration } =\r\n useInnoCalendar();\r\n return { view, setView, selectedDate, setSelectedDate, slotDuration };\r\n}\r\n\r\n/**\r\n * Access only events data\r\n */\r\nexport function useInnoCalendarEvents<TEventData = Record<string, unknown>>() {\r\n const { events, setEvents, filteredEvents } = useInnoCalendar<TEventData>();\r\n return { events, setEvents, filteredEvents };\r\n}\r\n\r\n/**\r\n * Access only filter state\r\n */\r\nexport function useInnoCalendarFilters() {\r\n const {\r\n selectedScheduleTypeIds,\r\n setSelectedScheduleTypeIds,\r\n selectedUserId,\r\n setSelectedUserId,\r\n searchQuery,\r\n setSearchQuery,\r\n } = useInnoCalendar();\r\n return {\r\n selectedScheduleTypeIds,\r\n setSelectedScheduleTypeIds,\r\n selectedUserId,\r\n setSelectedUserId,\r\n searchQuery,\r\n setSearchQuery,\r\n };\r\n}\r\n\r\n/**\r\n * Access only time configuration\r\n */\r\nexport function useInnoCalendarTimeConfig() {\r\n const {\r\n workingHours,\r\n setWorkingHours,\r\n visibleHours,\r\n setVisibleHours,\r\n showWorkingHoursOnly,\r\n setShowWorkingHoursOnly,\r\n } = useInnoCalendar();\r\n return {\r\n workingHours,\r\n setWorkingHours,\r\n visibleHours,\r\n setVisibleHours,\r\n showWorkingHoursOnly,\r\n setShowWorkingHoursOnly,\r\n };\r\n}\r\n"],"names":["useCalendar","options","events","resources","scheduleTypes","initialView","initialDate","initialFilters","userPreferences","lockedPreferences","locale","onViewChange","onDateChange","onEventClick","onSlotSelect","onFiltersChange","view","setViewState","useState","currentDate","setCurrentDateState","filters","setFiltersState","preferences","setPreferencesState","DEFAULT_PREFERENCES","dateRange","useMemo","getViewDateRange","viewTitle","getViewTitle","filteredEvents","result","filterEventsByDateRange","scheduleTypeIds","filterEventsByScheduleType","resourceIds","filterEventsByResource","search","filterEventsBySearch","filterOutCanceled","sortEventsByStart","setView","useCallback","newView","setCurrentDate","date","goToNext","newDate","navigateNext","goToPrev","navigatePrev","goToToday","navigateToday","goToDate","setFilters","newFilters","updateFilters","updates","prev","next","clearFilters","emptyFilters","setPreferences","prefs","handleEventClick","event","handleSlotSelect","selection","CalendarContext","createContext","CalendarProvider","children","value","jsx","useCalendarContext","context","useContext","useOptionalCalendarContext","useCalendarView","useCalendarDate","useCalendarEvents","useCalendarFilters","useCalendarPreferences","PREFERENCES_STORAGE_KEY","DEFAULT_VISIBLE_HOURS","DEFAULT_WORKING_HOURS","DEFAULT_SLOT_DURATION","SYSTEM_DEFAULTS","loadFromStorage","key","stored","parsed","sanitized","saveToStorage","config","modes","locked","defaults","storageKey","disableStorage","effectiveDefaults","storedPreferences","setStoredPreferences","sessionPreferences","setSessionPreferences","useEffect","getMode","isLocked","isPersisted","mode","setPreference","sessionUpdates","storedUpdates","resetPreferences","resetPreference","_","rest","InnoCalendarContext","InnoCalendarProvider","initialEvents","initialUsers","initialScheduleTypes","initialSelectedUserId","initialScheduleTypeIds","initialParticipantIds","initialWorkingHoursView","initialSearchQuery","preferencesConfig","setViewInternal","selectedDate","setSelectedDateInternal","selectedUserId","setSelectedUserId","badgeVariant","setBadgeVariant","variant","workingHours","setWorkingHours","action","current","newValue","prefVisibleHours","visibleHours","setVisibleHours","showWorkingHoursOnlyState","setShowWorkingHoursOnlyState","showWorkingHoursOnly","setShowWorkingHoursOnly","show","slotDuration","setSlotDuration","duration","setEvents","selectedScheduleTypeIds","setSelectedScheduleTypeIds","selectedParticipantIds","_setSelectedParticipantIds","searchQuery","setSearchQuery","setSelectedDate","forView","query","p","useInnoCalendar","useOptionalInnoCalendar","useInnoCalendarView","useInnoCalendarEvents","useInnoCalendarFilters","useInnoCalendarTimeConfig"],"mappings":"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"}
1
+ {"version":3,"file":"inno-calendar-provider-CEO8ZyR2.cjs","sources":["../src/core/hooks/use-calendar.ts","../src/core/context/calendar-context.tsx","../src/core/preferences/types.ts","../src/core/preferences/use-preferences.ts","../src/core/context/inno-calendar-provider.tsx"],"sourcesContent":["/**\r\n * useCalendar - Main Calendar Hook\r\n *\r\n * This hook provides all the state and methods needed to build a calendar.\r\n * It is fully generic, allowing consumers to define their own event data types.\r\n *\r\n * @example\r\n * ```tsx\r\n * interface MyEventData {\r\n * projectId: number;\r\n * priority: 'low' | 'medium' | 'high';\r\n * }\r\n *\r\n * const calendar = useCalendar<MyEventData>({\r\n * events: myEvents,\r\n * onEventClick: (event) => {\r\n * console.log(event.data?.projectId);\r\n * },\r\n * });\r\n * ```\r\n */\r\n\r\nimport { useState, useMemo, useCallback } from 'react';\r\nimport type {\r\n\tCalendarEvent,\r\n\tTCalendarView,\r\n\tICalendarPreferences,\r\n\tICalendarFilters,\r\n\tIResource,\r\n\tIScheduleType,\r\n\tISelectionResult,\r\n\tIDateRange,\r\n} from '../types';\r\nimport { DEFAULT_PREFERENCES } from '../constants';\r\nimport {\r\n\tgetViewDateRange,\r\n\tnavigateNext,\r\n\tnavigatePrev,\r\n\tnavigateToday,\r\n\tgetViewTitle,\r\n} from '../utils/grid-utils';\r\nimport {\r\n\tfilterEventsByDateRange,\r\n\tfilterEventsByScheduleType,\r\n\tfilterEventsByResource,\r\n\tfilterEventsBySearch,\r\n\tfilterOutCanceled,\r\n\tsortEventsByStart,\r\n} from '../utils/event-utils';\r\n\r\n// ============================================================================\r\n// TYPES\r\n// ============================================================================\r\n\r\n/**\r\n * Options for useCalendar hook\r\n */\r\nexport interface UseCalendarOptions<\r\n\tTEventData = Record<string, unknown>,\r\n\tTScheduleTypeData = Record<string, unknown>,\r\n\tTResourceData = Record<string, unknown>,\r\n> {\r\n\t/** Events to display */\r\n\tevents: CalendarEvent<TEventData>[];\r\n\r\n\t/** Available resources (for resource views) */\r\n\tresources?: IResource<TResourceData>[] | undefined;\r\n\r\n\t/** Available schedule types */\r\n\tscheduleTypes?: IScheduleType<TScheduleTypeData>[] | undefined;\r\n\r\n\t/** Initial view */\r\n\tinitialView?: TCalendarView | undefined;\r\n\r\n\t/** Initial date */\r\n\tinitialDate?: Date | undefined;\r\n\r\n\t/** Initial filters */\r\n\tinitialFilters?: ICalendarFilters | undefined;\r\n\r\n\t/** User preferences */\r\n\tpreferences?: Partial<ICalendarPreferences> | undefined;\r\n\r\n\t/** Locked preferences (cannot be changed by user) */\r\n\tlockedPreferences?: Partial<ICalendarPreferences> | undefined;\r\n\r\n\t/** Locale for formatting */\r\n\tlocale?: string | undefined;\r\n\r\n\t/** Callback when view changes */\r\n\tonViewChange?: ((view: TCalendarView) => void) | undefined;\r\n\r\n\t/** Callback when date changes */\r\n\tonDateChange?: ((date: Date) => void) | undefined;\r\n\r\n\t/** Callback when event is clicked */\r\n\tonEventClick?: ((event: CalendarEvent<TEventData>) => void) | undefined;\r\n\r\n\t/** Callback when slot is selected */\r\n\tonSlotSelect?: ((selection: ISelectionResult) => void) | undefined;\r\n\r\n\t/** Callback when filters change */\r\n\tonFiltersChange?: ((filters: ICalendarFilters) => void) | undefined;\r\n}\r\n\r\n/**\r\n * Return type for useCalendar hook\r\n */\r\nexport interface UseCalendarReturn<\r\n\tTEventData = Record<string, unknown>,\r\n\tTScheduleTypeData = Record<string, unknown>,\r\n\tTResourceData = Record<string, unknown>,\r\n> {\r\n\t// State\r\n\tview: TCalendarView;\r\n\tcurrentDate: Date;\r\n\tdateRange: IDateRange;\r\n\tfilters: ICalendarFilters;\r\n\tpreferences: ICalendarPreferences;\r\n\r\n\t// Computed\r\n\tfilteredEvents: CalendarEvent<TEventData>[];\r\n\tviewTitle: string;\r\n\r\n\t// Data\r\n\tevents: CalendarEvent<TEventData>[];\r\n\tresources: IResource<TResourceData>[];\r\n\tscheduleTypes: IScheduleType<TScheduleTypeData>[];\r\n\r\n\t// Actions\r\n\tsetView: (view: TCalendarView) => void;\r\n\tsetCurrentDate: (date: Date) => void;\r\n\tgoToNext: () => void;\r\n\tgoToPrev: () => void;\r\n\tgoToToday: () => void;\r\n\tgoToDate: (date: Date) => void;\r\n\r\n\t// Filters\r\n\tsetFilters: (filters: ICalendarFilters) => void;\r\n\tupdateFilters: (updates: Partial<ICalendarFilters>) => void;\r\n\tclearFilters: () => void;\r\n\r\n\t// Preferences\r\n\tsetPreferences: (prefs: Partial<ICalendarPreferences>) => void;\r\n\r\n\t// Event handlers\r\n\thandleEventClick: (event: CalendarEvent<TEventData>) => void;\r\n\thandleSlotSelect: (selection: ISelectionResult) => void;\r\n}\r\n\r\n// ============================================================================\r\n// HOOK\r\n// ============================================================================\r\n\r\nexport function useCalendar<\r\n\tTEventData = Record<string, unknown>,\r\n\tTScheduleTypeData = Record<string, unknown>,\r\n\tTResourceData = Record<string, unknown>,\r\n>(\r\n\toptions: UseCalendarOptions<TEventData, TScheduleTypeData, TResourceData>,\r\n): UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData> {\r\n\tconst {\r\n\t\tevents,\r\n\t\tresources = [],\r\n\t\tscheduleTypes = [],\r\n\t\tinitialView = 'week',\r\n\t\tinitialDate,\r\n\t\tinitialFilters = {},\r\n\t\tpreferences: userPreferences = {},\r\n\t\tlockedPreferences = {},\r\n\t\tlocale = 'en-US',\r\n\t\tonViewChange,\r\n\t\tonDateChange,\r\n\t\tonEventClick,\r\n\t\tonSlotSelect,\r\n\t\tonFiltersChange,\r\n\t} = options;\r\n\r\n\t// ========================================================================\r\n\t// STATE\r\n\t// ========================================================================\r\n\r\n\tconst [view, setViewState] = useState<TCalendarView>(initialView);\r\n\tconst [currentDate, setCurrentDateState] = useState<Date>(() => initialDate ?? new Date());\r\n\tconst [filters, setFiltersState] = useState<ICalendarFilters>(initialFilters);\r\n\tconst [preferences, setPreferencesState] = useState<ICalendarPreferences>(() => ({\r\n\t\t...DEFAULT_PREFERENCES,\r\n\t\t...userPreferences,\r\n\t\t...lockedPreferences,\r\n\t}));\r\n\r\n\t// ========================================================================\r\n\t// COMPUTED\r\n\t// ========================================================================\r\n\r\n\tconst dateRange = useMemo(\r\n\t\t() => getViewDateRange(currentDate, view, preferences.firstDayOfWeek),\r\n\t\t[currentDate, view, preferences.firstDayOfWeek],\r\n\t);\r\n\r\n\tconst viewTitle = useMemo(\r\n\t\t() => getViewTitle(currentDate, view, locale),\r\n\t\t[currentDate, view, locale],\r\n\t);\r\n\r\n\tconst filteredEvents = useMemo(() => {\r\n\t\tlet result = [...events];\r\n\r\n\t\t// Filter by date range\r\n\t\tresult = filterEventsByDateRange(result, dateRange.startDate, dateRange.endDate);\r\n\r\n\t\t// Filter by schedule types\r\n\t\tconst scheduleTypeIds = filters.scheduleTypeIds;\r\n\t\tif (scheduleTypeIds && scheduleTypeIds.length > 0) {\r\n\t\t\tresult = filterEventsByScheduleType(result, scheduleTypeIds);\r\n\t\t}\r\n\r\n\t\t// Filter by resources\r\n\t\tconst resourceIds = filters.resourceIds;\r\n\t\tif (resourceIds && resourceIds.length > 0) {\r\n\t\t\tresult = filterEventsByResource(result, resourceIds);\r\n\t\t}\r\n\r\n\t\t// Filter by search\r\n\t\tconst search = filters.search;\r\n\t\tif (search) {\r\n\t\t\tresult = filterEventsBySearch(result, search);\r\n\t\t}\r\n\r\n\t\t// Filter canceled\r\n\t\tif (!preferences.showCanceledEvents) {\r\n\t\t\tresult = filterOutCanceled(result);\r\n\t\t}\r\n\r\n\t\t// Sort by start date\r\n\t\treturn sortEventsByStart(result);\r\n\t}, [events, dateRange, filters, preferences.showCanceledEvents]);\r\n\r\n\t// ========================================================================\r\n\t// ACTIONS\r\n\t// ========================================================================\r\n\r\n\tconst setView = useCallback(\r\n\t\t(newView: TCalendarView) => {\r\n\t\t\tsetViewState(newView);\r\n\t\t\tonViewChange?.(newView);\r\n\t\t},\r\n\t\t[onViewChange],\r\n\t);\r\n\r\n\tconst setCurrentDate = useCallback(\r\n\t\t(date: Date) => {\r\n\t\t\tsetCurrentDateState(date);\r\n\t\t\tonDateChange?.(date);\r\n\t\t},\r\n\t\t[onDateChange],\r\n\t);\r\n\r\n\tconst goToNext = useCallback(() => {\r\n\t\tconst newDate = navigateNext(currentDate, view);\r\n\t\tsetCurrentDate(newDate);\r\n\t}, [currentDate, view, setCurrentDate]);\r\n\r\n\tconst goToPrev = useCallback(() => {\r\n\t\tconst newDate = navigatePrev(currentDate, view);\r\n\t\tsetCurrentDate(newDate);\r\n\t}, [currentDate, view, setCurrentDate]);\r\n\r\n\tconst goToToday = useCallback(() => {\r\n\t\tsetCurrentDate(navigateToday());\r\n\t}, [setCurrentDate]);\r\n\r\n\tconst goToDate = useCallback(\r\n\t\t(date: Date) => {\r\n\t\t\tsetCurrentDate(date);\r\n\t\t},\r\n\t\t[setCurrentDate],\r\n\t);\r\n\r\n\t// ========================================================================\r\n\t// FILTERS\r\n\t// ========================================================================\r\n\r\n\tconst setFilters = useCallback(\r\n\t\t(newFilters: ICalendarFilters) => {\r\n\t\t\tsetFiltersState(newFilters);\r\n\t\t\tonFiltersChange?.(newFilters);\r\n\t\t},\r\n\t\t[onFiltersChange],\r\n\t);\r\n\r\n\tconst updateFilters = useCallback(\r\n\t\t(updates: Partial<ICalendarFilters>) => {\r\n\t\t\tsetFiltersState((prev) => {\r\n\t\t\t\tconst next = { ...prev, ...updates };\r\n\t\t\t\tonFiltersChange?.(next);\r\n\t\t\t\treturn next;\r\n\t\t\t});\r\n\t\t},\r\n\t\t[onFiltersChange],\r\n\t);\r\n\r\n\tconst clearFilters = useCallback(() => {\r\n\t\tconst emptyFilters: ICalendarFilters = {};\r\n\t\tsetFiltersState(emptyFilters);\r\n\t\tonFiltersChange?.(emptyFilters);\r\n\t}, [onFiltersChange]);\r\n\r\n\t// ========================================================================\r\n\t// PREFERENCES\r\n\t// ========================================================================\r\n\r\n\tconst setPreferences = useCallback(\r\n\t\t(prefs: Partial<ICalendarPreferences>) => {\r\n\t\t\tsetPreferencesState((prev) => ({\r\n\t\t\t\t...prev,\r\n\t\t\t\t...prefs,\r\n\t\t\t\t...lockedPreferences, // Locked prefs always override\r\n\t\t\t}));\r\n\t\t},\r\n\t\t[lockedPreferences],\r\n\t);\r\n\r\n\t// ========================================================================\r\n\t// EVENT HANDLERS\r\n\t// ========================================================================\r\n\r\n\tconst handleEventClick = useCallback(\r\n\t\t(event: CalendarEvent<TEventData>) => {\r\n\t\t\tonEventClick?.(event);\r\n\t\t},\r\n\t\t[onEventClick],\r\n\t);\r\n\r\n\tconst handleSlotSelect = useCallback(\r\n\t\t(selection: ISelectionResult) => {\r\n\t\t\tonSlotSelect?.(selection);\r\n\t\t},\r\n\t\t[onSlotSelect],\r\n\t);\r\n\r\n\t// ========================================================================\r\n\t// RETURN\r\n\t// ========================================================================\r\n\r\n\treturn {\r\n\t\t// State\r\n\t\tview,\r\n\t\tcurrentDate,\r\n\t\tdateRange,\r\n\t\tfilters,\r\n\t\tpreferences,\r\n\r\n\t\t// Computed\r\n\t\tfilteredEvents,\r\n\t\tviewTitle,\r\n\r\n\t\t// Data\r\n\t\tevents,\r\n\t\tresources,\r\n\t\tscheduleTypes,\r\n\r\n\t\t// Actions\r\n\t\tsetView,\r\n\t\tsetCurrentDate,\r\n\t\tgoToNext,\r\n\t\tgoToPrev,\r\n\t\tgoToToday,\r\n\t\tgoToDate,\r\n\r\n\t\t// Filters\r\n\t\tsetFilters,\r\n\t\tupdateFilters,\r\n\t\tclearFilters,\r\n\r\n\t\t// Preferences\r\n\t\tsetPreferences,\r\n\r\n\t\t// Event handlers\r\n\t\thandleEventClick,\r\n\t\thandleSlotSelect,\r\n\t};\r\n}\r\n","/**\r\n * CalendarContext - React Context for Calendar State\r\n *\r\n * Provides calendar state to deeply nested components without prop drilling.\r\n */\r\n\r\nimport { createContext, useContext, type ReactNode } from 'react';\r\nimport type { UseCalendarReturn } from '../hooks/use-calendar';\r\n\r\n// ============================================================================\r\n// CONTEXT\r\n// ============================================================================\r\n\r\n/**\r\n * Calendar context type - generic to support any event data type\r\n * We use `any` here because context consumers may not know the exact type\r\n * Use the typed hooks below for type-safe access\r\n */\r\n// biome-ignore lint/suspicious/noExplicitAny: Context needs to be flexible for different event types\r\nconst CalendarContext = createContext<UseCalendarReturn<any, any, any> | undefined>(undefined);\r\n\r\n// ============================================================================\r\n// PROVIDER\r\n// ============================================================================\r\n\r\nexport interface CalendarProviderProps<\r\n TEventData = Record<string, unknown>,\r\n TScheduleTypeData = Record<string, unknown>,\r\n TResourceData = Record<string, unknown>,\r\n> {\r\n children: ReactNode;\r\n value: UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData>;\r\n}\r\n\r\nexport function CalendarProvider<\r\n TEventData = Record<string, unknown>,\r\n TScheduleTypeData = Record<string, unknown>,\r\n TResourceData = Record<string, unknown>,\r\n>({ children, value }: CalendarProviderProps<TEventData, TScheduleTypeData, TResourceData>) {\r\n return <CalendarContext.Provider value={value}>{children}</CalendarContext.Provider>;\r\n}\r\n\r\n// ============================================================================\r\n// HOOKS\r\n// ============================================================================\r\n\r\n/**\r\n * Get the full calendar context (throws if not in provider)\r\n */\r\nexport function useCalendarContext<\r\n TEventData = Record<string, unknown>,\r\n TScheduleTypeData = Record<string, unknown>,\r\n TResourceData = Record<string, unknown>,\r\n>(): UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData> {\r\n const context = useContext(CalendarContext);\r\n if (!context) {\r\n throw new Error('useCalendarContext must be used within a CalendarProvider');\r\n }\r\n return context as UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData>;\r\n}\r\n\r\n/**\r\n * Get the calendar context or undefined (safe version)\r\n */\r\nexport function useOptionalCalendarContext<\r\n TEventData = Record<string, unknown>,\r\n TScheduleTypeData = Record<string, unknown>,\r\n TResourceData = Record<string, unknown>,\r\n>(): UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData> | undefined {\r\n const context = useContext(CalendarContext);\r\n return context as UseCalendarReturn<TEventData, TScheduleTypeData, TResourceData> | undefined;\r\n}\r\n\r\n// ============================================================================\r\n// CONVENIENCE HOOKS\r\n// ============================================================================\r\n\r\n/**\r\n * Get current view\r\n */\r\nexport function useCalendarView() {\r\n const { view, setView } = useCalendarContext();\r\n return { view, setView };\r\n}\r\n\r\n/**\r\n * Get current date and navigation\r\n */\r\nexport function useCalendarDate() {\r\n const { currentDate, setCurrentDate, goToNext, goToPrev, goToToday, goToDate } =\r\n useCalendarContext();\r\n return { currentDate, setCurrentDate, goToNext, goToPrev, goToToday, goToDate };\r\n}\r\n\r\n/**\r\n * Get filtered events\r\n */\r\nexport function useCalendarEvents<TEventData = Record<string, unknown>>() {\r\n const { events, filteredEvents } = useCalendarContext<TEventData>();\r\n return { events, filteredEvents };\r\n}\r\n\r\n/**\r\n * Get filters\r\n */\r\nexport function useCalendarFilters() {\r\n const { filters, setFilters, updateFilters, clearFilters } = useCalendarContext();\r\n return { filters, setFilters, updateFilters, clearFilters };\r\n}\r\n\r\n/**\r\n * Get preferences\r\n */\r\nexport function useCalendarPreferences() {\r\n const { preferences, setPreferences } = useCalendarContext();\r\n return { preferences, setPreferences };\r\n}\r\n\r\n// ============================================================================\r\n// ALIASES (for agenda-v2 naming convention compatibility)\r\n// ============================================================================\r\n\r\n/**\r\n * Alias for useCalendarContext - matches agenda-v2 naming convention\r\n */\r\nexport { useCalendarContext as useCalendar };\r\n\r\n/**\r\n * Alias for useOptionalCalendarContext - matches agenda-v2 naming convention\r\n */\r\nexport { useOptionalCalendarContext as useOptionalCalendar };\r\n","/**\r\n * Calendar Preferences Types\r\n *\r\n * Type definitions for the calendar preferences system.\r\n * This module enables:\r\n * - Persistent user preferences via localStorage\r\n * - Developer-controlled defaults and overrides\r\n * - Locking preferences to prevent user modifications\r\n * - Complete customization for different deployment scenarios\r\n */\r\n\r\nimport type { TBadgeVariant, TCalendarView, TSlotDuration } from '../types';\r\n\r\n// ============================================================================\r\n// PREFERENCE KEYS\r\n// ============================================================================\r\n\r\n/**\r\n * All available preference keys\r\n */\r\nexport type TPreferenceKey =\r\n\t| 'view'\r\n\t| 'badgeVariant'\r\n\t| 'slotDuration'\r\n\t| 'visibleHours'\r\n\t| 'workingHours'\r\n\t| 'showWorkingHoursOnly'\r\n\t| 'showWeekends'\r\n\t| 'firstDayOfWeek';\r\n\r\n/**\r\n * Storage key for localStorage\r\n */\r\nexport const PREFERENCES_STORAGE_KEY = 'inno-calendar-preferences';\r\n\r\n// ============================================================================\r\n// PREFERENCE VALUE TYPES\r\n// ============================================================================\r\n\r\n/**\r\n * Visible hours configuration\r\n */\r\nexport interface IVisibleHoursConfig {\r\n\tfrom: number;\r\n\tto: number;\r\n}\r\n\r\n/**\r\n * Working hours configuration per day of week\r\n * Key: 0 = Sunday, 1 = Monday, ..., 6 = Saturday\r\n */\r\nexport type TWorkingHoursConfig = {\r\n\t[dayIndex: number]: { from: number; to: number };\r\n};\r\n\r\n// ============================================================================\r\n// PREFERENCE VALUES\r\n// ============================================================================\r\n\r\n/**\r\n * Complete preferences object structure\r\n */\r\nexport interface IPreferences {\r\n\t/** Default calendar view */\r\n\tview: TCalendarView;\r\n\t/** Event badge display style */\r\n\tbadgeVariant: TBadgeVariant;\r\n\t/** Time slot duration in minutes (15, 30, 60) */\r\n\tslotDuration: TSlotDuration;\r\n\t/** Visible hours range for day/week views */\r\n\tvisibleHours: IVisibleHoursConfig;\r\n\t/** Working hours configuration per day */\r\n\tworkingHours: TWorkingHoursConfig;\r\n\t/** Show only working hours in day/week views */\r\n\tshowWorkingHoursOnly: boolean;\r\n\t/** Show weekend days */\r\n\tshowWeekends: boolean;\r\n\t/** First day of week (0 = Sunday, 1 = Monday, etc.) */\r\n\tfirstDayOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6;\r\n}\r\n\r\n/**\r\n * Partial preferences for updates\r\n */\r\nexport type TPartialPreferences = Partial<IPreferences>;\r\n\r\n// ============================================================================\r\n// PREFERENCE CONTROL\r\n// ============================================================================\r\n\r\n/**\r\n * Control mode for each preference\r\n * - 'user': User can modify, persisted to localStorage\r\n * - 'locked': Developer-controlled, cannot be modified by user\r\n * - 'session': User can modify during session, not persisted\r\n */\r\nexport type TPreferenceMode = 'user' | 'locked' | 'session';\r\n\r\n/**\r\n * Configuration for preference control\r\n * Allows developers to lock certain preferences to specific values\r\n */\r\nexport type TPreferenceModes = {\r\n\t[K in TPreferenceKey]?: TPreferenceMode;\r\n};\r\n\r\n/**\r\n * Locked values for preferences\r\n * When a preference mode is 'locked', this value is used\r\n */\r\nexport type TLockedPreferences = TPartialPreferences;\r\n\r\n// ============================================================================\r\n// PREFERENCES CONFIG\r\n// ============================================================================\r\n\r\n/**\r\n * Complete preferences configuration for developers\r\n *\r\n * @example\r\n * // Allow all preferences to be user-controlled (default)\r\n * const config: IPreferencesConfig = {};\r\n *\r\n * @example\r\n * // Lock slot duration to 30 minutes, let users control the rest\r\n * const config: IPreferencesConfig = {\r\n * modes: { slotDuration: 'locked' },\r\n * locked: { slotDuration: 30 }\r\n * };\r\n *\r\n * @example\r\n * // Completely override all preferences (no user control)\r\n * const config: IPreferencesConfig = {\r\n * modes: {\r\n * view: 'locked',\r\n * badgeVariant: 'locked',\r\n * slotDuration: 'locked',\r\n * visibleHours: 'locked',\r\n * workingHours: 'locked',\r\n * showWorkingHoursOnly: 'locked'\r\n * },\r\n * locked: {\r\n * view: 'week',\r\n * badgeVariant: 'colored',\r\n * slotDuration: 30,\r\n * visibleHours: { from: 8, to: 18 },\r\n * workingHours: { ... },\r\n * showWorkingHoursOnly: true\r\n * }\r\n * };\r\n */\r\nexport interface IPreferencesConfig {\r\n\t/**\r\n\t * Control mode for each preference\r\n\t * Defaults to 'user' for all preferences\r\n\t */\r\n\tmodes?: TPreferenceModes;\r\n\r\n\t/**\r\n\t * Values to use when preference mode is 'locked'\r\n\t */\r\n\tlocked?: TLockedPreferences;\r\n\r\n\t/**\r\n\t * Custom default values (used when no stored preference exists)\r\n\t * These override the system defaults\r\n\t */\r\n\tdefaults?: TPartialPreferences;\r\n\r\n\t/**\r\n\t * Custom localStorage key (default: 'inno-calendar-preferences')\r\n\t * Useful when multiple calendar instances need separate storage\r\n\t */\r\n\tstorageKey?: string;\r\n\r\n\t/**\r\n\t * Disable localStorage entirely\r\n\t * All preferences will reset on page reload\r\n\t */\r\n\tdisableStorage?: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// HOOK RETURN TYPE\r\n// ============================================================================\r\n\r\n/**\r\n * Return type for useCalendarPreferences hook\r\n */\r\nexport interface IUsePreferencesReturn {\r\n\t/** Current preference values */\r\n\tpreferences: IPreferences;\r\n\r\n\t/** Update a single preference */\r\n\tsetPreference: <K extends TPreferenceKey>(key: K, value: IPreferences[K]) => void;\r\n\r\n\t/** Update multiple preferences at once */\r\n\tsetPreferences: (updates: TPartialPreferences) => void;\r\n\r\n\t/** Reset preferences to defaults */\r\n\tresetPreferences: () => void;\r\n\r\n\t/** Reset a single preference to default */\r\n\tresetPreference: (key: TPreferenceKey) => void;\r\n\r\n\t/** Check if a preference is locked */\r\n\tisLocked: (key: TPreferenceKey) => boolean;\r\n\r\n\t/** Check if a preference is persisted */\r\n\tisPersisted: (key: TPreferenceKey) => boolean;\r\n\r\n\t/** Get the mode for a preference */\r\n\tgetMode: (key: TPreferenceKey) => TPreferenceMode;\r\n}\r\n","/**\r\n * Calendar Preferences Hook\r\n *\r\n * Manages calendar preferences with localStorage persistence and developer control.\r\n *\r\n * Features:\r\n * - Automatic localStorage persistence\r\n * - Developer-controlled defaults and overrides\r\n * - Preference locking for controlled deployments\r\n * - Session-only preferences that don't persist\r\n * - Type-safe preference access and updates\r\n *\r\n * @example Basic usage\r\n * ```tsx\r\n * const { preferences, setPreference } = useCalendarPreferences();\r\n * setPreference('slotDuration', 30);\r\n * ```\r\n *\r\n * @example With developer configuration\r\n * ```tsx\r\n * const { preferences } = useCalendarPreferences({\r\n * modes: { slotDuration: 'locked' },\r\n * locked: { slotDuration: 60 },\r\n * defaults: { view: 'week' }\r\n * });\r\n * ```\r\n */\r\n\r\nimport { useCallback, useEffect, useMemo, useState } from 'react';\r\nimport type { TWorkingHours } from '../types';\r\nimport {\r\n\tPREFERENCES_STORAGE_KEY,\r\n\ttype IPreferences,\r\n\ttype IPreferencesConfig,\r\n\ttype IUsePreferencesReturn,\r\n\ttype TPartialPreferences,\r\n\ttype TPreferenceKey,\r\n\ttype TPreferenceMode,\r\n} from './types';\r\n\r\n// ============================================================================\r\n// SYSTEM DEFAULTS\r\n// ============================================================================\r\n\r\n/**\r\n * Default visible hours\r\n */\r\nexport const DEFAULT_VISIBLE_HOURS = {\r\n\tfrom: 0,\r\n\tto: 24,\r\n};\r\n\r\n/**\r\n * Default working hours (Monday-Friday, 8am-6pm)\r\n */\r\nexport const DEFAULT_WORKING_HOURS: TWorkingHours = {\r\n\t0: { enabled: false, from: 8, to: 18 }, // Sunday - disabled\r\n\t1: { enabled: true, from: 8, to: 18 }, // Monday\r\n\t2: { enabled: true, from: 8, to: 18 }, // Tuesday\r\n\t3: { enabled: true, from: 8, to: 18 }, // Wednesday\r\n\t4: { enabled: true, from: 8, to: 18 }, // Thursday\r\n\t5: { enabled: true, from: 8, to: 18 }, // Friday\r\n\t6: { enabled: false, from: 8, to: 18 }, // Saturday - disabled\r\n};\r\n\r\n/**\r\n * Default slot duration in minutes\r\n */\r\nexport const DEFAULT_SLOT_DURATION = 30;\r\n\r\n/**\r\n * System default preferences\r\n * These are used when no stored preference or custom default exists\r\n */\r\nconst SYSTEM_DEFAULTS: IPreferences = {\r\n\tview: 'month',\r\n\tbadgeVariant: 'colored',\r\n\tslotDuration: DEFAULT_SLOT_DURATION,\r\n\tvisibleHours: DEFAULT_VISIBLE_HOURS,\r\n\tworkingHours: DEFAULT_WORKING_HOURS,\r\n\tshowWorkingHoursOnly: false,\r\n\tshowWeekends: true,\r\n\tfirstDayOfWeek: 1,\r\n};\r\n\r\n// ============================================================================\r\n// STORAGE HELPERS\r\n// ============================================================================\r\n\r\n/**\r\n * Load preferences from localStorage\r\n */\r\nfunction loadFromStorage(key: string): TPartialPreferences {\r\n\tif (typeof window === 'undefined') return {};\r\n\r\n\ttry {\r\n\t\tconst stored = localStorage.getItem(key);\r\n\t\tif (!stored) return {};\r\n\r\n\t\tconst parsed = JSON.parse(stored);\r\n\r\n\t\t// Validate and sanitize stored values\r\n\t\tconst sanitized: TPartialPreferences = {};\r\n\r\n\t\tif (parsed.view && typeof parsed.view === 'string') {\r\n\t\t\tsanitized.view = parsed.view;\r\n\t\t}\r\n\r\n\t\tif (parsed.badgeVariant && typeof parsed.badgeVariant === 'string') {\r\n\t\t\tsanitized.badgeVariant = parsed.badgeVariant;\r\n\t\t}\r\n\r\n\t\tif (parsed.slotDuration && typeof parsed.slotDuration === 'number') {\r\n\t\t\tsanitized.slotDuration = parsed.slotDuration;\r\n\t\t}\r\n\r\n\t\tif (parsed.visibleHours && typeof parsed.visibleHours === 'object') {\r\n\t\t\tsanitized.visibleHours = parsed.visibleHours;\r\n\t\t}\r\n\r\n\t\tif (parsed.workingHours && typeof parsed.workingHours === 'object') {\r\n\t\t\tsanitized.workingHours = parsed.workingHours;\r\n\t\t}\r\n\r\n\t\tif (typeof parsed.showWorkingHoursOnly === 'boolean') {\r\n\t\t\tsanitized.showWorkingHoursOnly = parsed.showWorkingHoursOnly;\r\n\t\t}\r\n\r\n\t\tif (typeof parsed.showWeekends === 'boolean') {\r\n\t\t\tsanitized.showWeekends = parsed.showWeekends;\r\n\t\t}\r\n\r\n\t\tif (typeof parsed.firstDayOfWeek === 'number') {\r\n\t\t\tsanitized.firstDayOfWeek = parsed.firstDayOfWeek;\r\n\t\t}\r\n\r\n\t\treturn sanitized;\r\n\t} catch {\r\n\t\tconsole.warn('[InnoCalendar] Failed to load preferences from localStorage');\r\n\t\treturn {};\r\n\t}\r\n}\r\n\r\n/**\r\n * Save preferences to localStorage\r\n */\r\nfunction saveToStorage(key: string, preferences: TPartialPreferences): void {\r\n\tif (typeof window === 'undefined') return;\r\n\r\n\ttry {\r\n\t\tlocalStorage.setItem(key, JSON.stringify(preferences));\r\n\t} catch {\r\n\t\tconsole.warn('[InnoCalendar] Failed to save preferences to localStorage');\r\n\t}\r\n}\r\n\r\n// ============================================================================\r\n// HOOK\r\n// ============================================================================\r\n\r\n/**\r\n * Calendar preferences hook with localStorage persistence\r\n *\r\n * @param config - Optional configuration for preferences behavior\r\n * @returns Preferences state and control functions\r\n */\r\nexport function useCalendarPreferences(config: IPreferencesConfig = {}): IUsePreferencesReturn {\r\n\tconst {\r\n\t\tmodes = {},\r\n\t\tlocked = {},\r\n\t\tdefaults = {},\r\n\t\tstorageKey = PREFERENCES_STORAGE_KEY,\r\n\t\tdisableStorage = false,\r\n\t} = config;\r\n\r\n\t// Compute effective defaults (system + custom)\r\n\tconst effectiveDefaults = useMemo<IPreferences>(\r\n\t\t() => ({\r\n\t\t\t...SYSTEM_DEFAULTS,\r\n\t\t\t...defaults,\r\n\t\t}),\r\n\t\t[defaults],\r\n\t);\r\n\r\n\t// Initialize state with stored + defaults\r\n\tconst [storedPreferences, setStoredPreferences] = useState<TPartialPreferences>(() => {\r\n\t\tif (disableStorage) return {};\r\n\t\treturn loadFromStorage(storageKey);\r\n\t});\r\n\r\n\t// Session-only preferences (not persisted)\r\n\tconst [sessionPreferences, setSessionPreferences] = useState<TPartialPreferences>({});\r\n\r\n\t// Save to localStorage when stored preferences change\r\n\tuseEffect(() => {\r\n\t\tif (disableStorage) return;\r\n\t\tsaveToStorage(storageKey, storedPreferences);\r\n\t}, [storedPreferences, storageKey, disableStorage]);\r\n\r\n\t// Get mode for a preference\r\n\tconst getMode = useCallback(\r\n\t\t(key: TPreferenceKey): TPreferenceMode => {\r\n\t\t\treturn modes[key] ?? 'user';\r\n\t\t},\r\n\t\t[modes],\r\n\t);\r\n\r\n\t// Check if preference is locked\r\n\tconst isLocked = useCallback(\r\n\t\t(key: TPreferenceKey): boolean => {\r\n\t\t\treturn getMode(key) === 'locked';\r\n\t\t},\r\n\t\t[getMode],\r\n\t);\r\n\r\n\t// Check if preference is persisted\r\n\tconst isPersisted = useCallback(\r\n\t\t(key: TPreferenceKey): boolean => {\r\n\t\t\tconst mode = getMode(key);\r\n\t\t\treturn mode === 'user' && !disableStorage;\r\n\t\t},\r\n\t\t[getMode, disableStorage],\r\n\t);\r\n\r\n\t// Compute final preferences (locked > session > stored > defaults)\r\n\tconst preferences = useMemo<IPreferences>(() => {\r\n\t\tconst result = { ...effectiveDefaults };\r\n\r\n\t\t// Apply stored preferences (for 'user' mode)\r\n\t\tfor (const key of Object.keys(result) as TPreferenceKey[]) {\r\n\t\t\tconst mode = getMode(key);\r\n\r\n\t\t\tif (mode === 'locked' && key in locked) {\r\n\t\t\t\t// Use locked value\r\n\t\t\t\t(result as Record<string, unknown>)[key] = locked[key];\r\n\t\t\t} else if (mode === 'session' && key in sessionPreferences) {\r\n\t\t\t\t// Use session value\r\n\t\t\t\t(result as Record<string, unknown>)[key] = sessionPreferences[key];\r\n\t\t\t} else if (mode === 'user' && key in storedPreferences) {\r\n\t\t\t\t// Use stored value\r\n\t\t\t\t(result as Record<string, unknown>)[key] = storedPreferences[key];\r\n\t\t\t}\r\n\t\t\t// Otherwise, keep default\r\n\t\t}\r\n\r\n\t\treturn result;\r\n\t}, [effectiveDefaults, storedPreferences, sessionPreferences, locked, getMode]);\r\n\r\n\t// Set a single preference\r\n\tconst setPreference = useCallback(\r\n\t\t<K extends TPreferenceKey>(key: K, value: IPreferences[K]) => {\r\n\t\t\tconst mode = getMode(key);\r\n\r\n\t\t\t// Can't modify locked preferences\r\n\t\t\tif (mode === 'locked') {\r\n\t\t\t\tconsole.warn(`[InnoCalendar] Preference \"${key}\" is locked and cannot be modified`);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (mode === 'session') {\r\n\t\t\t\tsetSessionPreferences((prev) => ({ ...prev, [key]: value }));\r\n\t\t\t} else {\r\n\t\t\t\tsetStoredPreferences((prev) => ({ ...prev, [key]: value }));\r\n\t\t\t}\r\n\t\t},\r\n\t\t[getMode],\r\n\t);\r\n\r\n\t// Set multiple preferences at once\r\n\tconst setPreferences = useCallback(\r\n\t\t(updates: TPartialPreferences) => {\r\n\t\t\tconst sessionUpdates: TPartialPreferences = {};\r\n\t\t\tconst storedUpdates: TPartialPreferences = {};\r\n\r\n\t\t\tfor (const key of Object.keys(updates) as TPreferenceKey[]) {\r\n\t\t\t\tconst mode = getMode(key);\r\n\t\t\t\tconst value = updates[key];\r\n\r\n\t\t\t\tif (value === undefined) continue;\r\n\r\n\t\t\t\tif (mode === 'locked') {\r\n\t\t\t\t\tconsole.warn(`[InnoCalendar] Preference \"${key}\" is locked and cannot be modified`);\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (mode === 'session') {\r\n\t\t\t\t\t(sessionUpdates as Record<string, unknown>)[key] = value;\r\n\t\t\t\t} else {\r\n\t\t\t\t\t(storedUpdates as Record<string, unknown>)[key] = value;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (Object.keys(sessionUpdates).length > 0) {\r\n\t\t\t\tsetSessionPreferences((prev) => ({ ...prev, ...sessionUpdates }));\r\n\t\t\t}\r\n\r\n\t\t\tif (Object.keys(storedUpdates).length > 0) {\r\n\t\t\t\tsetStoredPreferences((prev) => ({ ...prev, ...storedUpdates }));\r\n\t\t\t}\r\n\t\t},\r\n\t\t[getMode],\r\n\t);\r\n\r\n\t// Reset all preferences to defaults\r\n\tconst resetPreferences = useCallback(() => {\r\n\t\tsetStoredPreferences({});\r\n\t\tsetSessionPreferences({});\r\n\r\n\t\tif (!disableStorage) {\r\n\t\t\tlocalStorage.removeItem(storageKey);\r\n\t\t}\r\n\t}, [storageKey, disableStorage]);\r\n\r\n\t// Reset a single preference to default\r\n\tconst resetPreference = useCallback(\r\n\t\t(key: TPreferenceKey) => {\r\n\t\t\tconst mode = getMode(key);\r\n\r\n\t\t\tif (mode === 'locked') {\r\n\t\t\t\tconsole.warn(`[InnoCalendar] Preference \"${key}\" is locked and cannot be reset`);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (mode === 'session') {\r\n\t\t\t\tsetSessionPreferences((prev) => {\r\n\t\t\t\t\tconst { [key]: _, ...rest } = prev;\r\n\t\t\t\t\treturn rest;\r\n\t\t\t\t});\r\n\t\t\t} else {\r\n\t\t\t\tsetStoredPreferences((prev) => {\r\n\t\t\t\t\tconst { [key]: _, ...rest } = prev;\r\n\t\t\t\t\treturn rest;\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t\t[getMode],\r\n\t);\r\n\r\n\treturn {\r\n\t\tpreferences,\r\n\t\tsetPreference,\r\n\t\tsetPreferences,\r\n\t\tresetPreferences,\r\n\t\tresetPreference,\r\n\t\tisLocked,\r\n\t\tisPersisted,\r\n\t\tgetMode,\r\n\t};\r\n}\r\n\r\nexport default useCalendarPreferences;\r\n","/**\r\n * InnoCalendar Provider\r\n *\r\n * A CalendarProvider that matches agenda-v2's API exactly.\r\n * This is an all-in-one provider that manages state internally\r\n * rather than requiring consumers to use useCalendar separately.\r\n *\r\n * Features:\r\n * - Automatic preference persistence to localStorage\r\n * - Developer-controlled preference locking\r\n * - Same prop interface as agenda-v2's CalendarProvider\r\n * - Same context shape for component compatibility\r\n */\r\n\r\nimport {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useState,\r\n type Dispatch,\r\n type ReactNode,\r\n type SetStateAction,\r\n} from 'react';\r\nimport {\r\n useCalendarPreferences,\r\n type IPreferencesConfig,\r\n type TPreferenceKey,\r\n} from '../preferences';\r\nimport type {\r\n CalendarEvent,\r\n ICalendarUser,\r\n IScheduleType,\r\n TBadgeVariant,\r\n TCalendarView,\r\n TSlotDuration,\r\n TWorkingHours,\r\n} from '../types';\r\n\r\n// ============================================================================\r\n// TYPES\r\n// ============================================================================\r\n\r\n// Re-export types from core/types for convenience\r\nexport type { TSlotDuration, TWorkingHours, IWorkingHoursDay } from '../types';\r\n\r\n/**\r\n * Visible hours configuration\r\n * Using start/end to match agenda-v2 naming\r\n */\r\nexport interface TVisibleHours {\r\n start: number;\r\n end: number;\r\n}\r\n\r\n// ============================================================================\r\n// CONTEXT INTERFACE - Matches agenda-v2 exactly\r\n// ============================================================================\r\n\r\nexport interface IInnoCalendarContext<TEventData = Record<string, unknown>> {\r\n // View & Navigation\r\n view: TCalendarView;\r\n setView: (view: TCalendarView) => void;\r\n selectedDate: Date;\r\n /** Set selected date. Pass optional forView to use that view for date range calculation. */\r\n setSelectedDate: (date: Date, forView?: TCalendarView) => void;\r\n\r\n // User/Participant Filtering\r\n selectedUserId: string | 'all';\r\n setSelectedUserId: (userId: string | 'all') => void;\r\n\r\n // Visual Customization\r\n badgeVariant: TBadgeVariant;\r\n setBadgeVariant: (variant: TBadgeVariant) => void;\r\n\r\n // Time Configuration\r\n workingHours: TWorkingHours;\r\n setWorkingHours: Dispatch<SetStateAction<TWorkingHours>>;\r\n visibleHours: TVisibleHours;\r\n setVisibleHours: Dispatch<SetStateAction<TVisibleHours>>;\r\n showWorkingHoursOnly: boolean;\r\n setShowWorkingHoursOnly: (show: boolean) => void;\r\n slotDuration: TSlotDuration;\r\n setSlotDuration: (duration: TSlotDuration) => void;\r\n\r\n // Preferences\r\n /**\r\n * Check if a specific preference is locked by the developer.\r\n * Useful for conditionally disabling UI controls.\r\n */\r\n isPreferenceLocked: (key: TPreferenceKey) => boolean;\r\n\r\n // Data\r\n events: CalendarEvent<TEventData>[];\r\n setEvents: Dispatch<SetStateAction<CalendarEvent<TEventData>[]>>;\r\n users: ICalendarUser[];\r\n scheduleTypes: IScheduleType[];\r\n\r\n // Filter state (schedule types)\r\n selectedScheduleTypeIds: number[];\r\n setSelectedScheduleTypeIds: Dispatch<SetStateAction<number[]>>;\r\n\r\n // Search\r\n searchQuery: string;\r\n setSearchQuery: (query: string) => void;\r\n\r\n // Computed / Filtered Events\r\n filteredEvents: CalendarEvent<TEventData>[];\r\n}\r\n\r\n// ============================================================================\r\n// CONTEXT\r\n// ============================================================================\r\n\r\n// biome-ignore lint/suspicious/noExplicitAny: Context needs flexibility for different event types\r\nconst InnoCalendarContext = createContext<IInnoCalendarContext<any> | undefined>(undefined);\r\n\r\n// ============================================================================\r\n// DEFAULT WORKING HOURS\r\n// ============================================================================\r\n\r\nconst DEFAULT_WORKING_HOURS: TWorkingHours = {\r\n 0: { enabled: false, from: 8, to: 17 }, // Sunday\r\n 1: { enabled: true, from: 8, to: 17 }, // Monday\r\n 2: { enabled: true, from: 8, to: 17 }, // Tuesday\r\n 3: { enabled: true, from: 8, to: 17 }, // Wednesday\r\n 4: { enabled: true, from: 8, to: 17 }, // Thursday\r\n 5: { enabled: true, from: 8, to: 17 }, // Friday\r\n 6: { enabled: true, from: 8, to: 12 }, // Saturday\r\n};\r\n\r\nconst DEFAULT_VISIBLE_HOURS: TVisibleHours = { start: 0, end: 24 };\r\n\r\n// ============================================================================\r\n// PROVIDER PROPS - Matches agenda-v2 exactly\r\n// ============================================================================\r\n\r\nexport interface InnoCalendarProviderProps<TEventData = Record<string, unknown>> {\r\n children: ReactNode;\r\n\r\n // Initial data from server/loader\r\n initialEvents?: CalendarEvent<TEventData>[];\r\n initialUsers?: ICalendarUser[];\r\n initialScheduleTypes?: IScheduleType[];\r\n\r\n // Initial filter state (from URL)\r\n initialView?: TCalendarView;\r\n initialDate?: Date;\r\n initialSelectedUserId?: string | 'all';\r\n initialScheduleTypeIds?: number[];\r\n initialParticipantIds?: string[];\r\n initialWorkingHoursView?: 'default' | 'enabled' | 'disabled';\r\n initialSearchQuery?: string;\r\n\r\n /**\r\n * Preferences configuration for developer control\r\n */\r\n preferencesConfig?: IPreferencesConfig;\r\n\r\n // Callbacks for parent sync\r\n onDateChange?: (date: Date, view: TCalendarView) => void;\r\n onViewChange?: (view: TCalendarView) => void;\r\n}\r\n\r\n// ============================================================================\r\n// PROVIDER COMPONENT\r\n// ============================================================================\r\n\r\nexport function InnoCalendarProvider<TEventData = Record<string, unknown>>({\r\n children,\r\n initialEvents = [],\r\n initialUsers = [],\r\n initialScheduleTypes = [],\r\n initialView,\r\n initialDate,\r\n initialSelectedUserId = 'all',\r\n initialScheduleTypeIds = [],\r\n initialParticipantIds = [],\r\n initialWorkingHoursView = 'default',\r\n initialSearchQuery = '',\r\n preferencesConfig,\r\n onDateChange,\r\n onViewChange,\r\n}: InnoCalendarProviderProps<TEventData>) {\r\n // ========================================================================\r\n // PREFERENCES (persisted to localStorage)\r\n // ========================================================================\r\n const { preferences, setPreference, isLocked } =\r\n useCalendarPreferences(preferencesConfig);\r\n\r\n // ========================================================================\r\n // VIEW & NAVIGATION\r\n // ========================================================================\r\n const [view, setViewInternal] = useState<TCalendarView>(\r\n initialView ?? (preferences.view as TCalendarView) ?? 'week',\r\n );\r\n const [selectedDate, setSelectedDateInternal] = useState<Date>(\r\n initialDate ?? new Date(),\r\n );\r\n\r\n // User Filtering\r\n const [selectedUserId, setSelectedUserId] = useState<string | 'all'>(\r\n initialSelectedUserId,\r\n );\r\n\r\n // ========================================================================\r\n // PREFERENCE-BACKED STATE\r\n // ========================================================================\r\n const badgeVariant = (preferences.badgeVariant as TBadgeVariant) ?? 'colored';\r\n const setBadgeVariant = useCallback(\r\n (variant: TBadgeVariant) => {\r\n if (!isLocked('badgeVariant')) {\r\n setPreference('badgeVariant', variant);\r\n }\r\n },\r\n [setPreference, isLocked],\r\n );\r\n\r\n const workingHours = (preferences.workingHours as TWorkingHours) ?? DEFAULT_WORKING_HOURS;\r\n const setWorkingHours: Dispatch<SetStateAction<TWorkingHours>> = useCallback(\r\n (action) => {\r\n if (!isLocked('workingHours')) {\r\n const current = (preferences.workingHours as TWorkingHours) ?? DEFAULT_WORKING_HOURS;\r\n const newValue = typeof action === 'function' ? action(current) : action;\r\n setPreference('workingHours', newValue);\r\n }\r\n },\r\n [setPreference, isLocked, preferences.workingHours],\r\n );\r\n\r\n // Convert preferences format (from/to) to our format (start/end)\r\n const prefVisibleHours = preferences.visibleHours as { from?: number; to?: number; start?: number; end?: number } | undefined;\r\n const visibleHours: TVisibleHours = useMemo(() => {\r\n if (!prefVisibleHours) return DEFAULT_VISIBLE_HOURS;\r\n // Handle both formats\r\n return {\r\n start: prefVisibleHours.start ?? prefVisibleHours.from ?? 0,\r\n end: prefVisibleHours.end ?? prefVisibleHours.to ?? 24,\r\n };\r\n }, [prefVisibleHours]);\r\n\r\n const setVisibleHours: Dispatch<SetStateAction<TVisibleHours>> = useCallback(\r\n (action) => {\r\n if (!isLocked('visibleHours')) {\r\n const newValue = typeof action === 'function' ? action(visibleHours) : action;\r\n // Store in preferences format (from/to)\r\n setPreference('visibleHours', { from: newValue.start, to: newValue.end });\r\n }\r\n },\r\n [setPreference, isLocked, visibleHours],\r\n );\r\n\r\n // showWorkingHoursOnly can be overridden by URL param\r\n const [showWorkingHoursOnlyState, setShowWorkingHoursOnlyState] = useState(\r\n initialWorkingHoursView === 'enabled'\r\n ? true\r\n : initialWorkingHoursView === 'disabled'\r\n ? false\r\n : (preferences.showWorkingHoursOnly as boolean) ?? false,\r\n );\r\n const showWorkingHoursOnly = showWorkingHoursOnlyState;\r\n const setShowWorkingHoursOnly = useCallback(\r\n (show: boolean) => {\r\n setShowWorkingHoursOnlyState(show);\r\n if (!isLocked('showWorkingHoursOnly')) {\r\n setPreference('showWorkingHoursOnly', show);\r\n }\r\n },\r\n [setPreference, isLocked],\r\n );\r\n\r\n const slotDuration = (preferences.slotDuration as TSlotDuration) ?? 30;\r\n const setSlotDuration = useCallback(\r\n (duration: TSlotDuration) => {\r\n if (!isLocked('slotDuration')) {\r\n setPreference('slotDuration', duration);\r\n }\r\n },\r\n [setPreference, isLocked],\r\n );\r\n\r\n // ========================================================================\r\n // DATA\r\n // ========================================================================\r\n const [events, setEvents] = useState<CalendarEvent<TEventData>[]>(initialEvents);\r\n\r\n // Sync events when initialEvents changes (e.g., after navigation/refetch)\r\n useEffect(() => {\r\n setEvents(initialEvents);\r\n }, [initialEvents]);\r\n\r\n // Filter State\r\n const [selectedScheduleTypeIds, setSelectedScheduleTypeIds] = useState<number[]>(\r\n initialScheduleTypeIds,\r\n );\r\n const [selectedParticipantIds, _setSelectedParticipantIds] = useState<string[]>(\r\n initialParticipantIds,\r\n );\r\n\r\n // Search\r\n const [searchQuery, setSearchQuery] = useState(initialSearchQuery);\r\n\r\n // ========================================================================\r\n // VIEW & DATE SETTERS\r\n // ========================================================================\r\n const setView = useCallback(\r\n (newView: TCalendarView) => {\r\n setViewInternal(newView);\r\n if (!isLocked('view')) {\r\n setPreference('view', newView);\r\n }\r\n onViewChange?.(newView);\r\n },\r\n [onViewChange, setPreference, isLocked],\r\n );\r\n\r\n const setSelectedDate = useCallback(\r\n (newDate: Date, forView?: TCalendarView) => {\r\n setSelectedDateInternal(newDate);\r\n onDateChange?.(newDate, forView ?? view);\r\n },\r\n [onDateChange, view],\r\n );\r\n\r\n // ========================================================================\r\n // FILTERED EVENTS\r\n // ========================================================================\r\n const filteredEvents = useMemo(() => {\r\n let result = events;\r\n\r\n // Filter by schedule type\r\n if (selectedScheduleTypeIds.length > 0) {\r\n result = result.filter(\r\n (event) =>\r\n event.scheduleTypeId !== undefined &&\r\n selectedScheduleTypeIds.includes(event.scheduleTypeId),\r\n );\r\n }\r\n\r\n // Filter by participant\r\n if (selectedParticipantIds.length > 0) {\r\n result = result.filter((event) => {\r\n // Check participants array (includes primary user in this model)\r\n if (event.participants?.length) {\r\n return event.participants.some((p) =>\r\n selectedParticipantIds.includes(p.id),\r\n );\r\n }\r\n return false;\r\n });\r\n }\r\n\r\n // Filter by selected user (single user view)\r\n if (selectedUserId !== 'all') {\r\n result = result.filter((event) =>\r\n event.participants?.some((p) => p.id === selectedUserId),\r\n );\r\n }\r\n\r\n // Filter by search query\r\n if (searchQuery.trim()) {\r\n const query = searchQuery.toLowerCase();\r\n result = result.filter(\r\n (event) =>\r\n event.title.toLowerCase().includes(query) ||\r\n event.description?.toLowerCase().includes(query) ||\r\n event.scheduleTypeName?.toLowerCase().includes(query) ||\r\n event.participants?.some((p) => p.name.toLowerCase().includes(query)),\r\n );\r\n }\r\n\r\n return result;\r\n }, [\r\n events,\r\n selectedScheduleTypeIds,\r\n selectedParticipantIds,\r\n selectedUserId,\r\n searchQuery,\r\n ]);\r\n\r\n // ========================================================================\r\n // CONTEXT VALUE\r\n // ========================================================================\r\n const value = useMemo<IInnoCalendarContext<TEventData>>(\r\n () => ({\r\n // View & Navigation\r\n view,\r\n setView,\r\n selectedDate,\r\n setSelectedDate,\r\n\r\n // User Filtering\r\n selectedUserId,\r\n setSelectedUserId,\r\n\r\n // Visual Customization\r\n badgeVariant,\r\n setBadgeVariant,\r\n\r\n // Time Configuration\r\n workingHours,\r\n setWorkingHours,\r\n visibleHours,\r\n setVisibleHours,\r\n showWorkingHoursOnly,\r\n setShowWorkingHoursOnly,\r\n slotDuration,\r\n setSlotDuration,\r\n\r\n // Preferences\r\n isPreferenceLocked: isLocked,\r\n\r\n // Data\r\n events,\r\n setEvents,\r\n users: initialUsers,\r\n scheduleTypes: initialScheduleTypes,\r\n\r\n // Filters\r\n selectedScheduleTypeIds,\r\n setSelectedScheduleTypeIds,\r\n\r\n // Search\r\n searchQuery,\r\n setSearchQuery,\r\n\r\n // Computed\r\n filteredEvents,\r\n }),\r\n [\r\n view,\r\n setView,\r\n selectedDate,\r\n setSelectedDate,\r\n selectedUserId,\r\n badgeVariant,\r\n setBadgeVariant,\r\n workingHours,\r\n setWorkingHours,\r\n visibleHours,\r\n setVisibleHours,\r\n showWorkingHoursOnly,\r\n setShowWorkingHoursOnly,\r\n slotDuration,\r\n setSlotDuration,\r\n isLocked,\r\n events,\r\n initialUsers,\r\n initialScheduleTypes,\r\n selectedScheduleTypeIds,\r\n searchQuery,\r\n filteredEvents,\r\n ],\r\n );\r\n\r\n return (\r\n <InnoCalendarContext.Provider value={value}>\r\n {children}\r\n </InnoCalendarContext.Provider>\r\n );\r\n}\r\n\r\n// ============================================================================\r\n// HOOKS\r\n// ============================================================================\r\n\r\n/**\r\n * Get the full calendar context\r\n * This is the primary hook - use this in most components\r\n */\r\nexport function useInnoCalendar<\r\n TEventData = Record<string, unknown>,\r\n>(): IInnoCalendarContext<TEventData> {\r\n const context = useContext(InnoCalendarContext);\r\n if (!context) {\r\n throw new Error(\r\n 'useInnoCalendar must be used within an InnoCalendarProvider',\r\n );\r\n }\r\n return context as IInnoCalendarContext<TEventData>;\r\n}\r\n\r\n/**\r\n * Optional calendar context hook\r\n */\r\nexport function useOptionalInnoCalendar<\r\n TEventData = Record<string, unknown>,\r\n>(): IInnoCalendarContext<TEventData> | undefined {\r\n return useContext(InnoCalendarContext) as\r\n | IInnoCalendarContext<TEventData>\r\n | undefined;\r\n}\r\n\r\n// ============================================================================\r\n// SELECTIVE HOOKS (for performance optimization)\r\n// ============================================================================\r\n\r\n/**\r\n * Access only view-related state\r\n */\r\nexport function useInnoCalendarView() {\r\n const { view, setView, selectedDate, setSelectedDate, slotDuration } =\r\n useInnoCalendar();\r\n return { view, setView, selectedDate, setSelectedDate, slotDuration };\r\n}\r\n\r\n/**\r\n * Access only events data\r\n */\r\nexport function useInnoCalendarEvents<TEventData = Record<string, unknown>>() {\r\n const { events, setEvents, filteredEvents } = useInnoCalendar<TEventData>();\r\n return { events, setEvents, filteredEvents };\r\n}\r\n\r\n/**\r\n * Access only filter state\r\n */\r\nexport function useInnoCalendarFilters() {\r\n const {\r\n selectedScheduleTypeIds,\r\n setSelectedScheduleTypeIds,\r\n selectedUserId,\r\n setSelectedUserId,\r\n searchQuery,\r\n setSearchQuery,\r\n } = useInnoCalendar();\r\n return {\r\n selectedScheduleTypeIds,\r\n setSelectedScheduleTypeIds,\r\n selectedUserId,\r\n setSelectedUserId,\r\n searchQuery,\r\n setSearchQuery,\r\n };\r\n}\r\n\r\n/**\r\n * Access only time configuration\r\n */\r\nexport function useInnoCalendarTimeConfig() {\r\n const {\r\n workingHours,\r\n setWorkingHours,\r\n visibleHours,\r\n setVisibleHours,\r\n showWorkingHoursOnly,\r\n setShowWorkingHoursOnly,\r\n } = useInnoCalendar();\r\n return {\r\n workingHours,\r\n setWorkingHours,\r\n visibleHours,\r\n setVisibleHours,\r\n showWorkingHoursOnly,\r\n setShowWorkingHoursOnly,\r\n };\r\n}\r\n"],"names":["useCalendar","options","events","resources","scheduleTypes","initialView","initialDate","initialFilters","userPreferences","lockedPreferences","locale","onViewChange","onDateChange","onEventClick","onSlotSelect","onFiltersChange","view","setViewState","useState","currentDate","setCurrentDateState","filters","setFiltersState","preferences","setPreferencesState","DEFAULT_PREFERENCES","dateRange","useMemo","getViewDateRange","viewTitle","getViewTitle","filteredEvents","result","filterEventsByDateRange","scheduleTypeIds","filterEventsByScheduleType","resourceIds","filterEventsByResource","search","filterEventsBySearch","filterOutCanceled","sortEventsByStart","setView","useCallback","newView","setCurrentDate","date","goToNext","newDate","navigateNext","goToPrev","navigatePrev","goToToday","navigateToday","goToDate","setFilters","newFilters","updateFilters","updates","prev","next","clearFilters","emptyFilters","setPreferences","prefs","handleEventClick","event","handleSlotSelect","selection","CalendarContext","createContext","CalendarProvider","children","value","jsx","useCalendarContext","context","useContext","useOptionalCalendarContext","useCalendarView","useCalendarDate","useCalendarEvents","useCalendarFilters","useCalendarPreferences","PREFERENCES_STORAGE_KEY","DEFAULT_VISIBLE_HOURS","DEFAULT_WORKING_HOURS","DEFAULT_SLOT_DURATION","SYSTEM_DEFAULTS","loadFromStorage","key","stored","parsed","sanitized","saveToStorage","config","modes","locked","defaults","storageKey","disableStorage","effectiveDefaults","storedPreferences","setStoredPreferences","sessionPreferences","setSessionPreferences","useEffect","getMode","isLocked","isPersisted","mode","setPreference","sessionUpdates","storedUpdates","resetPreferences","resetPreference","_","rest","InnoCalendarContext","InnoCalendarProvider","initialEvents","initialUsers","initialScheduleTypes","initialSelectedUserId","initialScheduleTypeIds","initialParticipantIds","initialWorkingHoursView","initialSearchQuery","preferencesConfig","setViewInternal","selectedDate","setSelectedDateInternal","selectedUserId","setSelectedUserId","badgeVariant","setBadgeVariant","variant","workingHours","setWorkingHours","action","current","newValue","prefVisibleHours","visibleHours","setVisibleHours","showWorkingHoursOnlyState","setShowWorkingHoursOnlyState","showWorkingHoursOnly","setShowWorkingHoursOnly","show","slotDuration","setSlotDuration","duration","setEvents","selectedScheduleTypeIds","setSelectedScheduleTypeIds","selectedParticipantIds","_setSelectedParticipantIds","searchQuery","setSearchQuery","setSelectedDate","forView","query","p","useInnoCalendar","useOptionalInnoCalendar","useInnoCalendarView","useInnoCalendarEvents","useInnoCalendarFilters","useInnoCalendarTimeConfig"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { useState as h, useMemo as P, useCallback as l, useContext as M, createContext as oe, useEffect as re } from "react";
2
- import { c as ue, af as de, ag as fe, O as ge, Q as we, P as ye, R as ve, T as Se, aN as be, aE as pe, aF as ke, aG as he } from "./slot-selection-context-CZjfJAcp.js";
2
+ import { c as ue, af as de, ag as fe, O as ge, Q as we, P as ye, R as ve, T as Se, aN as be, aE as pe, aF as ke, aG as he } from "./slot-selection-context-CMaE5Bc5.js";
3
3
  import { jsx as ae } from "react/jsx-runtime";
4
4
  function Le(s) {
5
5
  const {
@@ -553,4 +553,4 @@ export {
553
553
  $e as p,
554
554
  Te as u
555
555
  };
556
- //# sourceMappingURL=inno-calendar-provider-Cy72EfJy.js.map
556
+ //# sourceMappingURL=inno-calendar-provider-CbnwQSuI.js.map