@innosolutions/inno-calendar 1.0.48 → 1.0.49
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.
- package/dist/agenda-widget-B-AVTnqM.cjs +2 -0
- package/dist/agenda-widget-B-AVTnqM.cjs.map +1 -0
- package/dist/{agenda-widget-DzXBzBfm.js → agenda-widget-DhCPt2vI.js} +941 -929
- package/dist/agenda-widget-DhCPt2vI.js.map +1 -0
- package/dist/components/event/event-card.d.ts.map +1 -1
- package/dist/components/index.cjs +1 -1
- package/dist/components/index.mjs +2 -2
- package/dist/components/inno-calendar.d.ts +11 -0
- package/dist/components/inno-calendar.d.ts.map +1 -1
- package/dist/core/context/inno-calendar-provider.d.ts +15 -1
- package/dist/core/context/inno-calendar-provider.d.ts.map +1 -1
- package/dist/core/index.cjs +1 -1
- package/dist/core/index.mjs +43 -43
- package/dist/core/types.d.ts +12 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +62 -62
- package/dist/presets/index.cjs +1 -1
- package/dist/presets/index.mjs +1 -1
- package/dist/slot-selection-context-BCsC7WT7.cjs +2 -0
- package/dist/slot-selection-context-BCsC7WT7.cjs.map +1 -0
- package/dist/slot-selection-context-D1495hEJ.js +595 -0
- package/dist/slot-selection-context-D1495hEJ.js.map +1 -0
- package/dist/{tailwind-calendar-Ba5BO9tj.js → tailwind-calendar-BmJa4HhQ.js} +2 -2
- package/dist/{tailwind-calendar-Ba5BO9tj.js.map → tailwind-calendar-BmJa4HhQ.js.map} +1 -1
- package/dist/{tailwind-calendar-4FkVdxbr.cjs → tailwind-calendar-CJmOutn1.cjs} +2 -2
- package/dist/{tailwind-calendar-4FkVdxbr.cjs.map → tailwind-calendar-CJmOutn1.cjs.map} +1 -1
- package/dist/use-calendar-BEuelmSu.cjs +2 -0
- package/dist/use-calendar-BEuelmSu.cjs.map +1 -0
- package/dist/use-calendar-Clo9DFK4.js +175 -0
- package/dist/use-calendar-Clo9DFK4.js.map +1 -0
- package/dist/{use-slot-selection-BJHlyfxL.js → use-slot-selection-BCZKnZSM.js} +2 -2
- package/dist/{use-slot-selection-BJHlyfxL.js.map → use-slot-selection-BCZKnZSM.js.map} +1 -1
- package/dist/{use-slot-selection-CTFC2-xS.cjs → use-slot-selection-Bwqwjiaq.cjs} +2 -2
- package/dist/{use-slot-selection-CTFC2-xS.cjs.map → use-slot-selection-Bwqwjiaq.cjs.map} +1 -1
- package/dist/week-view-D19YRBQC.cjs +11 -0
- package/dist/week-view-D19YRBQC.cjs.map +1 -0
- package/dist/{week-view-CVbu7Qh2.js → week-view-aRPB2cjn.js} +934 -916
- package/dist/week-view-aRPB2cjn.js.map +1 -0
- package/package.json +1 -1
- package/dist/agenda-widget-D_DbVHjB.cjs +0 -2
- package/dist/agenda-widget-D_DbVHjB.cjs.map +0 -1
- package/dist/agenda-widget-DzXBzBfm.js.map +0 -1
- package/dist/slot-selection-context-Bx3FKJfR.cjs +0 -2
- package/dist/slot-selection-context-Bx3FKJfR.cjs.map +0 -1
- package/dist/slot-selection-context-D2eu2o-7.js +0 -203
- package/dist/slot-selection-context-D2eu2o-7.js.map +0 -1
- package/dist/use-calendar-DR2emWYC.js +0 -555
- package/dist/use-calendar-DR2emWYC.js.map +0 -1
- package/dist/use-calendar-DR89bZu5.cjs +0 -2
- package/dist/use-calendar-DR89bZu5.cjs.map +0 -1
- package/dist/week-view-7r6Vhahg.cjs +0 -11
- package/dist/week-view-7r6Vhahg.cjs.map +0 -1
- package/dist/week-view-CVbu7Qh2.js.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { A as t, a as s, B as n, C as r, b as o, D as i, E as l, I as E, I as d, S as u, c as g, T as C, U as D, V as S, W as v, Y as T } from "./agenda-widget-
|
|
2
|
-
import { A as
|
|
3
|
-
import { CALENDAR_VIEWS as K, DEFAULT_BUSINESS_HOURS as j, DEFAULT_HEADER_HEIGHT as X, DEFAULT_HOUR_HEIGHT as q, DEFAULT_PREFERENCES as z, DEFAULT_RESOURCE_WIDTH as J, DEFAULT_SLOT_HEIGHT as Q, DEFAULT_VIEW_CONFIGS as Z, DEFAULT_VISIBLE_HOURS as $, EVENT_COLORS as ee, EVENT_COLOR_CLASSES as ae, HEX_TO_EVENT_COLOR as te, HOURS_IN_DAY as se, MINUTES_IN_HOUR as ne, MIN_EVENT_HEIGHT as re, MS_PER_DAY as oe, MS_PER_HOUR as ie, MS_PER_MINUTE as le, addDays as Ee, addHours as de, addMinutes as ue, addMonths as ge, addWeeks as Ce, addYears as De, applyEventFilters as Se, calculateEventPosition as ve, calculateOverlappingPositions as Te, calculateSelectionOverlay as Ie, detectAllDayEvent as
|
|
4
|
-
import { C as $a,
|
|
5
|
-
import { D as
|
|
6
|
-
import { D as
|
|
1
|
+
import { A as t, a as s, B as n, C as r, b as o, D as i, E as l, I as E, I as d, S as u, c as g, T as C, U as D, V as S, W as v, Y as T } from "./agenda-widget-DhCPt2vI.js";
|
|
2
|
+
import { A as f, B as O, C as _, D as p, a as y, b as c, c as R, E as m, d as H, M as A, e as F, f as U, P, g as M, h as N, i as V, T as W, j as B, k as h, l as L, m as k, n as b, W as w, o as x, p as Y } from "./week-view-aRPB2cjn.js";
|
|
3
|
+
import { CALENDAR_VIEWS as K, DEFAULT_BUSINESS_HOURS as j, DEFAULT_HEADER_HEIGHT as X, DEFAULT_HOUR_HEIGHT as q, DEFAULT_PREFERENCES as z, DEFAULT_RESOURCE_WIDTH as J, DEFAULT_SLOT_HEIGHT as Q, DEFAULT_VIEW_CONFIGS as Z, DEFAULT_VISIBLE_HOURS as $, EVENT_COLORS as ee, EVENT_COLOR_CLASSES as ae, HEX_TO_EVENT_COLOR as te, HOURS_IN_DAY as se, MINUTES_IN_HOUR as ne, MIN_EVENT_HEIGHT as re, MS_PER_DAY as oe, MS_PER_HOUR as ie, MS_PER_MINUTE as le, addDays as Ee, addHours as de, addMinutes as ue, addMonths as ge, addWeeks as Ce, addYears as De, applyEventFilters as Se, calculateEventPosition as ve, calculateOverlappingPositions as Te, calculateSelectionOverlay as Ie, detectAllDayEvent as fe, differenceInDays as Oe, differenceInHours as _e, differenceInMilliseconds as pe, differenceInMinutes as ye, eachDayOfInterval as ce, eachHourOfInterval as Re, endOfDay as me, endOfMonth as He, endOfWeek as Ae, endOfYear as Fe, eventsOverlap as Ue, filterEventsByDateRange as Pe, filterEventsByResource as Me, filterEventsByScheduleType as Ne, filterEventsBySearch as Ve, filterOutCanceled as We, formatDateISO as Be, formatEventTimeDisplay as he, formatHourLabel as Le, formatTime as ke, generateHourLabels as be, generateMonthCells as we, generateMonthGrid as xe, generateTimeSlots as Ye, generateWeekCells as Ge, generateYearCells as Ke, getAllDayEvents as je, getDayOfWeek as Xe, getDaysInMonth as qe, getDecimalHours as ze, getEventColor as Je, getEventDurationMinutes as Qe, getEventsCountInView as Ze, getEventsForDay as $e, getEventsInRange as ea, getMonthNames as aa, getMultiDayEvents as ta, getOverlappingGroups as sa, getRangeText as na, getTimedEvents as ra, getViewDateRange as oa, getViewTitle as ia, getVisibleHoursArray as la, getWeekDays as Ea, getWeekNumber as da, getWeekdayHeaders as ua, getWeekdayNames as ga, getWorkingHoursForDay as Ca, getYearMonths as Da, groupEventsByDate as Sa, groupEventsByResource as va, groupEventsByScheduleType as Ta, isAfter as Ia, isBefore as fa, isBetween as Oa, isMultiDayEvent as _a, isSameDay as pa, isSameMonth as ya, isSameWeek as ca, isSameYear as Ra, isToday as ma, isWeekend as Ha, isWorkingHour as Aa, maxDate as Fa, minDate as Ua, navigateNext as Pa, navigatePrev as Ma, navigateToday as Na, parseISO as Va, resolveEventColor as Wa, separateEventsByDuration as Ba, setTime as ha, shouldShowEventTime as La, sortEventsByDuration as ka, sortEventsByEnd as ba, sortEventsByStart as wa, startOfDay as xa, startOfMonth as Ya, startOfWeek as Ga, startOfYear as Ka, subDays as ja, subMonths as Xa, subWeeks as qa, subYears as za, timeToY as Ja, yToTime as Qa } from "./utils.mjs";
|
|
4
|
+
import { C as $a, u as et, a as at, b as tt, c as st, d as nt, a as rt, e as ot, f as it, g as lt, g as Et } from "./use-calendar-Clo9DFK4.js";
|
|
5
|
+
import { D as ut, T as gt } from "./tailwind-calendar-BmJa4HhQ.js";
|
|
6
|
+
import { D as Dt, I as St, I as vt, a as Tt, b as It, c as ft, P as Ot, S as _t, u as pt, d as yt, e as ct, f as Rt, g as mt, h as Ht, i as At, e as Ft, f as Ut, g as Pt, h as Mt, i as Nt, j as Vt, k as Wt, k as Bt, l as ht, m as Lt } from "./slot-selection-context-D1495hEJ.js";
|
|
7
7
|
import { c as bt } from "./index-DtaLkIY8.js";
|
|
8
|
-
import { u as xt, a as Yt, b as Gt } from "./use-slot-selection-
|
|
8
|
+
import { u as xt, a as Yt, b as Gt } from "./use-slot-selection-BCZKnZSM.js";
|
|
9
9
|
export {
|
|
10
10
|
t as AgendaDropdown,
|
|
11
|
-
|
|
11
|
+
f as AgendaView,
|
|
12
12
|
s as AgendaWidget,
|
|
13
13
|
n as BadgeVariantSetting,
|
|
14
14
|
O as Button,
|
|
@@ -26,23 +26,23 @@ export {
|
|
|
26
26
|
Z as DEFAULT_VIEW_CONFIGS,
|
|
27
27
|
$ as DEFAULT_VISIBLE_HOURS,
|
|
28
28
|
i as DEFAULT_WEEK_WORKING_HOURS,
|
|
29
|
-
|
|
29
|
+
p as DateNavigator,
|
|
30
30
|
y as DayEventsExpansion,
|
|
31
31
|
c as DaySlot,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
R as DayView,
|
|
33
|
+
ut as DefaultCalendar,
|
|
34
|
+
Dt as DragDropProvider,
|
|
35
35
|
ee as EVENT_COLORS,
|
|
36
36
|
ae as EVENT_COLOR_CLASSES,
|
|
37
|
-
|
|
37
|
+
m as EventBlock,
|
|
38
38
|
H as EventCard,
|
|
39
39
|
l as EventPopover,
|
|
40
40
|
te as HEX_TO_EVENT_COLOR,
|
|
41
41
|
se as HOURS_IN_DAY,
|
|
42
42
|
E as InnoCalendar,
|
|
43
|
-
|
|
43
|
+
St as InnoCalendarProvider,
|
|
44
44
|
d as IntegratedCalendar,
|
|
45
|
-
|
|
45
|
+
vt as IntegratedCalendarProvider,
|
|
46
46
|
ne as MINUTES_IN_HOUR,
|
|
47
47
|
re as MIN_EVENT_HEIGHT,
|
|
48
48
|
oe as MS_PER_DAY,
|
|
@@ -51,23 +51,23 @@ export {
|
|
|
51
51
|
A as MonthView,
|
|
52
52
|
F as MultiDayBanner,
|
|
53
53
|
U as MultiDayEventBar,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
Tt as PREFERENCES_DEFAULT_SLOT_DURATION,
|
|
55
|
+
It as PREFERENCES_DEFAULT_VISIBLE_HOURS,
|
|
56
|
+
ft as PREFERENCES_DEFAULT_WORKING_HOURS,
|
|
57
|
+
Ot as PREFERENCES_STORAGE_KEY,
|
|
58
58
|
P as Popover,
|
|
59
59
|
M as PopoverAnchor,
|
|
60
60
|
N as PopoverContent,
|
|
61
61
|
V as PopoverTrigger,
|
|
62
62
|
u as ScheduleTypeFilter,
|
|
63
63
|
g as SlotDurationSetting,
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
_t as SlotSelectionProvider,
|
|
65
|
+
gt as TailwindCalendar,
|
|
66
66
|
W as TimeSlot,
|
|
67
67
|
C as TimelineView,
|
|
68
68
|
B as TodayButton,
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
h as Tooltip,
|
|
70
|
+
L as TooltipContent,
|
|
71
71
|
k as TooltipProvider,
|
|
72
72
|
b as TooltipTrigger,
|
|
73
73
|
D as UserFilter,
|
|
@@ -87,14 +87,14 @@ export {
|
|
|
87
87
|
Te as calculateOverlappingPositions,
|
|
88
88
|
Ie as calculateSelectionOverlay,
|
|
89
89
|
bt as cn,
|
|
90
|
-
|
|
90
|
+
fe as detectAllDayEvent,
|
|
91
91
|
Oe as differenceInDays,
|
|
92
92
|
_e as differenceInHours,
|
|
93
|
-
|
|
93
|
+
pe as differenceInMilliseconds,
|
|
94
94
|
ye as differenceInMinutes,
|
|
95
95
|
ce as eachDayOfInterval,
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
Re as eachHourOfInterval,
|
|
97
|
+
me as endOfDay,
|
|
98
98
|
He as endOfMonth,
|
|
99
99
|
Ae as endOfWeek,
|
|
100
100
|
Fe as endOfYear,
|
|
@@ -105,8 +105,8 @@ export {
|
|
|
105
105
|
Ve as filterEventsBySearch,
|
|
106
106
|
We as filterOutCanceled,
|
|
107
107
|
Be as formatDateISO,
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
he as formatEventTimeDisplay,
|
|
109
|
+
Le as formatHourLabel,
|
|
110
110
|
ke as formatTime,
|
|
111
111
|
be as generateHourLabels,
|
|
112
112
|
we as generateMonthCells,
|
|
@@ -142,14 +142,14 @@ export {
|
|
|
142
142
|
va as groupEventsByResource,
|
|
143
143
|
Ta as groupEventsByScheduleType,
|
|
144
144
|
Ia as isAfter,
|
|
145
|
-
|
|
145
|
+
fa as isBefore,
|
|
146
146
|
Oa as isBetween,
|
|
147
147
|
_a as isMultiDayEvent,
|
|
148
|
-
|
|
148
|
+
pa as isSameDay,
|
|
149
149
|
ya as isSameMonth,
|
|
150
150
|
ca as isSameWeek,
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
Ra as isSameYear,
|
|
152
|
+
ma as isToday,
|
|
153
153
|
Ha as isWeekend,
|
|
154
154
|
Aa as isWorkingHour,
|
|
155
155
|
Fa as maxDate,
|
|
@@ -160,8 +160,8 @@ export {
|
|
|
160
160
|
Va as parseISO,
|
|
161
161
|
Wa as resolveEventColor,
|
|
162
162
|
Ba as separateEventsByDuration,
|
|
163
|
-
|
|
164
|
-
|
|
163
|
+
ha as setTime,
|
|
164
|
+
La as shouldShowEventTime,
|
|
165
165
|
ka as sortEventsByDuration,
|
|
166
166
|
ba as sortEventsByEnd,
|
|
167
167
|
wa as sortEventsByStart,
|
|
@@ -174,36 +174,36 @@ export {
|
|
|
174
174
|
qa as subWeeks,
|
|
175
175
|
za as subYears,
|
|
176
176
|
Ja as timeToY,
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
177
|
+
pt as useAdvancedPreferences,
|
|
178
|
+
et as useCalendar,
|
|
179
|
+
at as useCalendarContext,
|
|
180
|
+
tt as useCalendarDate,
|
|
181
|
+
st as useCalendarEvents,
|
|
182
|
+
nt as useCalendarFilters,
|
|
183
|
+
rt as useCalendarFromContext,
|
|
184
|
+
ot as useCalendarPreferences,
|
|
185
185
|
xt as useCalendarTimeConfig,
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
186
|
+
it as useCalendarView,
|
|
187
|
+
yt as useDragDrop,
|
|
188
|
+
ct as useInnoCalendar,
|
|
189
|
+
Rt as useInnoCalendarEvents,
|
|
190
|
+
mt as useInnoCalendarFilters,
|
|
191
|
+
Ht as useInnoCalendarTimeConfig,
|
|
192
|
+
At as useInnoCalendarView,
|
|
193
|
+
Ft as useIntegratedCalendar,
|
|
194
|
+
Ut as useIntegratedCalendarEvents,
|
|
195
|
+
Pt as useIntegratedCalendarFilters,
|
|
196
|
+
Mt as useIntegratedCalendarTimeConfig,
|
|
197
|
+
Nt as useIntegratedCalendarView,
|
|
198
|
+
lt as useOptionalCalendar,
|
|
199
|
+
Et as useOptionalCalendarContext,
|
|
200
|
+
Vt as useOptionalDragDrop,
|
|
201
|
+
Wt as useOptionalInnoCalendar,
|
|
202
|
+
Bt as useOptionalIntegratedCalendar,
|
|
203
|
+
ht as useOptionalSlotSelection,
|
|
204
204
|
Yt as usePreferences,
|
|
205
205
|
Gt as useSlotSelection,
|
|
206
|
-
|
|
206
|
+
Lt as useSlotSelectionContext,
|
|
207
207
|
Qa as yToTime
|
|
208
208
|
};
|
|
209
209
|
//# sourceMappingURL=index.mjs.map
|
package/dist/presets/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("../tailwind-calendar-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("../tailwind-calendar-CJmOutn1.cjs");exports.DefaultCalendar=a.DefaultCalendar;exports.TailwindCalendar=a.TailwindCalendar;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/presets/index.mjs
CHANGED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const V=require("react/jsx-runtime"),e=require("react"),F=e.createContext(void 0);function De({children:s,onEventDrop:n}){const[t,o]=e.useState(null),d=e.useCallback(r=>{const g=typeof r.startDate=="string"?new Date(r.startDate):r.startDate,b=typeof r.endDate=="string"?new Date(r.endDate):r.endDate;o({event:r,originalStartDate:g,originalEndDate:b})},[]),u=e.useCallback((r,g,b)=>{o(l=>l?{...l,previewDate:r,previewHour:g,previewMinute:b}:null)},[]),f=e.useCallback(()=>{if(!t)return null;const{event:r,originalStartDate:g,originalEndDate:b,previewDate:l,previewHour:H,previewMinute:I}=t,h=b.getTime()-g.getTime();let C;l?(C=new Date(l),typeof H=="number"?C.setHours(H,I??0,0,0):C.setHours(g.getHours(),g.getMinutes(),g.getSeconds(),0)):C=g;const c=new Date(C.getTime()+h),D={event:r,newStartDate:C,newEndDate:c};return o(null),n?.(D),D},[t,n]),i=e.useCallback(()=>{o(null)},[]);return V.jsx(F.Provider,{value:{dragState:t,isDragging:t!==null,startDrag:d,updateDragPreview:u,endDrag:f,cancelDrag:i},children:s})}function we(){const s=e.useContext(F);if(!s)throw new Error("useDragDrop must be used within a DragDropProvider");return s}function be(){return e.useContext(F)??null}const oe="inno-calendar-preferences",re={from:0,to:24},ae={0:{enabled:!1,from:8,to:18},1:{enabled:!0,from:8,to:18},2:{enabled:!0,from:8,to:18},3:{enabled:!0,from:8,to:18},4:{enabled:!0,from:8,to:18},5:{enabled:!0,from:8,to:18},6:{enabled:!1,from:8,to:18}},le=30,ke={view:"month",badgeVariant:"colored",slotDuration:le,visibleHours:re,workingHours:ae,showWorkingHoursOnly:!1,showWeekends:!0,firstDayOfWeek:1};function Ce(s){if(typeof window>"u")return{};try{const n=localStorage.getItem(s);if(!n)return{};const t=JSON.parse(n),o={};return t.view&&typeof t.view=="string"&&(o.view=t.view),t.badgeVariant&&typeof t.badgeVariant=="string"&&(o.badgeVariant=t.badgeVariant),t.slotDuration&&typeof t.slotDuration=="number"&&(o.slotDuration=t.slotDuration),t.visibleHours&&typeof t.visibleHours=="object"&&(o.visibleHours=t.visibleHours),t.workingHours&&typeof t.workingHours=="object"&&(o.workingHours=t.workingHours),typeof t.showWorkingHoursOnly=="boolean"&&(o.showWorkingHoursOnly=t.showWorkingHoursOnly),typeof t.showWeekends=="boolean"&&(o.showWeekends=t.showWeekends),typeof t.firstDayOfWeek=="number"&&(o.firstDayOfWeek=t.firstDayOfWeek),o}catch{return console.warn("[InnoCalendar] Failed to load preferences from localStorage"),{}}}function me(s,n){if(!(typeof window>"u"))try{localStorage.setItem(s,JSON.stringify(n))}catch{console.warn("[InnoCalendar] Failed to save preferences to localStorage")}}function ue(s={}){const{modes:n={},locked:t={},defaults:o={},storageKey:d=oe,disableStorage:u=!1}=s,f=e.useMemo(()=>({...ke,...o}),[o]),[i,r]=e.useState(()=>u?{}:Ce(d)),[g,b]=e.useState({});e.useEffect(()=>{u||me(d,i)},[i,d,u]);const l=e.useCallback(S=>n[S]??"user",[n]),H=e.useCallback(S=>l(S)==="locked",[l]),I=e.useCallback(S=>l(S)==="user"&&!u,[l,u]),h=e.useMemo(()=>{const S={...f};for(const w of Object.keys(S)){const p=l(w);p==="locked"&&w in t?S[w]=t[w]:p==="session"&&w in g?S[w]=g[w]:p==="user"&&w in i&&(S[w]=i[w])}return S},[f,i,g,t,l]),C=e.useCallback((S,w)=>{const p=l(S);if(p==="locked"){console.warn(`[InnoCalendar] Preference "${S}" is locked and cannot be modified`);return}p==="session"?b(k=>({...k,[S]:w})):r(k=>({...k,[S]:w}))},[l]),c=e.useCallback(S=>{const w={},p={};for(const k of Object.keys(S)){const O=l(k),E=S[k];if(E!==void 0){if(O==="locked"){console.warn(`[InnoCalendar] Preference "${k}" is locked and cannot be modified`);continue}O==="session"?w[k]=E:p[k]=E}}Object.keys(w).length>0&&b(k=>({...k,...w})),Object.keys(p).length>0&&r(k=>({...k,...p}))},[l]),D=e.useCallback(()=>{r({}),b({}),u||localStorage.removeItem(d)},[d,u]),v=e.useCallback(S=>{const w=l(S);if(w==="locked"){console.warn(`[InnoCalendar] Preference "${S}" is locked and cannot be reset`);return}w==="session"?b(p=>{const{[S]:k,...O}=p;return O}):r(p=>{const{[S]:k,...O}=p;return O})},[l]);return{preferences:h,setPreference:C,setPreferences:c,resetPreferences:D,resetPreference:v,isLocked:H,isPersisted:I,getMode:l}}const M=e.createContext(void 0),ne={0:{enabled:!1,from:8,to:17},1:{enabled:!0,from:8,to:17},2:{enabled:!0,from:8,to:17},3:{enabled:!0,from:8,to:17},4:{enabled:!0,from:8,to:17},5:{enabled:!0,from:8,to:17},6:{enabled:!0,from:8,to:12}},pe={start:0,end:24};function He({children:s,initialEvents:n=[],initialUsers:t=[],initialScheduleTypes:o=[],initialView:d,initialDate:u,initialSelectedUserId:f="all",initialScheduleTypeIds:i=[],initialParticipantIds:r=[],initialWorkingHoursView:g="default",initialSearchQuery:b="",preferencesConfig:l,initialFocusEventId:H=null,onDateChange:I,onViewChange:h}){const{preferences:C,setPreference:c,isLocked:D}=ue(l),[v,S]=e.useState(d??C.view??"week"),[w,p]=e.useState(u??new Date),[k,O]=e.useState(f),E=C.badgeVariant??"colored",N=e.useCallback(a=>{D("badgeVariant")||c("badgeVariant",a)},[c,D]),j=C.workingHours??ne,K=e.useCallback(a=>{if(!D("workingHours")){const m=C.workingHours??ne,y=typeof a=="function"?a(m):a;c("workingHours",y)}},[c,D,C.workingHours]),T=C.visibleHours,R=e.useMemo(()=>T?{start:T.start??T.from??0,end:T.end??T.to??24}:pe,[T]),G=e.useCallback(a=>{if(!D("visibleHours")){const m=typeof a=="function"?a(R):a;c("visibleHours",{from:m.start,to:m.end})}},[c,D,R]),[ie,ce]=e.useState(g==="enabled"?!0:g==="disabled"?!1:C.showWorkingHoursOnly??!1),Y=ie,$=e.useCallback(a=>{ce(a),D("showWorkingHoursOnly")||c("showWorkingHoursOnly",a)},[c,D]),z=C.slotDuration??30,B=e.useCallback(a=>{D("slotDuration")||c("slotDuration",a)},[c,D]),[L,Q]=e.useState(n);e.useEffect(()=>{Q(n)},[n]);const[P,de]=e.useState(i),[U,Re]=e.useState(r),[W,fe]=e.useState(b),[q,J]=e.useState(H??null);e.useEffect(()=>{H&&J(H)},[H]);const X=e.useCallback(()=>J(null),[]),Z=e.useCallback(a=>{S(a),D("view")||c("view",a),h?.(a)},[h,c,D]),ee=e.useCallback((a,m)=>{p(a),I?.(a,m??v)},[I,v]),te=e.useMemo(()=>{let a=L;if(P.length>0&&(a=a.filter(m=>m.scheduleTypeId!==void 0&&P.includes(m.scheduleTypeId))),U.length>0&&(a=a.filter(m=>m.participants?.length?m.participants.some(y=>U.includes(y.id)):!1)),k!=="all"&&(a=a.filter(m=>m.participants?.some(y=>y.id===k))),W.trim()){const m=W.toLowerCase();a=a.filter(y=>y.title.toLowerCase().includes(m)||y.description?.toLowerCase().includes(m)||y.scheduleTypeName?.toLowerCase().includes(m)||y.participants?.some(Se=>Se.name.toLowerCase().includes(m)))}return a},[L,P,U,k,W]),ge=e.useMemo(()=>({view:v,setView:Z,selectedDate:w,setSelectedDate:ee,selectedUserId:k,setSelectedUserId:O,badgeVariant:E,setBadgeVariant:N,workingHours:j,setWorkingHours:K,visibleHours:R,setVisibleHours:G,showWorkingHoursOnly:Y,setShowWorkingHoursOnly:$,slotDuration:z,setSlotDuration:B,isPreferenceLocked:D,events:L,setEvents:Q,users:t,scheduleTypes:o,selectedScheduleTypeIds:P,setSelectedScheduleTypeIds:de,searchQuery:W,setSearchQuery:fe,filteredEvents:te,focusEventId:q,clearFocusEventId:X}),[v,Z,w,ee,k,E,N,j,K,R,G,Y,$,z,B,D,L,t,o,P,W,te,q,X]);return V.jsx(M.Provider,{value:ge,children:s})}function _(){const s=e.useContext(M);if(!s)throw new Error("useInnoCalendar must be used within an InnoCalendarProvider");return s}function ye(){return e.useContext(M)}function Ie(){const{view:s,setView:n,selectedDate:t,setSelectedDate:o,slotDuration:d}=_();return{view:s,setView:n,selectedDate:t,setSelectedDate:o,slotDuration:d}}function he(){const{events:s,setEvents:n,filteredEvents:t}=_();return{events:s,setEvents:n,filteredEvents:t}}function Oe(){const{selectedScheduleTypeIds:s,setSelectedScheduleTypeIds:n,selectedUserId:t,setSelectedUserId:o,searchQuery:d,setSearchQuery:u}=_();return{selectedScheduleTypeIds:s,setSelectedScheduleTypeIds:n,selectedUserId:t,setSelectedUserId:o,searchQuery:d,setSearchQuery:u}}function ve(){const{workingHours:s,setWorkingHours:n,visibleHours:t,setVisibleHours:o,showWorkingHoursOnly:d,setShowWorkingHoursOnly:u}=_();return{workingHours:s,setWorkingHours:n,visibleHours:t,setVisibleHours:o,showWorkingHoursOnly:d,setShowWorkingHoursOnly:u}}const A=e.createContext(void 0);function x(s){const n=new Date(s.date);return typeof s.hour=="number"&&n.setHours(s.hour,s.minute??0,0,0),n}function Ee(s){const n=new Date(s),t=n.getMinutes(),o=Math.floor(t/30)*30;return n.setMinutes(o,0,0),n}function Te(s,n){return s.getFullYear()===n.getFullYear()&&s.getMonth()===n.getMonth()&&s.getDate()===n.getDate()}function se(s,n,t,o,d=30){const u=x(s),f=x(n);let i=u,r=f;if(f<u&&(i=f,r=u),t==="day")if(Te(i,r)){const b=Ee(new Date);i=new Date(i),i.setHours(b.getHours(),b.getMinutes(),0,0),r=new Date(i.getTime()+o*60*1e3)}else i.setHours(0,0,0,0),r.setHours(23,59,59,999);else{const g=d*60*1e3;r=new Date(r.getTime()+g);const b=r.getTime()-i.getTime(),l=o*60*1e3;b<l&&(r=new Date(i.getTime()+l))}return{startDate:i,endDate:r}}function Pe(s,n,t,o){const d=x(s),u=x(n),f=x(t),i=u<=f?u:f,r=u<=f?f:u;if(o==="day"){const g=new Date(d);g.setHours(0,0,0,0);const b=new Date(i);b.setHours(0,0,0,0);const l=new Date(r);return l.setHours(0,0,0,0),g>=b&&g<=l}return d>=i&&d<=r}function We({children:s,mode:n="time",onSelect:t,minDurationMinutes:o=30,slotDurationMinutes:d=30,enabled:u=!0}){const[f,i]=e.useState(null),r=e.useRef(!1),g=e.useCallback(c=>{u&&(r.current=!0,i({start:c,end:c,isSelecting:!0}))},[u]),b=e.useCallback(c=>{u&&r.current&&i(D=>D?{...D,end:c}:null)},[u]),l=e.useCallback(()=>{r.current&&(r.current=!1,i(c=>{if(!c)return null;const D=se(c.start,c.end,n,o,d);return t?.(D),{...c,isSelecting:!1}}),setTimeout(()=>{i(null)},100))},[n,o,d,t]),H=e.useCallback(()=>{r.current=!1,i(null)},[]),I=e.useCallback(c=>f?Pe(c,f.start,f.end,n):!1,[f,n]),h=e.useCallback(()=>f?se(f.start,f.end,n,o,d):null,[f,n,o,d]),C=e.useMemo(()=>({isSelecting:f?.isSelecting??!1,startSelection:g,updateSelection:b,endSelection:l,cancelSelection:H,isSlotSelected:I,getSelectionResult:h,mode:n}),[f?.isSelecting,g,b,l,H,I,h,n]);return V.jsx(A.Provider,{value:C,children:s})}function xe(){const s=e.useContext(A);if(!s)throw new Error("useSlotSelectionContext must be used within a SlotSelectionProvider");return s}function _e(){return e.useContext(A)}exports.DEFAULT_SLOT_DURATION=le;exports.DEFAULT_VISIBLE_HOURS=re;exports.DEFAULT_WORKING_HOURS=ae;exports.DragDropProvider=De;exports.InnoCalendarProvider=He;exports.PREFERENCES_STORAGE_KEY=oe;exports.SlotSelectionProvider=We;exports.useCalendarPreferences=ue;exports.useDragDrop=we;exports.useInnoCalendar=_;exports.useInnoCalendarEvents=he;exports.useInnoCalendarFilters=Oe;exports.useInnoCalendarTimeConfig=ve;exports.useInnoCalendarView=Ie;exports.useOptionalDragDrop=be;exports.useOptionalInnoCalendar=ye;exports.useOptionalSlotSelection=_e;exports.useSlotSelectionContext=xe;
|
|
2
|
+
//# sourceMappingURL=slot-selection-context-BCsC7WT7.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slot-selection-context-BCsC7WT7.cjs","sources":["../src/core/context/drag-drop-context.tsx","../src/core/preferences/types.ts","../src/core/preferences/use-preferences.ts","../src/core/context/inno-calendar-provider.tsx","../src/core/context/slot-selection-context.tsx"],"sourcesContent":["/**\n * DragDropContext - Drag & Drop State Management for Calendar Events\n *\n * Provides drag & drop state management for calendar events.\n * Enables dragging events between time slots and days.\n *\n * Features:\n * - Generic event type support via CalendarEvent<TData>\n * - Preview position tracking during drag\n * - Duration preservation when dropping\n * - Optional provider pattern (components can work without drag-drop)\n */\n\nimport { createContext, type ReactNode, useCallback, useContext, useState } from 'react';\nimport type { CalendarEvent } from '../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\nexport interface IDragState<TData = Record<string, unknown>> {\n\t/** The event being dragged */\n\tevent: CalendarEvent<TData>;\n\t/** Original start date of the event */\n\toriginalStartDate: Date;\n\t/** Original end date of the event */\n\toriginalEndDate: Date;\n\t/** Current preview position (during drag) */\n\tpreviewDate?: Date | undefined;\n\t/** Current preview hour (for time-based views) */\n\tpreviewHour?: number | undefined;\n\t/** Current preview minute */\n\tpreviewMinute?: number | undefined;\n}\n\nexport interface IDropResult<TData = Record<string, unknown>> {\n\t/** The event that was dropped */\n\tevent: CalendarEvent<TData>;\n\t/** New start date after drop */\n\tnewStartDate: Date;\n\t/** New end date after drop (maintains original duration) */\n\tnewEndDate: Date;\n}\n\nexport interface IDragDropContext<TData = Record<string, unknown>> {\n\t/** Current drag state, null when not dragging */\n\tdragState: IDragState<TData> | null;\n\t/** Whether a drag operation is in progress */\n\tisDragging: boolean;\n\t/** Start dragging an event */\n\t// biome-ignore lint/suspicious/noExplicitAny: Accept any event type for flexibility\n\tstartDrag: (event: CalendarEvent<any>) => void;\n\t/** Update drag preview position */\n\tupdateDragPreview: (date: Date, hour?: number, minute?: number) => void;\n\t/** End drag operation and return drop result */\n\tendDrag: () => IDropResult<TData> | null;\n\t/** Cancel drag operation */\n\tcancelDrag: () => void;\n}\n\n// ============================================================================\n// CONTEXT\n// ============================================================================\n\n// biome-ignore lint/suspicious/noExplicitAny: Context needs to be flexible for different event types\nconst DragDropContext = createContext<IDragDropContext<any> | undefined>(undefined);\n\n// ============================================================================\n// PROVIDER PROPS\n// ============================================================================\n\nexport interface DragDropProviderProps<TData = Record<string, unknown>> {\n\tchildren: ReactNode;\n\t/** Callback when an event is dropped at a new location */\n\tonEventDrop?: (result: IDropResult<TData>) => void;\n}\n\n// ============================================================================\n// PROVIDER\n// ============================================================================\n\nexport function DragDropProvider<TData = Record<string, unknown>>({\n\tchildren,\n\tonEventDrop,\n}: DragDropProviderProps<TData>) {\n\tconst [dragState, setDragState] = useState<IDragState<TData> | null>(null);\n\n\t// biome-ignore lint/suspicious/noExplicitAny: Accept any event type for flexibility\n\tconst startDrag = useCallback((event: CalendarEvent<any>) => {\n\t\tconst startDate =\n\t\t\ttypeof event.startDate === 'string' ? new Date(event.startDate) : event.startDate;\n\t\tconst endDate = typeof event.endDate === 'string' ? new Date(event.endDate) : event.endDate;\n\n\t\tsetDragState({\n\t\t\tevent: event as CalendarEvent<TData>,\n\t\t\toriginalStartDate: startDate,\n\t\t\toriginalEndDate: endDate,\n\t\t});\n\t}, []);\n\n\tconst updateDragPreview = useCallback((date: Date, hour?: number, minute?: number) => {\n\t\tsetDragState((prev) => {\n\t\t\tif (!prev) return null;\n\t\t\treturn {\n\t\t\t\t...prev,\n\t\t\t\tpreviewDate: date,\n\t\t\t\tpreviewHour: hour,\n\t\t\t\tpreviewMinute: minute,\n\t\t\t};\n\t\t});\n\t}, []);\n\n\tconst endDrag = useCallback(() => {\n\t\tif (!dragState) return null;\n\n\t\tconst { event, originalStartDate, originalEndDate, previewDate, previewHour, previewMinute } =\n\t\t\tdragState;\n\n\t\t// Calculate duration of original event\n\t\tconst durationMs = originalEndDate.getTime() - originalStartDate.getTime();\n\n\t\t// Calculate new start date\n\t\tlet newStartDate: Date;\n\n\t\tif (previewDate) {\n\t\t\tnewStartDate = new Date(previewDate);\n\n\t\t\tif (typeof previewHour === 'number') {\n\t\t\t\t// Time-based drop (day/week view)\n\t\t\t\tnewStartDate.setHours(previewHour, previewMinute ?? 0, 0, 0);\n\t\t\t} else {\n\t\t\t\t// Day-based drop (month view) - keep original time\n\t\t\t\tnewStartDate.setHours(\n\t\t\t\t\toriginalStartDate.getHours(),\n\t\t\t\t\toriginalStartDate.getMinutes(),\n\t\t\t\t\toriginalStartDate.getSeconds(),\n\t\t\t\t\t0\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// No preview, return to original position\n\t\t\tnewStartDate = originalStartDate;\n\t\t}\n\n\t\t// Calculate new end date maintaining duration\n\t\tconst newEndDate = new Date(newStartDate.getTime() + durationMs);\n\n\t\tconst result: IDropResult<TData> = {\n\t\t\tevent,\n\t\t\tnewStartDate,\n\t\t\tnewEndDate,\n\t\t};\n\n\t\t// Clear drag state\n\t\tsetDragState(null);\n\n\t\t// Notify parent\n\t\tonEventDrop?.(result);\n\n\t\treturn result;\n\t}, [dragState, onEventDrop]);\n\n\tconst cancelDrag = useCallback(() => {\n\t\tsetDragState(null);\n\t}, []);\n\n\treturn (\n\t\t<DragDropContext.Provider\n\t\t\tvalue={{\n\t\t\t\tdragState,\n\t\t\t\tisDragging: dragState !== null,\n\t\t\t\tstartDrag,\n\t\t\t\tupdateDragPreview,\n\t\t\t\tendDrag,\n\t\t\t\tcancelDrag,\n\t\t\t}}\n\t\t>\n\t\t\t{children}\n\t\t</DragDropContext.Provider>\n\t);\n}\n\n// ============================================================================\n// HOOKS\n// ============================================================================\n\n/**\n * Access drag & drop context (required)\n *\n * @throws Error if used outside of DragDropProvider\n */\nexport function useDragDrop<TData = Record<string, unknown>>(): IDragDropContext<TData> {\n\tconst context = useContext(DragDropContext);\n\tif (!context) {\n\t\tthrow new Error('useDragDrop must be used within a DragDropProvider');\n\t}\n\treturn context as IDragDropContext<TData>;\n}\n\n/**\n * Access drag & drop context (optional)\n *\n * Use this for components that may be rendered outside of DragDropProvider.\n * Returns null when drag-drop is not available.\n */\nexport function useOptionalDragDrop<\n\tTData = Record<string, unknown>,\n>(): IDragDropContext<TData> | null {\n\tconst context = useContext(DragDropContext);\n\treturn (context as IDragDropContext<TData>) ?? null;\n}\n","/**\n * Calendar Preferences Types\n *\n * Type definitions for the calendar preferences system.\n * This module enables:\n * - Persistent user preferences via localStorage\n * - Developer-controlled defaults and overrides\n * - Locking preferences to prevent user modifications\n * - Complete customization for different deployment scenarios\n */\n\nimport type { TBadgeVariant, TCalendarView, TSlotDuration } from '../types';\n\n// ============================================================================\n// PREFERENCE KEYS\n// ============================================================================\n\n/**\n * All available preference keys\n */\nexport type TPreferenceKey =\n\t| 'view'\n\t| 'badgeVariant'\n\t| 'slotDuration'\n\t| 'visibleHours'\n\t| 'workingHours'\n\t| 'showWorkingHoursOnly'\n\t| 'showWeekends'\n\t| 'firstDayOfWeek';\n\n/**\n * Storage key for localStorage\n */\nexport const PREFERENCES_STORAGE_KEY = 'inno-calendar-preferences';\n\n// ============================================================================\n// PREFERENCE VALUE TYPES\n// ============================================================================\n\n/**\n * Visible hours configuration\n */\nexport interface IVisibleHoursConfig {\n\tfrom: number;\n\tto: number;\n}\n\n/**\n * Working hours configuration per day of week\n * Key: 0 = Sunday, 1 = Monday, ..., 6 = Saturday\n */\nexport type TWorkingHoursConfig = {\n\t[dayIndex: number]: { from: number; to: number };\n};\n\n// ============================================================================\n// PREFERENCE VALUES\n// ============================================================================\n\n/**\n * Complete preferences object structure\n */\nexport interface IPreferences {\n\t/** Default calendar view */\n\tview: TCalendarView;\n\t/** Event badge display style */\n\tbadgeVariant: TBadgeVariant;\n\t/** Time slot duration in minutes (15, 30, 60) */\n\tslotDuration: TSlotDuration;\n\t/** Visible hours range for day/week views */\n\tvisibleHours: IVisibleHoursConfig;\n\t/** Working hours configuration per day */\n\tworkingHours: TWorkingHoursConfig;\n\t/** Show only working hours in day/week views */\n\tshowWorkingHoursOnly: boolean;\n\t/** Show weekend days */\n\tshowWeekends: boolean;\n\t/** First day of week (0 = Sunday, 1 = Monday, etc.) */\n\tfirstDayOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n}\n\n/**\n * Partial preferences for updates\n */\nexport type TPartialPreferences = Partial<IPreferences>;\n\n// ============================================================================\n// PREFERENCE CONTROL\n// ============================================================================\n\n/**\n * Control mode for each preference\n * - 'user': User can modify, persisted to localStorage\n * - 'locked': Developer-controlled, cannot be modified by user\n * - 'session': User can modify during session, not persisted\n */\nexport type TPreferenceMode = 'user' | 'locked' | 'session';\n\n/**\n * Configuration for preference control\n * Allows developers to lock certain preferences to specific values\n */\nexport type TPreferenceModes = {\n\t[K in TPreferenceKey]?: TPreferenceMode;\n};\n\n/**\n * Locked values for preferences\n * When a preference mode is 'locked', this value is used\n */\nexport type TLockedPreferences = TPartialPreferences;\n\n// ============================================================================\n// PREFERENCES CONFIG\n// ============================================================================\n\n/**\n * Complete preferences configuration for developers\n *\n * @example\n * // Allow all preferences to be user-controlled (default)\n * const config: IPreferencesConfig = {};\n *\n * @example\n * // Lock slot duration to 30 minutes, let users control the rest\n * const config: IPreferencesConfig = {\n * modes: { slotDuration: 'locked' },\n * locked: { slotDuration: 30 }\n * };\n *\n * @example\n * // Completely override all preferences (no user control)\n * const config: IPreferencesConfig = {\n * modes: {\n * view: 'locked',\n * badgeVariant: 'locked',\n * slotDuration: 'locked',\n * visibleHours: 'locked',\n * workingHours: 'locked',\n * showWorkingHoursOnly: 'locked'\n * },\n * locked: {\n * view: 'week',\n * badgeVariant: 'colored',\n * slotDuration: 30,\n * visibleHours: { from: 8, to: 18 },\n * workingHours: { ... },\n * showWorkingHoursOnly: true\n * }\n * };\n */\nexport interface IPreferencesConfig {\n\t/**\n\t * Control mode for each preference\n\t * Defaults to 'user' for all preferences\n\t */\n\tmodes?: TPreferenceModes;\n\n\t/**\n\t * Values to use when preference mode is 'locked'\n\t */\n\tlocked?: TLockedPreferences;\n\n\t/**\n\t * Custom default values (used when no stored preference exists)\n\t * These override the system defaults\n\t */\n\tdefaults?: TPartialPreferences;\n\n\t/**\n\t * Custom localStorage key (default: 'inno-calendar-preferences')\n\t * Useful when multiple calendar instances need separate storage\n\t */\n\tstorageKey?: string;\n\n\t/**\n\t * Disable localStorage entirely\n\t * All preferences will reset on page reload\n\t */\n\tdisableStorage?: boolean;\n}\n\n// ============================================================================\n// HOOK RETURN TYPE\n// ============================================================================\n\n/**\n * Return type for useCalendarPreferences hook\n */\nexport interface IUsePreferencesReturn {\n\t/** Current preference values */\n\tpreferences: IPreferences;\n\n\t/** Update a single preference */\n\tsetPreference: <K extends TPreferenceKey>(key: K, value: IPreferences[K]) => void;\n\n\t/** Update multiple preferences at once */\n\tsetPreferences: (updates: TPartialPreferences) => void;\n\n\t/** Reset preferences to defaults */\n\tresetPreferences: () => void;\n\n\t/** Reset a single preference to default */\n\tresetPreference: (key: TPreferenceKey) => void;\n\n\t/** Check if a preference is locked */\n\tisLocked: (key: TPreferenceKey) => boolean;\n\n\t/** Check if a preference is persisted */\n\tisPersisted: (key: TPreferenceKey) => boolean;\n\n\t/** Get the mode for a preference */\n\tgetMode: (key: TPreferenceKey) => TPreferenceMode;\n}\n","/**\n * Calendar Preferences Hook\n *\n * Manages calendar preferences with localStorage persistence and developer control.\n *\n * Features:\n * - Automatic localStorage persistence\n * - Developer-controlled defaults and overrides\n * - Preference locking for controlled deployments\n * - Session-only preferences that don't persist\n * - Type-safe preference access and updates\n *\n * @example Basic usage\n * ```tsx\n * const { preferences, setPreference } = useCalendarPreferences();\n * setPreference('slotDuration', 30);\n * ```\n *\n * @example With developer configuration\n * ```tsx\n * const { preferences } = useCalendarPreferences({\n * modes: { slotDuration: 'locked' },\n * locked: { slotDuration: 60 },\n * defaults: { view: 'week' }\n * });\n * ```\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport type { TWorkingHours } from '../types';\nimport {\n\ttype IPreferences,\n\ttype IPreferencesConfig,\n\ttype IUsePreferencesReturn,\n\tPREFERENCES_STORAGE_KEY,\n\ttype TPartialPreferences,\n\ttype TPreferenceKey,\n\ttype TPreferenceMode,\n} from './types';\n\n// ============================================================================\n// SYSTEM DEFAULTS\n// ============================================================================\n\n/**\n * Default visible hours\n */\nexport const DEFAULT_VISIBLE_HOURS = {\n\tfrom: 0,\n\tto: 24,\n};\n\n/**\n * Default working hours (Monday-Friday, 8am-6pm)\n */\nexport const DEFAULT_WORKING_HOURS: TWorkingHours = {\n\t0: { enabled: false, from: 8, to: 18 }, // Sunday - disabled\n\t1: { enabled: true, from: 8, to: 18 }, // Monday\n\t2: { enabled: true, from: 8, to: 18 }, // Tuesday\n\t3: { enabled: true, from: 8, to: 18 }, // Wednesday\n\t4: { enabled: true, from: 8, to: 18 }, // Thursday\n\t5: { enabled: true, from: 8, to: 18 }, // Friday\n\t6: { enabled: false, from: 8, to: 18 }, // Saturday - disabled\n};\n\n/**\n * Default slot duration in minutes\n */\nexport const DEFAULT_SLOT_DURATION = 30;\n\n/**\n * System default preferences\n * These are used when no stored preference or custom default exists\n */\nconst SYSTEM_DEFAULTS: IPreferences = {\n\tview: 'month',\n\tbadgeVariant: 'colored',\n\tslotDuration: DEFAULT_SLOT_DURATION,\n\tvisibleHours: DEFAULT_VISIBLE_HOURS,\n\tworkingHours: DEFAULT_WORKING_HOURS,\n\tshowWorkingHoursOnly: false,\n\tshowWeekends: true,\n\tfirstDayOfWeek: 1,\n};\n\n// ============================================================================\n// STORAGE HELPERS\n// ============================================================================\n\n/**\n * Load preferences from localStorage\n */\nfunction loadFromStorage(key: string): TPartialPreferences {\n\tif (typeof window === 'undefined') return {};\n\n\ttry {\n\t\tconst stored = localStorage.getItem(key);\n\t\tif (!stored) return {};\n\n\t\tconst parsed = JSON.parse(stored);\n\n\t\t// Validate and sanitize stored values\n\t\tconst sanitized: TPartialPreferences = {};\n\n\t\tif (parsed.view && typeof parsed.view === 'string') {\n\t\t\tsanitized.view = parsed.view;\n\t\t}\n\n\t\tif (parsed.badgeVariant && typeof parsed.badgeVariant === 'string') {\n\t\t\tsanitized.badgeVariant = parsed.badgeVariant;\n\t\t}\n\n\t\tif (parsed.slotDuration && typeof parsed.slotDuration === 'number') {\n\t\t\tsanitized.slotDuration = parsed.slotDuration;\n\t\t}\n\n\t\tif (parsed.visibleHours && typeof parsed.visibleHours === 'object') {\n\t\t\tsanitized.visibleHours = parsed.visibleHours;\n\t\t}\n\n\t\tif (parsed.workingHours && typeof parsed.workingHours === 'object') {\n\t\t\tsanitized.workingHours = parsed.workingHours;\n\t\t}\n\n\t\tif (typeof parsed.showWorkingHoursOnly === 'boolean') {\n\t\t\tsanitized.showWorkingHoursOnly = parsed.showWorkingHoursOnly;\n\t\t}\n\n\t\tif (typeof parsed.showWeekends === 'boolean') {\n\t\t\tsanitized.showWeekends = parsed.showWeekends;\n\t\t}\n\n\t\tif (typeof parsed.firstDayOfWeek === 'number') {\n\t\t\tsanitized.firstDayOfWeek = parsed.firstDayOfWeek;\n\t\t}\n\n\t\treturn sanitized;\n\t} catch {\n\t\tconsole.warn('[InnoCalendar] Failed to load preferences from localStorage');\n\t\treturn {};\n\t}\n}\n\n/**\n * Save preferences to localStorage\n */\nfunction saveToStorage(key: string, preferences: TPartialPreferences): void {\n\tif (typeof window === 'undefined') return;\n\n\ttry {\n\t\tlocalStorage.setItem(key, JSON.stringify(preferences));\n\t} catch {\n\t\tconsole.warn('[InnoCalendar] Failed to save preferences to localStorage');\n\t}\n}\n\n// ============================================================================\n// HOOK\n// ============================================================================\n\n/**\n * Calendar preferences hook with localStorage persistence\n *\n * @param config - Optional configuration for preferences behavior\n * @returns Preferences state and control functions\n */\nexport function useCalendarPreferences(config: IPreferencesConfig = {}): IUsePreferencesReturn {\n\tconst {\n\t\tmodes = {},\n\t\tlocked = {},\n\t\tdefaults = {},\n\t\tstorageKey = PREFERENCES_STORAGE_KEY,\n\t\tdisableStorage = false,\n\t} = config;\n\n\t// Compute effective defaults (system + custom)\n\tconst effectiveDefaults = useMemo<IPreferences>(\n\t\t() => ({\n\t\t\t...SYSTEM_DEFAULTS,\n\t\t\t...defaults,\n\t\t}),\n\t\t[defaults]\n\t);\n\n\t// Initialize state with stored + defaults\n\tconst [storedPreferences, setStoredPreferences] = useState<TPartialPreferences>(() => {\n\t\tif (disableStorage) return {};\n\t\treturn loadFromStorage(storageKey);\n\t});\n\n\t// Session-only preferences (not persisted)\n\tconst [sessionPreferences, setSessionPreferences] = useState<TPartialPreferences>({});\n\n\t// Save to localStorage when stored preferences change\n\tuseEffect(() => {\n\t\tif (disableStorage) return;\n\t\tsaveToStorage(storageKey, storedPreferences);\n\t}, [storedPreferences, storageKey, disableStorage]);\n\n\t// Get mode for a preference\n\tconst getMode = useCallback(\n\t\t(key: TPreferenceKey): TPreferenceMode => {\n\t\t\treturn modes[key] ?? 'user';\n\t\t},\n\t\t[modes]\n\t);\n\n\t// Check if preference is locked\n\tconst isLocked = useCallback(\n\t\t(key: TPreferenceKey): boolean => {\n\t\t\treturn getMode(key) === 'locked';\n\t\t},\n\t\t[getMode]\n\t);\n\n\t// Check if preference is persisted\n\tconst isPersisted = useCallback(\n\t\t(key: TPreferenceKey): boolean => {\n\t\t\tconst mode = getMode(key);\n\t\t\treturn mode === 'user' && !disableStorage;\n\t\t},\n\t\t[getMode, disableStorage]\n\t);\n\n\t// Compute final preferences (locked > session > stored > defaults)\n\tconst preferences = useMemo<IPreferences>(() => {\n\t\tconst result = { ...effectiveDefaults };\n\n\t\t// Apply stored preferences (for 'user' mode)\n\t\tfor (const key of Object.keys(result) as TPreferenceKey[]) {\n\t\t\tconst mode = getMode(key);\n\n\t\t\tif (mode === 'locked' && key in locked) {\n\t\t\t\t// Use locked value\n\t\t\t\t(result as Record<string, unknown>)[key] = locked[key];\n\t\t\t} else if (mode === 'session' && key in sessionPreferences) {\n\t\t\t\t// Use session value\n\t\t\t\t(result as Record<string, unknown>)[key] = sessionPreferences[key];\n\t\t\t} else if (mode === 'user' && key in storedPreferences) {\n\t\t\t\t// Use stored value\n\t\t\t\t(result as Record<string, unknown>)[key] = storedPreferences[key];\n\t\t\t}\n\t\t\t// Otherwise, keep default\n\t\t}\n\n\t\treturn result;\n\t}, [effectiveDefaults, storedPreferences, sessionPreferences, locked, getMode]);\n\n\t// Set a single preference\n\tconst setPreference = useCallback(\n\t\t<K extends TPreferenceKey>(key: K, value: IPreferences[K]) => {\n\t\t\tconst mode = getMode(key);\n\n\t\t\t// Can't modify locked preferences\n\t\t\tif (mode === 'locked') {\n\t\t\t\tconsole.warn(`[InnoCalendar] Preference \"${key}\" is locked and cannot be modified`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (mode === 'session') {\n\t\t\t\tsetSessionPreferences((prev) => ({ ...prev, [key]: value }));\n\t\t\t} else {\n\t\t\t\tsetStoredPreferences((prev) => ({ ...prev, [key]: value }));\n\t\t\t}\n\t\t},\n\t\t[getMode]\n\t);\n\n\t// Set multiple preferences at once\n\tconst setPreferences = useCallback(\n\t\t(updates: TPartialPreferences) => {\n\t\t\tconst sessionUpdates: TPartialPreferences = {};\n\t\t\tconst storedUpdates: TPartialPreferences = {};\n\n\t\t\tfor (const key of Object.keys(updates) as TPreferenceKey[]) {\n\t\t\t\tconst mode = getMode(key);\n\t\t\t\tconst value = updates[key];\n\n\t\t\t\tif (value === undefined) continue;\n\n\t\t\t\tif (mode === 'locked') {\n\t\t\t\t\tconsole.warn(`[InnoCalendar] Preference \"${key}\" is locked and cannot be modified`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (mode === 'session') {\n\t\t\t\t\t(sessionUpdates as Record<string, unknown>)[key] = value;\n\t\t\t\t} else {\n\t\t\t\t\t(storedUpdates as Record<string, unknown>)[key] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (Object.keys(sessionUpdates).length > 0) {\n\t\t\t\tsetSessionPreferences((prev) => ({ ...prev, ...sessionUpdates }));\n\t\t\t}\n\n\t\t\tif (Object.keys(storedUpdates).length > 0) {\n\t\t\t\tsetStoredPreferences((prev) => ({ ...prev, ...storedUpdates }));\n\t\t\t}\n\t\t},\n\t\t[getMode]\n\t);\n\n\t// Reset all preferences to defaults\n\tconst resetPreferences = useCallback(() => {\n\t\tsetStoredPreferences({});\n\t\tsetSessionPreferences({});\n\n\t\tif (!disableStorage) {\n\t\t\tlocalStorage.removeItem(storageKey);\n\t\t}\n\t}, [storageKey, disableStorage]);\n\n\t// Reset a single preference to default\n\tconst resetPreference = useCallback(\n\t\t(key: TPreferenceKey) => {\n\t\t\tconst mode = getMode(key);\n\n\t\t\tif (mode === 'locked') {\n\t\t\t\tconsole.warn(`[InnoCalendar] Preference \"${key}\" is locked and cannot be reset`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (mode === 'session') {\n\t\t\t\tsetSessionPreferences((prev) => {\n\t\t\t\t\tconst { [key]: _, ...rest } = prev;\n\t\t\t\t\treturn rest;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tsetStoredPreferences((prev) => {\n\t\t\t\t\tconst { [key]: _, ...rest } = prev;\n\t\t\t\t\treturn rest;\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[getMode]\n\t);\n\n\treturn {\n\t\tpreferences,\n\t\tsetPreference,\n\t\tsetPreferences,\n\t\tresetPreferences,\n\t\tresetPreference,\n\t\tisLocked,\n\t\tisPersisted,\n\t\tgetMode,\n\t};\n}\n\nexport default useCalendarPreferences;\n","/**\n * InnoCalendar Provider\n *\n * A CalendarProvider that matches agenda-v2's API exactly.\n * This is an all-in-one provider that manages state internally\n * rather than requiring consumers to use useCalendar separately.\n *\n * Features:\n * - Automatic preference persistence to localStorage\n * - Developer-controlled preference locking\n * - Same prop interface as agenda-v2's CalendarProvider\n * - Same context shape for component compatibility\n */\n\nimport {\n createContext,\n type Dispatch,\n type ReactNode,\n type SetStateAction,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport {\n type IPreferencesConfig,\n type TPreferenceKey,\n useCalendarPreferences,\n} from \"../preferences\";\nimport type {\n CalendarEvent,\n ICalendarUser,\n IScheduleType,\n TBadgeVariant,\n TCalendarView,\n TSlotDuration,\n TWorkingHours,\n} from \"../types\";\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n// Re-export types from core/types for convenience\nexport type { IWorkingHoursDay, TSlotDuration, TWorkingHours } from \"../types\";\n\n/**\n * Visible hours configuration\n * Using start/end to match agenda-v2 naming\n */\nexport interface TVisibleHours {\n start: number;\n end: number;\n}\n\n// ============================================================================\n// CONTEXT INTERFACE - Matches agenda-v2 exactly\n// ============================================================================\n\nexport interface IInnoCalendarContext<TEventData = Record<string, unknown>> {\n // View & Navigation\n view: TCalendarView;\n setView: (view: TCalendarView) => void;\n selectedDate: Date;\n /** Set selected date. Pass optional forView to use that view for date range calculation. */\n setSelectedDate: (date: Date, forView?: TCalendarView) => void;\n\n // User/Participant Filtering\n selectedUserId: string | \"all\";\n setSelectedUserId: (userId: string | \"all\") => void;\n\n // Visual Customization\n badgeVariant: TBadgeVariant;\n setBadgeVariant: (variant: TBadgeVariant) => void;\n\n // Time Configuration\n workingHours: TWorkingHours;\n setWorkingHours: Dispatch<SetStateAction<TWorkingHours>>;\n visibleHours: TVisibleHours;\n setVisibleHours: Dispatch<SetStateAction<TVisibleHours>>;\n showWorkingHoursOnly: boolean;\n setShowWorkingHoursOnly: (show: boolean) => void;\n slotDuration: TSlotDuration;\n setSlotDuration: (duration: TSlotDuration) => void;\n\n // Preferences\n /**\n * Check if a specific preference is locked by the developer.\n * Useful for conditionally disabling UI controls.\n */\n isPreferenceLocked: (key: TPreferenceKey) => boolean;\n\n // Data\n events: CalendarEvent<TEventData>[];\n setEvents: Dispatch<SetStateAction<CalendarEvent<TEventData>[]>>;\n users: ICalendarUser[];\n scheduleTypes: IScheduleType[];\n\n // Filter state (schedule types)\n selectedScheduleTypeIds: number[];\n setSelectedScheduleTypeIds: Dispatch<SetStateAction<number[]>>;\n\n // Search\n searchQuery: string;\n setSearchQuery: (query: string) => void;\n\n // Computed / Filtered Events\n filteredEvents: CalendarEvent<TEventData>[];\n\n // Focus Event (auto-open popover for a specific event)\n /**\n * When set, the EventCard / EventBlock whose `event.id` matches this value\n * will automatically open its popover after rendering.\n * Cleared automatically after the popover opens.\n */\n focusEventId: string | null;\n /** Clear the focused event (called internally after popover opens). */\n clearFocusEventId: () => void;\n}\n\n// ============================================================================\n// CONTEXT\n// ============================================================================\n\n// biome-ignore lint/suspicious/noExplicitAny: Context needs flexibility for different event types\nconst InnoCalendarContext = createContext<\n IInnoCalendarContext<any> | undefined\n>(undefined);\n\n// ============================================================================\n// DEFAULT WORKING HOURS\n// ============================================================================\n\nconst DEFAULT_WORKING_HOURS: TWorkingHours = {\n 0: { enabled: false, from: 8, to: 17 }, // Sunday\n 1: { enabled: true, from: 8, to: 17 }, // Monday\n 2: { enabled: true, from: 8, to: 17 }, // Tuesday\n 3: { enabled: true, from: 8, to: 17 }, // Wednesday\n 4: { enabled: true, from: 8, to: 17 }, // Thursday\n 5: { enabled: true, from: 8, to: 17 }, // Friday\n 6: { enabled: true, from: 8, to: 12 }, // Saturday\n};\n\nconst DEFAULT_VISIBLE_HOURS: TVisibleHours = { start: 0, end: 24 };\n\n// ============================================================================\n// PROVIDER PROPS - Matches agenda-v2 exactly\n// ============================================================================\n\nexport interface InnoCalendarProviderProps<\n TEventData = Record<string, unknown>,\n> {\n children: ReactNode;\n\n // Initial data from server/loader\n initialEvents?: CalendarEvent<TEventData>[];\n initialUsers?: ICalendarUser[];\n initialScheduleTypes?: IScheduleType[];\n\n // Initial filter state (from URL)\n initialView?: TCalendarView;\n initialDate?: Date;\n initialSelectedUserId?: string | \"all\";\n initialScheduleTypeIds?: number[];\n initialParticipantIds?: string[];\n initialWorkingHoursView?: \"default\" | \"enabled\" | \"disabled\";\n initialSearchQuery?: string;\n\n /**\n * Preferences configuration for developer control\n */\n preferencesConfig?: IPreferencesConfig;\n\n /**\n * When set, the event with this ID will auto-open its popover after rendering.\n * Useful for deep-linking from other pages (e.g. clicking an appointment\n * in an overview card that navigates to the agenda with a specific event).\n */\n initialFocusEventId?: string | null;\n\n // Callbacks for parent sync\n onDateChange?: (date: Date, view: TCalendarView) => void;\n onViewChange?: (view: TCalendarView) => void;\n}\n\n// ============================================================================\n// PROVIDER COMPONENT\n// ============================================================================\n\nexport function InnoCalendarProvider<TEventData = Record<string, unknown>>({\n children,\n initialEvents = [],\n initialUsers = [],\n initialScheduleTypes = [],\n initialView,\n initialDate,\n initialSelectedUserId = \"all\",\n initialScheduleTypeIds = [],\n initialParticipantIds = [],\n initialWorkingHoursView = \"default\",\n initialSearchQuery = \"\",\n preferencesConfig,\n initialFocusEventId = null,\n onDateChange,\n onViewChange,\n}: InnoCalendarProviderProps<TEventData>) {\n // ========================================================================\n // PREFERENCES (persisted to localStorage)\n // ========================================================================\n const { preferences, setPreference, isLocked } =\n useCalendarPreferences(preferencesConfig);\n\n // ========================================================================\n // VIEW & NAVIGATION\n // ========================================================================\n const [view, setViewInternal] = useState<TCalendarView>(\n initialView ?? (preferences.view as TCalendarView) ?? \"week\",\n );\n const [selectedDate, setSelectedDateInternal] = useState<Date>(\n initialDate ?? new Date(),\n );\n\n // User Filtering\n const [selectedUserId, setSelectedUserId] = useState<string | \"all\">(\n initialSelectedUserId,\n );\n\n // ========================================================================\n // PREFERENCE-BACKED STATE\n // ========================================================================\n const badgeVariant = (preferences.badgeVariant as TBadgeVariant) ?? \"colored\";\n const setBadgeVariant = useCallback(\n (variant: TBadgeVariant) => {\n if (!isLocked(\"badgeVariant\")) {\n setPreference(\"badgeVariant\", variant);\n }\n },\n [setPreference, isLocked],\n );\n\n const workingHours =\n (preferences.workingHours as TWorkingHours) ?? DEFAULT_WORKING_HOURS;\n const setWorkingHours: Dispatch<SetStateAction<TWorkingHours>> = useCallback(\n (action) => {\n if (!isLocked(\"workingHours\")) {\n const current =\n (preferences.workingHours as TWorkingHours) ?? DEFAULT_WORKING_HOURS;\n const newValue =\n typeof action === \"function\" ? action(current) : action;\n setPreference(\"workingHours\", newValue);\n }\n },\n [setPreference, isLocked, preferences.workingHours],\n );\n\n // Convert preferences format (from/to) to our format (start/end)\n const prefVisibleHours = preferences.visibleHours as\n | { from?: number; to?: number; start?: number; end?: number }\n | undefined;\n const visibleHours: TVisibleHours = useMemo(() => {\n if (!prefVisibleHours) return DEFAULT_VISIBLE_HOURS;\n // Handle both formats\n return {\n start: prefVisibleHours.start ?? prefVisibleHours.from ?? 0,\n end: prefVisibleHours.end ?? prefVisibleHours.to ?? 24,\n };\n }, [prefVisibleHours]);\n\n const setVisibleHours: Dispatch<SetStateAction<TVisibleHours>> = useCallback(\n (action) => {\n if (!isLocked(\"visibleHours\")) {\n const newValue =\n typeof action === \"function\" ? action(visibleHours) : action;\n // Store in preferences format (from/to)\n setPreference(\"visibleHours\", {\n from: newValue.start,\n to: newValue.end,\n });\n }\n },\n [setPreference, isLocked, visibleHours],\n );\n\n // showWorkingHoursOnly can be overridden by URL param\n const [showWorkingHoursOnlyState, setShowWorkingHoursOnlyState] = useState(\n initialWorkingHoursView === \"enabled\"\n ? true\n : initialWorkingHoursView === \"disabled\"\n ? false\n : ((preferences.showWorkingHoursOnly as boolean) ?? false),\n );\n const showWorkingHoursOnly = showWorkingHoursOnlyState;\n const setShowWorkingHoursOnly = useCallback(\n (show: boolean) => {\n setShowWorkingHoursOnlyState(show);\n if (!isLocked(\"showWorkingHoursOnly\")) {\n setPreference(\"showWorkingHoursOnly\", show);\n }\n },\n [setPreference, isLocked],\n );\n\n const slotDuration = (preferences.slotDuration as TSlotDuration) ?? 30;\n const setSlotDuration = useCallback(\n (duration: TSlotDuration) => {\n if (!isLocked(\"slotDuration\")) {\n setPreference(\"slotDuration\", duration);\n }\n },\n [setPreference, isLocked],\n );\n\n // ========================================================================\n // DATA\n // ========================================================================\n const [events, setEvents] =\n useState<CalendarEvent<TEventData>[]>(initialEvents);\n\n // Sync events when initialEvents changes (e.g., after navigation/refetch)\n useEffect(() => {\n setEvents(initialEvents);\n }, [initialEvents]);\n\n // Filter State\n const [selectedScheduleTypeIds, setSelectedScheduleTypeIds] = useState<\n number[]\n >(initialScheduleTypeIds);\n const [selectedParticipantIds, _setSelectedParticipantIds] = useState<\n string[]\n >(initialParticipantIds);\n\n // Search\n const [searchQuery, setSearchQuery] = useState(initialSearchQuery);\n\n // Focus Event (auto-open popover for a specific event)\n const [focusEventId, setFocusEventId] = useState<string | null>(\n initialFocusEventId ?? null,\n );\n\n // Sync focusEventId when the prop changes (e.g. URL navigation)\n useEffect(() => {\n if (initialFocusEventId) {\n setFocusEventId(initialFocusEventId);\n }\n }, [initialFocusEventId]);\n\n const clearFocusEventId = useCallback(() => setFocusEventId(null), []);\n\n // ========================================================================\n // VIEW & DATE SETTERS\n // ========================================================================\n const setView = useCallback(\n (newView: TCalendarView) => {\n setViewInternal(newView);\n if (!isLocked(\"view\")) {\n setPreference(\"view\", newView);\n }\n onViewChange?.(newView);\n },\n [onViewChange, setPreference, isLocked],\n );\n\n const setSelectedDate = useCallback(\n (newDate: Date, forView?: TCalendarView) => {\n setSelectedDateInternal(newDate);\n onDateChange?.(newDate, forView ?? view);\n },\n [onDateChange, view],\n );\n\n // ========================================================================\n // FILTERED EVENTS\n // ========================================================================\n const filteredEvents = useMemo(() => {\n let result = events;\n\n // Filter by schedule type\n if (selectedScheduleTypeIds.length > 0) {\n result = result.filter(\n (event) =>\n event.scheduleTypeId !== undefined &&\n selectedScheduleTypeIds.includes(event.scheduleTypeId),\n );\n }\n\n // Filter by participant\n if (selectedParticipantIds.length > 0) {\n result = result.filter((event) => {\n // Check participants array (includes primary user in this model)\n if (event.participants?.length) {\n return event.participants.some((p) =>\n selectedParticipantIds.includes(p.id),\n );\n }\n return false;\n });\n }\n\n // Filter by selected user (single user view)\n if (selectedUserId !== \"all\") {\n result = result.filter((event) =>\n event.participants?.some((p) => p.id === selectedUserId),\n );\n }\n\n // Filter by search query\n if (searchQuery.trim()) {\n const query = searchQuery.toLowerCase();\n result = result.filter(\n (event) =>\n event.title.toLowerCase().includes(query) ||\n event.description?.toLowerCase().includes(query) ||\n event.scheduleTypeName?.toLowerCase().includes(query) ||\n event.participants?.some((p) => p.name.toLowerCase().includes(query)),\n );\n }\n\n return result;\n }, [\n events,\n selectedScheduleTypeIds,\n selectedParticipantIds,\n selectedUserId,\n searchQuery,\n ]);\n\n // ========================================================================\n // CONTEXT VALUE\n // ========================================================================\n const value = useMemo<IInnoCalendarContext<TEventData>>(\n () => ({\n // View & Navigation\n view,\n setView,\n selectedDate,\n setSelectedDate,\n\n // User Filtering\n selectedUserId,\n setSelectedUserId,\n\n // Visual Customization\n badgeVariant,\n setBadgeVariant,\n\n // Time Configuration\n workingHours,\n setWorkingHours,\n visibleHours,\n setVisibleHours,\n showWorkingHoursOnly,\n setShowWorkingHoursOnly,\n slotDuration,\n setSlotDuration,\n\n // Preferences\n isPreferenceLocked: isLocked,\n\n // Data\n events,\n setEvents,\n users: initialUsers,\n scheduleTypes: initialScheduleTypes,\n\n // Filters\n selectedScheduleTypeIds,\n setSelectedScheduleTypeIds,\n\n // Search\n searchQuery,\n setSearchQuery,\n\n // Computed\n filteredEvents,\n\n // Focus Event\n focusEventId,\n clearFocusEventId,\n }),\n [\n view,\n setView,\n selectedDate,\n setSelectedDate,\n selectedUserId,\n badgeVariant,\n setBadgeVariant,\n workingHours,\n setWorkingHours,\n visibleHours,\n setVisibleHours,\n showWorkingHoursOnly,\n setShowWorkingHoursOnly,\n slotDuration,\n setSlotDuration,\n isLocked,\n events,\n initialUsers,\n initialScheduleTypes,\n selectedScheduleTypeIds,\n searchQuery,\n filteredEvents,\n focusEventId,\n clearFocusEventId,\n ],\n );\n\n return (\n <InnoCalendarContext.Provider value={value}>\n {children}\n </InnoCalendarContext.Provider>\n );\n}\n\n// ============================================================================\n// HOOKS\n// ============================================================================\n\n/**\n * Get the full calendar context\n * This is the primary hook - use this in most components\n */\nexport function useInnoCalendar<\n TEventData = Record<string, unknown>,\n>(): IInnoCalendarContext<TEventData> {\n const context = useContext(InnoCalendarContext);\n if (!context) {\n throw new Error(\n \"useInnoCalendar must be used within an InnoCalendarProvider\",\n );\n }\n return context as IInnoCalendarContext<TEventData>;\n}\n\n/**\n * Optional calendar context hook\n */\nexport function useOptionalInnoCalendar<\n TEventData = Record<string, unknown>,\n>(): IInnoCalendarContext<TEventData> | undefined {\n return useContext(InnoCalendarContext) as\n | IInnoCalendarContext<TEventData>\n | undefined;\n}\n\n// ============================================================================\n// SELECTIVE HOOKS (for performance optimization)\n// ============================================================================\n\n/**\n * Access only view-related state\n */\nexport function useInnoCalendarView() {\n const { view, setView, selectedDate, setSelectedDate, slotDuration } =\n useInnoCalendar();\n return { view, setView, selectedDate, setSelectedDate, slotDuration };\n}\n\n/**\n * Access only events data\n */\nexport function useInnoCalendarEvents<TEventData = Record<string, unknown>>() {\n const { events, setEvents, filteredEvents } = useInnoCalendar<TEventData>();\n return { events, setEvents, filteredEvents };\n}\n\n/**\n * Access only filter state\n */\nexport function useInnoCalendarFilters() {\n const {\n selectedScheduleTypeIds,\n setSelectedScheduleTypeIds,\n selectedUserId,\n setSelectedUserId,\n searchQuery,\n setSearchQuery,\n } = useInnoCalendar();\n return {\n selectedScheduleTypeIds,\n setSelectedScheduleTypeIds,\n selectedUserId,\n setSelectedUserId,\n searchQuery,\n setSearchQuery,\n };\n}\n\n/**\n * Access only time configuration\n */\nexport function useInnoCalendarTimeConfig() {\n const {\n workingHours,\n setWorkingHours,\n visibleHours,\n setVisibleHours,\n showWorkingHoursOnly,\n setShowWorkingHoursOnly,\n } = useInnoCalendar();\n return {\n workingHours,\n setWorkingHours,\n visibleHours,\n setVisibleHours,\n showWorkingHoursOnly,\n setShowWorkingHoursOnly,\n };\n}\n","/**\n * Slot Selection Context\n *\n * Provides centralized selection state management across all calendar views.\n * This context handles:\n * - Drag-to-select functionality\n * - Selection visualization\n * - Callback integration with parent components\n *\n * Usage:\n * 1. Wrap calendar views with SlotSelectionProvider\n * 2. Use useSlotSelectionContext in child components\n * 3. Connect onSelect callback to event creation dialog\n */\n\nimport {\n\tcreateContext,\n\ttype ReactNode,\n\tuseCallback,\n\tuseContext,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport type {\n\tISelectionResult,\n\tISlotSelectionState,\n\tITimeSlot,\n\tTOnSlotSelect,\n\tTSelectionMode,\n} from '../types';\n\n// ============================================================================\n// CONTEXT TYPES\n// ============================================================================\n\ninterface ISlotSelectionContext {\n\t/** Current selection state */\n\tisSelecting: boolean;\n\t/** Start selection at a slot */\n\tstartSelection: (slot: ITimeSlot) => void;\n\t/** Update selection end point */\n\tupdateSelection: (slot: ITimeSlot) => void;\n\t/** Complete the selection */\n\tendSelection: () => void;\n\t/** Cancel the selection */\n\tcancelSelection: () => void;\n\t/** Check if a slot is within the current selection */\n\tisSlotSelected: (slot: ITimeSlot) => boolean;\n\t/** Get the normalized selection result */\n\tgetSelectionResult: () => ISelectionResult | null;\n\t/** Current selection mode */\n\tmode: TSelectionMode;\n}\n\n// ============================================================================\n// CONTEXT\n// ============================================================================\n\nconst SlotSelectionContext = createContext<ISlotSelectionContext | undefined>(undefined);\n\n// ============================================================================\n// PROVIDER PROPS\n// ============================================================================\n\ninterface SlotSelectionProviderProps {\n\tchildren: ReactNode;\n\t/** Selection mode based on view */\n\tmode?: TSelectionMode;\n\t/** Callback when selection completes */\n\tonSelect?: TOnSlotSelect;\n\t/** Minimum duration in minutes (for time mode) */\n\tminDurationMinutes?: number;\n\t/** Slot duration in minutes (default: 30) */\n\tslotDurationMinutes?: number;\n\t/** Whether selection is enabled */\n\tenabled?: boolean;\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Convert a time slot to a Date object\n */\nfunction slotToDate(slot: ITimeSlot): Date {\n\tconst date = new Date(slot.date);\n\tif (typeof slot.hour === 'number') {\n\t\tdate.setHours(slot.hour, slot.minute ?? 0, 0, 0);\n\t}\n\treturn date;\n}\n\n/**\n * Round time to nearest 30-minute interval\n */\nfunction roundToNearest30Minutes(date: Date): Date {\n\tconst result = new Date(date);\n\tconst minutes = result.getMinutes();\n\tconst roundedMinutes = Math.floor(minutes / 30) * 30;\n\tresult.setMinutes(roundedMinutes, 0, 0);\n\treturn result;\n}\n\n/**\n * Check if two dates are the same calendar day\n */\nfunction isSameDay(date1: Date, date2: Date): boolean {\n\treturn (\n\t\tdate1.getFullYear() === date2.getFullYear() &&\n\t\tdate1.getMonth() === date2.getMonth() &&\n\t\tdate1.getDate() === date2.getDate()\n\t);\n}\n\n/**\n * Normalize selection so start is always before end\n */\nfunction normalizeSelection(\n\tstart: ITimeSlot,\n\tend: ITimeSlot,\n\tmode: TSelectionMode,\n\tminDurationMinutes: number,\n\tslotDurationMinutes = 30\n): ISelectionResult {\n\tconst startDate = slotToDate(start);\n\tconst endDate = slotToDate(end);\n\n\t// Swap if end is before start\n\tlet normalizedStart = startDate;\n\tlet normalizedEnd = endDate;\n\n\tif (endDate < startDate) {\n\t\tnormalizedStart = endDate;\n\t\tnormalizedEnd = startDate;\n\t}\n\n\t// Apply mode-specific logic\n\tif (mode === 'day') {\n\t\t// Check if single day selection (same day click)\n\t\tif (isSameDay(normalizedStart, normalizedEnd)) {\n\t\t\t// Single day: use current time rounded to nearest 30 min + default duration\n\t\t\tconst now = new Date();\n\t\t\tconst roundedNow = roundToNearest30Minutes(now);\n\n\t\t\t// Set the date portion from the selected day\n\t\t\tnormalizedStart = new Date(normalizedStart);\n\t\t\tnormalizedStart.setHours(roundedNow.getHours(), roundedNow.getMinutes(), 0, 0);\n\n\t\t\t// End time = start + minimum duration (default 30 min)\n\t\t\tnormalizedEnd = new Date(normalizedStart.getTime() + minDurationMinutes * 60 * 1000);\n\t\t} else {\n\t\t\t// Multi-day selection: full days\n\t\t\tnormalizedStart.setHours(0, 0, 0, 0);\n\t\t\tnormalizedEnd.setHours(23, 59, 59, 999);\n\t\t}\n\t} else {\n\t\t// Time mode: The end slot represents the START of that slot block,\n\t\t// so we need to add slot duration to get the actual end time\n\t\tconst slotDurationMs = slotDurationMinutes * 60 * 1000;\n\t\tnormalizedEnd = new Date(normalizedEnd.getTime() + slotDurationMs);\n\n\t\t// Ensure minimum duration\n\t\tconst durationMs = normalizedEnd.getTime() - normalizedStart.getTime();\n\t\tconst minDurationMs = minDurationMinutes * 60 * 1000;\n\n\t\tif (durationMs < minDurationMs) {\n\t\t\tnormalizedEnd = new Date(normalizedStart.getTime() + minDurationMs);\n\t\t}\n\t}\n\n\treturn {\n\t\tstartDate: normalizedStart,\n\t\tendDate: normalizedEnd,\n\t};\n}\n\n/**\n * Check if a slot is within a selection range\n */\nfunction isSlotWithinRange(\n\tslot: ITimeSlot,\n\tstart: ITimeSlot,\n\tend: ITimeSlot,\n\tmode: TSelectionMode\n): boolean {\n\tconst slotDate = slotToDate(slot);\n\tconst startDate = slotToDate(start);\n\tconst endDate = slotToDate(end);\n\n\t// Normalize the range\n\tconst rangeStart = startDate <= endDate ? startDate : endDate;\n\tconst rangeEnd = startDate <= endDate ? endDate : startDate;\n\n\tif (mode === 'day') {\n\t\t// Day mode: check if slot's date is within range (ignore time)\n\t\tconst slotDay = new Date(slotDate);\n\t\tslotDay.setHours(0, 0, 0, 0);\n\t\tconst startDay = new Date(rangeStart);\n\t\tstartDay.setHours(0, 0, 0, 0);\n\t\tconst endDay = new Date(rangeEnd);\n\t\tendDay.setHours(0, 0, 0, 0);\n\t\treturn slotDay >= startDay && slotDay <= endDay;\n\t}\n\n\t// Time mode: precise check\n\treturn slotDate >= rangeStart && slotDate <= rangeEnd;\n}\n\n// ============================================================================\n// PROVIDER\n// ============================================================================\n\nexport function SlotSelectionProvider({\n\tchildren,\n\tmode = 'time',\n\tonSelect,\n\tminDurationMinutes = 30,\n\tslotDurationMinutes = 30,\n\tenabled = true,\n}: SlotSelectionProviderProps) {\n\tconst [selection, setSelection] = useState<ISlotSelectionState | null>(null);\n\tconst isSelectingRef = useRef(false);\n\n\t// Start selection\n\tconst startSelection = useCallback(\n\t\t(slot: ITimeSlot) => {\n\t\t\tif (!enabled) return;\n\n\t\t\tisSelectingRef.current = true;\n\t\t\tsetSelection({\n\t\t\t\tstart: slot,\n\t\t\t\tend: slot,\n\t\t\t\tisSelecting: true,\n\t\t\t});\n\t\t},\n\t\t[enabled]\n\t);\n\n\t// Update selection end point\n\tconst updateSelection = useCallback(\n\t\t(slot: ITimeSlot) => {\n\t\t\tif (!(enabled && isSelectingRef.current)) return;\n\n\t\t\tsetSelection((prev) => {\n\t\t\t\tif (!prev) return null;\n\t\t\t\treturn {\n\t\t\t\t\t...prev,\n\t\t\t\t\tend: slot,\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\t[enabled]\n\t);\n\n\t// Complete selection and fire callback\n\tconst endSelection = useCallback(() => {\n\t\tif (!isSelectingRef.current) return;\n\n\t\tisSelectingRef.current = false;\n\n\t\tsetSelection((prev) => {\n\t\t\tif (!prev) return null;\n\n\t\t\t// Calculate final result\n\t\t\tconst result = normalizeSelection(\n\t\t\t\tprev.start,\n\t\t\t\tprev.end,\n\t\t\t\tmode,\n\t\t\t\tminDurationMinutes,\n\t\t\t\tslotDurationMinutes\n\t\t\t);\n\n\t\t\t// Fire callback\n\t\t\tonSelect?.(result);\n\n\t\t\t// Clear selection after a brief delay for visual feedback\n\t\t\treturn {\n\t\t\t\t...prev,\n\t\t\t\tisSelecting: false,\n\t\t\t};\n\t\t});\n\n\t\t// Clear selection after callback\n\t\tsetTimeout(() => {\n\t\t\tsetSelection(null);\n\t\t}, 100);\n\t}, [mode, minDurationMinutes, slotDurationMinutes, onSelect]);\n\n\t// Cancel selection without firing callback\n\tconst cancelSelection = useCallback(() => {\n\t\tisSelectingRef.current = false;\n\t\tsetSelection(null);\n\t}, []);\n\n\t// Check if a slot is in the current selection\n\tconst isSlotInSelection = useCallback(\n\t\t(slot: ITimeSlot): boolean => {\n\t\t\tif (!selection) return false;\n\t\t\treturn isSlotWithinRange(slot, selection.start, selection.end, mode);\n\t\t},\n\t\t[selection, mode]\n\t);\n\n\t// Get the normalized selection result\n\tconst getSelectionResult = useCallback((): ISelectionResult | null => {\n\t\tif (!selection) return null;\n\t\treturn normalizeSelection(\n\t\t\tselection.start,\n\t\t\tselection.end,\n\t\t\tmode,\n\t\t\tminDurationMinutes,\n\t\t\tslotDurationMinutes\n\t\t);\n\t}, [selection, mode, minDurationMinutes, slotDurationMinutes]);\n\n\t// Memoize context value\n\tconst value = useMemo<ISlotSelectionContext>(\n\t\t() => ({\n\t\t\tisSelecting: selection?.isSelecting ?? false,\n\t\t\tstartSelection,\n\t\t\tupdateSelection,\n\t\t\tendSelection,\n\t\t\tcancelSelection,\n\t\t\tisSlotSelected: isSlotInSelection,\n\t\t\tgetSelectionResult,\n\t\t\tmode,\n\t\t}),\n\t\t[\n\t\t\tselection?.isSelecting,\n\t\t\tstartSelection,\n\t\t\tupdateSelection,\n\t\t\tendSelection,\n\t\t\tcancelSelection,\n\t\t\tisSlotInSelection,\n\t\t\tgetSelectionResult,\n\t\t\tmode,\n\t\t]\n\t);\n\n\treturn <SlotSelectionContext.Provider value={value}>{children}</SlotSelectionContext.Provider>;\n}\n\n// ============================================================================\n// HOOKS\n// ============================================================================\n\nexport function useSlotSelectionContext(): ISlotSelectionContext {\n\tconst context = useContext(SlotSelectionContext);\n\tif (!context) {\n\t\tthrow new Error('useSlotSelectionContext must be used within a SlotSelectionProvider');\n\t}\n\treturn context;\n}\n\n/**\n * Optional hook that returns undefined if not in provider\n * Useful for components that can work with or without selection\n */\nexport function useOptionalSlotSelection(): ISlotSelectionContext | undefined {\n\treturn useContext(SlotSelectionContext);\n}\n\n// ============================================================================\n// TYPE EXPORTS\n// ============================================================================\n\nexport type { ISlotSelectionContext, SlotSelectionProviderProps };\n"],"names":["DragDropContext","createContext","DragDropProvider","children","onEventDrop","dragState","setDragState","useState","startDrag","useCallback","event","startDate","endDate","updateDragPreview","date","hour","minute","prev","endDrag","originalStartDate","originalEndDate","previewDate","previewHour","previewMinute","durationMs","newStartDate","newEndDate","result","cancelDrag","jsx","useDragDrop","context","useContext","useOptionalDragDrop","PREFERENCES_STORAGE_KEY","DEFAULT_VISIBLE_HOURS","DEFAULT_WORKING_HOURS","DEFAULT_SLOT_DURATION","SYSTEM_DEFAULTS","loadFromStorage","key","stored","parsed","sanitized","saveToStorage","preferences","useCalendarPreferences","config","modes","locked","defaults","storageKey","disableStorage","effectiveDefaults","useMemo","storedPreferences","setStoredPreferences","sessionPreferences","setSessionPreferences","useEffect","getMode","isLocked","isPersisted","mode","setPreference","value","setPreferences","updates","sessionUpdates","storedUpdates","resetPreferences","resetPreference","_","rest","InnoCalendarContext","InnoCalendarProvider","initialEvents","initialUsers","initialScheduleTypes","initialView","initialDate","initialSelectedUserId","initialScheduleTypeIds","initialParticipantIds","initialWorkingHoursView","initialSearchQuery","preferencesConfig","initialFocusEventId","onDateChange","onViewChange","view","setViewInternal","selectedDate","setSelectedDateInternal","selectedUserId","setSelectedUserId","badgeVariant","setBadgeVariant","variant","workingHours","setWorkingHours","action","current","newValue","prefVisibleHours","visibleHours","setVisibleHours","showWorkingHoursOnlyState","setShowWorkingHoursOnlyState","showWorkingHoursOnly","setShowWorkingHoursOnly","show","slotDuration","setSlotDuration","duration","events","setEvents","selectedScheduleTypeIds","setSelectedScheduleTypeIds","selectedParticipantIds","_setSelectedParticipantIds","searchQuery","setSearchQuery","focusEventId","setFocusEventId","clearFocusEventId","setView","newView","setSelectedDate","newDate","forView","filteredEvents","p","query","useInnoCalendar","useOptionalInnoCalendar","useInnoCalendarView","useInnoCalendarEvents","useInnoCalendarFilters","useInnoCalendarTimeConfig","SlotSelectionContext","slotToDate","slot","roundToNearest30Minutes","minutes","roundedMinutes","isSameDay","date1","date2","normalizeSelection","start","end","minDurationMinutes","slotDurationMinutes","normalizedStart","normalizedEnd","roundedNow","slotDurationMs","minDurationMs","isSlotWithinRange","slotDate","rangeStart","rangeEnd","slotDay","startDay","endDay","SlotSelectionProvider","onSelect","enabled","selection","setSelection","isSelectingRef","useRef","startSelection","updateSelection","endSelection","cancelSelection","isSlotInSelection","getSelectionResult","useSlotSelectionContext","useOptionalSlotSelection"],"mappings":"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"}
|