@innosolutions/inno-calendar 1.0.65 → 1.0.66
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-COxgmpv4.cjs → agenda-widget-BNnhQds1.cjs} +2 -2
- package/dist/{agenda-widget-COxgmpv4.cjs.map → agenda-widget-BNnhQds1.cjs.map} +1 -1
- package/dist/{agenda-widget-CD_UoYWC.js → agenda-widget-qwbBw3IK.js} +245 -245
- package/dist/agenda-widget-qwbBw3IK.js.map +1 -0
- package/dist/components/index.cjs +1 -1
- package/dist/components/index.mjs +2 -2
- package/dist/core/context/inno-calendar-provider.d.ts.map +1 -1
- package/dist/core/index.cjs +1 -1
- package/dist/core/index.mjs +147 -145
- package/dist/core/utils/view-storage.d.ts +21 -0
- package/dist/core/utils/view-storage.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +201 -199
- package/dist/{position-utils-DpaKqYhO.js → position-utils-BzmOPdvQ.js} +294 -276
- package/dist/position-utils-BzmOPdvQ.js.map +1 -0
- package/dist/position-utils-EQTCC4tZ.cjs +2 -0
- package/dist/position-utils-EQTCC4tZ.cjs.map +1 -0
- package/dist/presets/index.cjs +1 -1
- package/dist/presets/index.mjs +1 -1
- package/dist/{slot-selection-context-D3MW4WJ7.js → slot-selection-context-CjS_VIPj.js} +72 -73
- package/dist/slot-selection-context-CjS_VIPj.js.map +1 -0
- package/dist/slot-selection-context-CmE-aWgt.cjs +2 -0
- package/dist/slot-selection-context-CmE-aWgt.cjs.map +1 -0
- package/dist/{tailwind-calendar-CzbuXRmn.js → tailwind-calendar-B6qsueM3.js} +15 -15
- package/dist/{tailwind-calendar-CzbuXRmn.js.map → tailwind-calendar-B6qsueM3.js.map} +1 -1
- package/dist/{tailwind-calendar-smlkVdSq.cjs → tailwind-calendar-KJ1XJ4gr.cjs} +2 -2
- package/dist/{tailwind-calendar-smlkVdSq.cjs.map → tailwind-calendar-KJ1XJ4gr.cjs.map} +1 -1
- package/dist/{use-calendar-mU1joTwp.js → use-calendar--JnbGA3L.js} +23 -23
- package/dist/{use-calendar-mU1joTwp.js.map → use-calendar--JnbGA3L.js.map} +1 -1
- package/dist/{use-calendar-Bd-d8oGj.cjs → use-calendar-BwqE_WNA.cjs} +2 -2
- package/dist/{use-calendar-Bd-d8oGj.cjs.map → use-calendar-BwqE_WNA.cjs.map} +1 -1
- package/dist/{use-slot-selection-CauKdLYv.js → use-slot-selection-BLCDzQzo.js} +8 -8
- package/dist/{use-slot-selection-CauKdLYv.js.map → use-slot-selection-BLCDzQzo.js.map} +1 -1
- package/dist/{use-slot-selection-CCOSsRSh.cjs → use-slot-selection-C1tk-o0j.cjs} +2 -2
- package/dist/{use-slot-selection-CCOSsRSh.cjs.map → use-slot-selection-C1tk-o0j.cjs.map} +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.mjs +52 -50
- package/dist/{week-view-BQXIaSUZ.js → week-view-B1KsZsC3.js} +3 -3
- package/dist/{week-view-BQXIaSUZ.js.map → week-view-B1KsZsC3.js.map} +1 -1
- package/dist/{week-view-xrKlAJos.cjs → week-view-Dv-Uz0eT.cjs} +2 -2
- package/dist/{week-view-xrKlAJos.cjs.map → week-view-Dv-Uz0eT.cjs.map} +1 -1
- package/package.json +1 -1
- package/dist/agenda-widget-CD_UoYWC.js.map +0 -1
- package/dist/position-utils-Do2ciBXl.cjs +0 -2
- package/dist/position-utils-Do2ciBXl.cjs.map +0 -1
- package/dist/position-utils-DpaKqYhO.js.map +0 -1
- package/dist/slot-selection-context-BlrL9b5P.cjs +0 -2
- package/dist/slot-selection-context-BlrL9b5P.cjs.map +0 -1
- package/dist/slot-selection-context-D3MW4WJ7.js.map +0 -1
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-KJ1XJ4gr.cjs");exports.DefaultCalendar=a.DefaultCalendar;exports.TailwindCalendar=a.TailwindCalendar;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/presets/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { useState as h, useCallback as w, useContext as R, createContext as
|
|
3
|
-
import {
|
|
4
|
-
const
|
|
5
|
-
function
|
|
1
|
+
import { jsx as $ } from "react/jsx-runtime";
|
|
2
|
+
import { useState as h, useCallback as w, useContext as R, createContext as z, useMemo as W, useEffect as A, useRef as N } from "react";
|
|
3
|
+
import { P as me, aR as pe, aX as ye, aP as j } from "./position-utils-BzmOPdvQ.js";
|
|
4
|
+
const B = z(void 0);
|
|
5
|
+
function Ue({
|
|
6
6
|
children: n,
|
|
7
7
|
onEventDrop: t
|
|
8
8
|
}) {
|
|
@@ -41,8 +41,8 @@ function _e({
|
|
|
41
41
|
}, [e, t]), u = w(() => {
|
|
42
42
|
r(null);
|
|
43
43
|
}, []);
|
|
44
|
-
return /* @__PURE__ */
|
|
45
|
-
|
|
44
|
+
return /* @__PURE__ */ $(
|
|
45
|
+
B.Provider,
|
|
46
46
|
{
|
|
47
47
|
value: {
|
|
48
48
|
dragState: e,
|
|
@@ -56,19 +56,19 @@ function _e({
|
|
|
56
56
|
}
|
|
57
57
|
);
|
|
58
58
|
}
|
|
59
|
-
function
|
|
60
|
-
const n = R(
|
|
59
|
+
function _e() {
|
|
60
|
+
const n = R(B);
|
|
61
61
|
if (!n)
|
|
62
62
|
throw new Error("useDragDrop must be used within a DragDropProvider");
|
|
63
63
|
return n;
|
|
64
64
|
}
|
|
65
|
-
function
|
|
66
|
-
return R(
|
|
65
|
+
function xe() {
|
|
66
|
+
return R(B) ?? null;
|
|
67
67
|
}
|
|
68
|
-
const be =
|
|
68
|
+
const be = {
|
|
69
69
|
from: 0,
|
|
70
70
|
to: 24
|
|
71
|
-
},
|
|
71
|
+
}, He = {
|
|
72
72
|
0: { enabled: !1, from: 8, to: 18 },
|
|
73
73
|
// Sunday - disabled
|
|
74
74
|
1: { enabled: !0, from: 8, to: 18 },
|
|
@@ -83,17 +83,17 @@ const be = "inno-calendar-preferences", He = {
|
|
|
83
83
|
// Friday
|
|
84
84
|
6: { enabled: !1, from: 8, to: 18 }
|
|
85
85
|
// Saturday - disabled
|
|
86
|
-
},
|
|
86
|
+
}, ke = 30, he = {
|
|
87
87
|
view: "month",
|
|
88
88
|
badgeVariant: "colored",
|
|
89
|
-
slotDuration:
|
|
90
|
-
visibleHours:
|
|
91
|
-
workingHours:
|
|
89
|
+
slotDuration: ke,
|
|
90
|
+
visibleHours: be,
|
|
91
|
+
workingHours: He,
|
|
92
92
|
showWorkingHoursOnly: !1,
|
|
93
93
|
showWeekends: !0,
|
|
94
94
|
firstDayOfWeek: 1
|
|
95
95
|
};
|
|
96
|
-
function
|
|
96
|
+
function Ie(n) {
|
|
97
97
|
if (typeof window > "u") return {};
|
|
98
98
|
try {
|
|
99
99
|
const t = localStorage.getItem(n);
|
|
@@ -104,7 +104,7 @@ function ve(n) {
|
|
|
104
104
|
return console.warn("[InnoCalendar] Failed to load preferences from localStorage"), {};
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
-
function
|
|
107
|
+
function ve(n, t) {
|
|
108
108
|
if (!(typeof window > "u"))
|
|
109
109
|
try {
|
|
110
110
|
localStorage.setItem(n, JSON.stringify(t));
|
|
@@ -112,22 +112,22 @@ function Oe(n, t) {
|
|
|
112
112
|
console.warn("[InnoCalendar] Failed to save preferences to localStorage");
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
function
|
|
115
|
+
function Oe(n = {}) {
|
|
116
116
|
const {
|
|
117
117
|
modes: t = {},
|
|
118
118
|
locked: e = {},
|
|
119
119
|
defaults: r = {},
|
|
120
|
-
storageKey: f =
|
|
120
|
+
storageKey: f = me,
|
|
121
121
|
disableStorage: c = !1
|
|
122
122
|
} = n, g = W(
|
|
123
123
|
() => ({
|
|
124
|
-
...
|
|
124
|
+
...he,
|
|
125
125
|
...r
|
|
126
126
|
}),
|
|
127
127
|
[r]
|
|
128
|
-
), [u, s] = h(() => c ? {} :
|
|
128
|
+
), [u, s] = h(() => c ? {} : Ie(f)), [d, S] = h({});
|
|
129
129
|
A(() => {
|
|
130
|
-
c ||
|
|
130
|
+
c || ve(f, u);
|
|
131
131
|
}, [u, f, c]);
|
|
132
132
|
const i = w(
|
|
133
133
|
(o) => t[o] ?? "user",
|
|
@@ -159,13 +159,13 @@ function Te(n = {}) {
|
|
|
159
159
|
(o) => {
|
|
160
160
|
const l = {}, b = {};
|
|
161
161
|
for (const p of Object.keys(o)) {
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
164
|
-
if (
|
|
162
|
+
const P = i(p), C = o[p];
|
|
163
|
+
if (C !== void 0) {
|
|
164
|
+
if (P === "locked") {
|
|
165
165
|
console.warn(`[InnoCalendar] Preference "${p}" is locked and cannot be modified`);
|
|
166
166
|
continue;
|
|
167
167
|
}
|
|
168
|
-
|
|
168
|
+
P === "session" ? l[p] = C : b[p] = C;
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
Object.keys(l).length > 0 && S((p) => ({ ...p, ...l })), Object.keys(b).length > 0 && s((p) => ({ ...p, ...b }));
|
|
@@ -181,11 +181,11 @@ function Te(n = {}) {
|
|
|
181
181
|
return;
|
|
182
182
|
}
|
|
183
183
|
l === "session" ? S((b) => {
|
|
184
|
-
const { [o]: p, ...
|
|
185
|
-
return
|
|
184
|
+
const { [o]: p, ...P } = b;
|
|
185
|
+
return P;
|
|
186
186
|
}) : s((b) => {
|
|
187
|
-
const { [o]: p, ...
|
|
188
|
-
return
|
|
187
|
+
const { [o]: p, ...P } = b;
|
|
188
|
+
return P;
|
|
189
189
|
});
|
|
190
190
|
},
|
|
191
191
|
[i]
|
|
@@ -201,7 +201,7 @@ function Te(n = {}) {
|
|
|
201
201
|
getMode: i
|
|
202
202
|
};
|
|
203
203
|
}
|
|
204
|
-
const
|
|
204
|
+
const K = z(void 0), ue = {
|
|
205
205
|
0: { enabled: !1, from: 8, to: 17 },
|
|
206
206
|
// Sunday
|
|
207
207
|
1: { enabled: !0, from: 8, to: 17 },
|
|
@@ -216,8 +216,8 @@ const B = $(void 0), ue = {
|
|
|
216
216
|
// Friday
|
|
217
217
|
6: { enabled: !0, from: 8, to: 12 }
|
|
218
218
|
// Saturday
|
|
219
|
-
},
|
|
220
|
-
function
|
|
219
|
+
}, Te = { start: 0, end: 24 };
|
|
220
|
+
function Fe({
|
|
221
221
|
children: n,
|
|
222
222
|
initialEvents: t = [],
|
|
223
223
|
initialUsers: e = [],
|
|
@@ -234,13 +234,13 @@ function Me({
|
|
|
234
234
|
onDateChange: T,
|
|
235
235
|
onViewChange: v
|
|
236
236
|
}) {
|
|
237
|
-
const { preferences: k, setPreference: D, isLocked: m } =
|
|
238
|
-
|
|
237
|
+
const { preferences: k, setPreference: D, isLocked: m } = Oe(i), [I, o] = h(
|
|
238
|
+
() => f ?? pe() ?? "week"
|
|
239
239
|
), [l, b] = h(
|
|
240
240
|
c ?? /* @__PURE__ */ new Date()
|
|
241
|
-
), [p,
|
|
241
|
+
), [p, P] = h(
|
|
242
242
|
g
|
|
243
|
-
),
|
|
243
|
+
), C = k.badgeVariant ?? "colored", Y = w(
|
|
244
244
|
(a) => {
|
|
245
245
|
m("badgeVariant") || D("badgeVariant", a);
|
|
246
246
|
},
|
|
@@ -256,7 +256,7 @@ function Me({
|
|
|
256
256
|
), E = k.visibleHours, _ = W(() => E ? {
|
|
257
257
|
start: E.start ?? E.from ?? 0,
|
|
258
258
|
end: E.end ?? E.to ?? 24
|
|
259
|
-
} :
|
|
259
|
+
} : Te, [E]), q = w(
|
|
260
260
|
(a) => {
|
|
261
261
|
if (!m("visibleHours")) {
|
|
262
262
|
const y = typeof a == "function" ? a(_) : a;
|
|
@@ -283,7 +283,7 @@ function Me({
|
|
|
283
283
|
A(() => {
|
|
284
284
|
ne(t);
|
|
285
285
|
}, [t]);
|
|
286
|
-
const [V, ge] = h(u), [M,
|
|
286
|
+
const [V, ge] = h(u), [M, We] = h(s), [L, we] = h(S), [re, oe] = h(
|
|
287
287
|
H ?? null
|
|
288
288
|
);
|
|
289
289
|
A(() => {
|
|
@@ -329,9 +329,9 @@ function Me({
|
|
|
329
329
|
setSelectedDate: ie,
|
|
330
330
|
// User Filtering
|
|
331
331
|
selectedUserId: p,
|
|
332
|
-
setSelectedUserId:
|
|
332
|
+
setSelectedUserId: P,
|
|
333
333
|
// Visual Customization
|
|
334
|
-
badgeVariant:
|
|
334
|
+
badgeVariant: C,
|
|
335
335
|
setBadgeVariant: Y,
|
|
336
336
|
// Time Configuration
|
|
337
337
|
workingHours: G,
|
|
@@ -367,7 +367,7 @@ function Me({
|
|
|
367
367
|
l,
|
|
368
368
|
ie,
|
|
369
369
|
p,
|
|
370
|
-
|
|
370
|
+
C,
|
|
371
371
|
Y,
|
|
372
372
|
G,
|
|
373
373
|
J,
|
|
@@ -388,28 +388,28 @@ function Me({
|
|
|
388
388
|
se
|
|
389
389
|
]
|
|
390
390
|
);
|
|
391
|
-
return /* @__PURE__ */
|
|
391
|
+
return /* @__PURE__ */ $(K.Provider, { value: Se, children: n });
|
|
392
392
|
}
|
|
393
393
|
function F() {
|
|
394
|
-
const n = R(
|
|
394
|
+
const n = R(K);
|
|
395
395
|
if (!n)
|
|
396
396
|
throw new Error(
|
|
397
397
|
"useInnoCalendar must be used within an InnoCalendarProvider"
|
|
398
398
|
);
|
|
399
399
|
return n;
|
|
400
400
|
}
|
|
401
|
-
function
|
|
402
|
-
return R(
|
|
401
|
+
function Me() {
|
|
402
|
+
return R(K);
|
|
403
403
|
}
|
|
404
|
-
function
|
|
404
|
+
function Ne() {
|
|
405
405
|
const { view: n, setView: t, selectedDate: e, setSelectedDate: r, slotDuration: f } = F();
|
|
406
406
|
return { view: n, setView: t, selectedDate: e, setSelectedDate: r, slotDuration: f };
|
|
407
407
|
}
|
|
408
|
-
function
|
|
408
|
+
function je() {
|
|
409
409
|
const { events: n, setEvents: t, filteredEvents: e } = F();
|
|
410
410
|
return { events: n, setEvents: t, filteredEvents: e };
|
|
411
411
|
}
|
|
412
|
-
function
|
|
412
|
+
function Ae() {
|
|
413
413
|
const {
|
|
414
414
|
selectedScheduleTypeIds: n,
|
|
415
415
|
setSelectedScheduleTypeIds: t,
|
|
@@ -445,7 +445,7 @@ function $e() {
|
|
|
445
445
|
setShowWorkingHoursOnly: c
|
|
446
446
|
};
|
|
447
447
|
}
|
|
448
|
-
const
|
|
448
|
+
const Q = z(void 0);
|
|
449
449
|
function U(n) {
|
|
450
450
|
const t = new Date(n.date);
|
|
451
451
|
return typeof n.hour == "number" && t.setHours(n.hour, n.minute ?? 0, 0, 0), t;
|
|
@@ -454,14 +454,14 @@ function Pe(n) {
|
|
|
454
454
|
const t = new Date(n), e = t.getMinutes(), r = Math.floor(e / 30) * 30;
|
|
455
455
|
return t.setMinutes(r, 0, 0), t;
|
|
456
456
|
}
|
|
457
|
-
function
|
|
457
|
+
function Ce(n, t) {
|
|
458
458
|
return n.getFullYear() === t.getFullYear() && n.getMonth() === t.getMonth() && n.getDate() === t.getDate();
|
|
459
459
|
}
|
|
460
460
|
function le(n, t, e, r, f = 30) {
|
|
461
461
|
const c = U(n), g = U(t);
|
|
462
462
|
let u = c, s = g;
|
|
463
463
|
if (g < c && (u = g, s = c), e === "day")
|
|
464
|
-
if (
|
|
464
|
+
if (Ce(u, s)) {
|
|
465
465
|
const S = Pe(/* @__PURE__ */ new Date());
|
|
466
466
|
u = new Date(u), u.setHours(S.getHours(), S.getMinutes(), 0, 0), s = new Date(u.getTime() + r * 60 * 1e3);
|
|
467
467
|
} else
|
|
@@ -477,7 +477,7 @@ function le(n, t, e, r, f = 30) {
|
|
|
477
477
|
endDate: s
|
|
478
478
|
};
|
|
479
479
|
}
|
|
480
|
-
function
|
|
480
|
+
function Ee(n, t, e, r) {
|
|
481
481
|
const f = U(n), c = U(t), g = U(e), u = c <= g ? c : g, s = c <= g ? g : c;
|
|
482
482
|
if (r === "day") {
|
|
483
483
|
const d = new Date(f);
|
|
@@ -538,7 +538,7 @@ function ze({
|
|
|
538
538
|
}, [t, r, f, e]), k = w(() => {
|
|
539
539
|
s.current = !1, u(null);
|
|
540
540
|
}, []), D = w(
|
|
541
|
-
(o) => g ?
|
|
541
|
+
(o) => g ? Ee(o, g.start, g.end, t) : !1,
|
|
542
542
|
[g, t]
|
|
543
543
|
), m = w(() => g ? le(
|
|
544
544
|
g.start,
|
|
@@ -570,35 +570,34 @@ function ze({
|
|
|
570
570
|
i
|
|
571
571
|
]
|
|
572
572
|
);
|
|
573
|
-
return /* @__PURE__ */ Q
|
|
573
|
+
return /* @__PURE__ */ $(Q.Provider, { value: I, children: n });
|
|
574
574
|
}
|
|
575
575
|
function Be() {
|
|
576
|
-
const n = R(
|
|
576
|
+
const n = R(Q);
|
|
577
577
|
if (!n)
|
|
578
578
|
throw new Error("useSlotSelectionContext must be used within a SlotSelectionProvider");
|
|
579
579
|
return n;
|
|
580
580
|
}
|
|
581
581
|
function Ke() {
|
|
582
|
-
return R(
|
|
582
|
+
return R(Q);
|
|
583
583
|
}
|
|
584
584
|
export {
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
be as P,
|
|
585
|
+
Ue as D,
|
|
586
|
+
Fe as I,
|
|
588
587
|
ze as S,
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
588
|
+
ke as a,
|
|
589
|
+
be as b,
|
|
590
|
+
He as c,
|
|
591
|
+
_e as d,
|
|
593
592
|
F as e,
|
|
594
|
-
|
|
595
|
-
|
|
593
|
+
je as f,
|
|
594
|
+
Ae as g,
|
|
596
595
|
$e as h,
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
596
|
+
Ne as i,
|
|
597
|
+
xe as j,
|
|
598
|
+
Me as k,
|
|
600
599
|
Ke as l,
|
|
601
600
|
Be as m,
|
|
602
|
-
|
|
601
|
+
Oe as u
|
|
603
602
|
};
|
|
604
|
-
//# sourceMappingURL=slot-selection-context-
|
|
603
|
+
//# sourceMappingURL=slot-selection-context-CjS_VIPj.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slot-selection-context-CjS_VIPj.js","sources":["../src/core/context/drag-drop-context.tsx","../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\t/** Original resource/row ID (for resource/timeline views) */\n\toriginalResourceId?: string | undefined;\n\t/** Current target resource/row ID during drag (for resource/timeline views) */\n\ttargetResourceId?: string | 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\t/** New resource/row ID after drop (for resource/timeline views) */\n\tnewResourceId?: string | undefined;\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, resourceId?: string) => 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, resourceId?: string) => {\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\t...(resourceId !== undefined && { targetResourceId: resourceId }),\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, targetResourceId } =\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\t...(targetResourceId !== undefined && { newResourceId: targetResourceId }),\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 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\";\nimport { reactNodeToText } from \"../utils/react-node-utils\";\nimport { readPersistedView, saveViewByFamily } from \"../utils/view-storage\";\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 // Initial view priority:\n // 1. Explicit `initialView` prop (consumer-controlled)\n // 2. Any view persisted to localStorage (per-family keys, then legacy\n // preferences key — see `readPersistedView` for details)\n // 3. The documented default: \"week\"\n //\n // Note: `preferences.view` is intentionally not used as a fallback because\n // it always resolves to a value (SYSTEM_DEFAULTS = 'month') and would\n // shadow the localStorage chain. Saved values still feed in through\n // `readPersistedView`, which reads the same legacy key directly.\n const [view, setViewInternal] = useState<TCalendarView>(\n () => initialView ?? readPersistedView() ?? \"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 // Persist the last selection per family (calendar vs resource) so each\n // dropdown remembers its own most-recent value independently.\n saveViewByFamily(newView);\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 reactNodeToText(event.title).toLowerCase().includes(query) ||\n reactNodeToText(event.description).toLowerCase().includes(query) ||\n reactNodeToText(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\t/** Temporarily suppress selection (e.g. after popover dismiss) */\n\tsuppressSelection: () => void;\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\tconst isSuppressedRef = useRef(false);\n\tconst suppressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n\t// Temporarily suppress selection (e.g. when a popover is dismissed by clicking outside)\n\tconst suppressSelection = useCallback(() => {\n\t\tisSuppressedRef.current = true;\n\t\tif (suppressTimerRef.current) clearTimeout(suppressTimerRef.current);\n\t\tsuppressTimerRef.current = setTimeout(() => {\n\t\t\tisSuppressedRef.current = false;\n\t\t}, 300);\n\t}, []);\n\n\t// Start selection\n\tconst startSelection = useCallback(\n\t\t(slot: ITimeSlot) => {\n\t\t\tif (!enabled || isSuppressedRef.current) 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\tsuppressSelection,\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\tsuppressSelection,\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","resourceId","prev","endDrag","originalStartDate","originalEndDate","previewDate","previewHour","previewMinute","targetResourceId","durationMs","newStartDate","newEndDate","result","cancelDrag","jsx","useDragDrop","context","useContext","useOptionalDragDrop","DEFAULT_VISIBLE_HOURS","DEFAULT_WORKING_HOURS","DEFAULT_SLOT_DURATION","SYSTEM_DEFAULTS","loadFromStorage","key","stored","parsed","sanitized","saveToStorage","preferences","useCalendarPreferences","config","modes","locked","defaults","storageKey","PREFERENCES_STORAGE_KEY","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","readPersistedView","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","saveViewByFamily","setSelectedDate","newDate","forView","filteredEvents","p","query","reactNodeToText","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","isSuppressedRef","suppressTimerRef","suppressSelection","startSelection","updateSelection","endSelection","cancelSelection","isSlotInSelection","getSelectionResult","useSlotSelectionContext","useOptionalSlotSelection"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const F=require("react/jsx-runtime"),e=require("react"),P=require("./position-utils-EQTCC4tZ.cjs"),M=e.createContext(void 0);function De({children:s,onEventDrop:n}){const[t,r]=e.useState(null),g=e.useCallback(a=>{const f=typeof a.startDate=="string"?new Date(a.startDate):a.startDate,D=typeof a.endDate=="string"?new Date(a.endDate):a.endDate;r({event:a,originalStartDate:f,originalEndDate:D})},[]),i=e.useCallback((a,f,D,l)=>{r(m=>m?{...m,previewDate:a,previewHour:f,previewMinute:D,...l!==void 0&&{targetResourceId:l}}:null)},[]),S=e.useCallback(()=>{if(!t)return null;const{event:a,originalStartDate:f,originalEndDate:D,previewDate:l,previewHour:m,previewMinute:T,targetResourceId:I}=t,H=D.getTime()-f.getTime();let w;l?(w=new Date(l),typeof m=="number"?w.setHours(m,T??0,0,0):w.setHours(f.getHours(),f.getMinutes(),f.getSeconds(),0)):w=f;const b=new Date(w.getTime()+H),y={event:a,newStartDate:w,newEndDate:b,...I!==void 0&&{newResourceId:I}};return r(null),n?.(y),y},[t,n]),c=e.useCallback(()=>{r(null)},[]);return F.jsx(M.Provider,{value:{dragState:t,isDragging:t!==null,startDrag:g,updateDragPreview:i,endDrag:S,cancelDrag:c},children:s})}function we(){const s=e.useContext(M);if(!s)throw new Error("useDragDrop must be used within a DragDropProvider");return s}function be(){return e.useContext(M)??null}const oe={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}},ue=30,ke={view:"month",badgeVariant:"colored",slotDuration:ue,visibleHours:oe,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),r={};return t.view&&typeof t.view=="string"&&(r.view=t.view),t.badgeVariant&&typeof t.badgeVariant=="string"&&(r.badgeVariant=t.badgeVariant),t.slotDuration&&typeof t.slotDuration=="number"&&(r.slotDuration=t.slotDuration),t.visibleHours&&typeof t.visibleHours=="object"&&(r.visibleHours=t.visibleHours),t.workingHours&&typeof t.workingHours=="object"&&(r.workingHours=t.workingHours),typeof t.showWorkingHoursOnly=="boolean"&&(r.showWorkingHoursOnly=t.showWorkingHoursOnly),typeof t.showWeekends=="boolean"&&(r.showWeekends=t.showWeekends),typeof t.firstDayOfWeek=="number"&&(r.firstDayOfWeek=t.firstDayOfWeek),r}catch{return console.warn("[InnoCalendar] Failed to load preferences from localStorage"),{}}}function pe(s,n){if(!(typeof window>"u"))try{localStorage.setItem(s,JSON.stringify(n))}catch{console.warn("[InnoCalendar] Failed to save preferences to localStorage")}}function le(s={}){const{modes:n={},locked:t={},defaults:r={},storageKey:g=P.PREFERENCES_STORAGE_KEY,disableStorage:i=!1}=s,S=e.useMemo(()=>({...ke,...r}),[r]),[c,a]=e.useState(()=>i?{}:Ce(g)),[f,D]=e.useState({});e.useEffect(()=>{i||pe(g,c)},[c,g,i]);const l=e.useCallback(o=>n[o]??"user",[n]),m=e.useCallback(o=>l(o)==="locked",[l]),T=e.useCallback(o=>l(o)==="user"&&!i,[l,i]),I=e.useMemo(()=>{const o={...S};for(const d of Object.keys(o)){const p=l(d);p==="locked"&&d in t?o[d]=t[d]:p==="session"&&d in f?o[d]=f[d]:p==="user"&&d in c&&(o[d]=c[d])}return o},[S,c,f,t,l]),H=e.useCallback((o,d)=>{const p=l(o);if(p==="locked"){console.warn(`[InnoCalendar] Preference "${o}" is locked and cannot be modified`);return}p==="session"?D(k=>({...k,[o]:d})):a(k=>({...k,[o]:d}))},[l]),w=e.useCallback(o=>{const d={},p={};for(const k of Object.keys(o)){const v=l(k),O=o[k];if(O!==void 0){if(v==="locked"){console.warn(`[InnoCalendar] Preference "${k}" is locked and cannot be modified`);continue}v==="session"?d[k]=O:p[k]=O}}Object.keys(d).length>0&&D(k=>({...k,...d})),Object.keys(p).length>0&&a(k=>({...k,...p}))},[l]),b=e.useCallback(()=>{a({}),D({}),i||localStorage.removeItem(g)},[g,i]),y=e.useCallback(o=>{const d=l(o);if(d==="locked"){console.warn(`[InnoCalendar] Preference "${o}" is locked and cannot be reset`);return}d==="session"?D(p=>{const{[o]:k,...v}=p;return v}):a(p=>{const{[o]:k,...v}=p;return v})},[l]);return{preferences:I,setPreference:H,setPreferences:w,resetPreferences:b,resetPreference:y,isLocked:m,isPersisted:T,getMode:l}}const N=e.createContext(void 0),se={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}},me={start:0,end:24};function He({children:s,initialEvents:n=[],initialUsers:t=[],initialScheduleTypes:r=[],initialView:g,initialDate:i,initialSelectedUserId:S="all",initialScheduleTypeIds:c=[],initialParticipantIds:a=[],initialWorkingHoursView:f="default",initialSearchQuery:D="",preferencesConfig:l,initialFocusEventId:m=null,onDateChange:T,onViewChange:I}){const{preferences:H,setPreference:w,isLocked:b}=le(l),[y,o]=e.useState(()=>g??P.readPersistedView()??"week"),[d,p]=e.useState(i??new Date),[k,v]=e.useState(S),O=H.badgeVariant??"colored",j=e.useCallback(u=>{b("badgeVariant")||w("badgeVariant",u)},[w,b]),B=H.workingHours??se,K=e.useCallback(u=>{if(!b("workingHours")){const C=H.workingHours??se,h=typeof u=="function"?u(C):u;w("workingHours",h)}},[w,b,H.workingHours]),E=H.visibleHours,L=e.useMemo(()=>E?{start:E.start??E.from??0,end:E.end??E.to??24}:me,[E]),$=e.useCallback(u=>{if(!b("visibleHours")){const C=typeof u=="function"?u(L):u;w("visibleHours",{from:C.start,to:C.end})}},[w,b,L]),[ie,ce]=e.useState(f==="enabled"?!0:f==="disabled"?!1:H.showWorkingHoursOnly??!1),q=ie,z=e.useCallback(u=>{ce(u),b("showWorkingHoursOnly")||w("showWorkingHoursOnly",u)},[w,b]),G=H.slotDuration??30,Q=e.useCallback(u=>{b("slotDuration")||w("slotDuration",u)},[w,b]),[_,Y]=e.useState(n);e.useEffect(()=>{Y(n)},[n]);const[x,de]=e.useState(c),[V,Ue]=e.useState(a),[R,fe]=e.useState(D),[J,X]=e.useState(m??null);e.useEffect(()=>{m&&X(m)},[m]);const Z=e.useCallback(()=>X(null),[]),ee=e.useCallback(u=>{o(u),b("view")||w("view",u),P.saveViewByFamily(u),I?.(u)},[I,w,b]),te=e.useCallback((u,C)=>{p(u),T?.(u,C??y)},[T,y]),ne=e.useMemo(()=>{let u=_;if(x.length>0&&(u=u.filter(C=>C.scheduleTypeId!==void 0&&x.includes(C.scheduleTypeId))),V.length>0&&(u=u.filter(C=>C.participants?.length?C.participants.some(h=>V.includes(h.id)):!1)),k!=="all"&&(u=u.filter(C=>C.participants?.some(h=>h.id===k))),R.trim()){const C=R.toLowerCase();u=u.filter(h=>P.reactNodeToText(h.title).toLowerCase().includes(C)||P.reactNodeToText(h.description).toLowerCase().includes(C)||P.reactNodeToText(h.scheduleTypeName).toLowerCase().includes(C)||h.participants?.some(Se=>Se.name.toLowerCase().includes(C)))}return u},[_,x,V,k,R]),ge=e.useMemo(()=>({view:y,setView:ee,selectedDate:d,setSelectedDate:te,selectedUserId:k,setSelectedUserId:v,badgeVariant:O,setBadgeVariant:j,workingHours:B,setWorkingHours:K,visibleHours:L,setVisibleHours:$,showWorkingHoursOnly:q,setShowWorkingHoursOnly:z,slotDuration:G,setSlotDuration:Q,isPreferenceLocked:b,events:_,setEvents:Y,users:t,scheduleTypes:r,selectedScheduleTypeIds:x,setSelectedScheduleTypeIds:de,searchQuery:R,setSearchQuery:fe,filteredEvents:ne,focusEventId:J,clearFocusEventId:Z}),[y,ee,d,te,k,O,j,B,K,L,$,q,z,G,Q,b,_,t,r,x,R,ne,J,Z]);return F.jsx(N.Provider,{value:ge,children:s})}function U(){const s=e.useContext(N);if(!s)throw new Error("useInnoCalendar must be used within an InnoCalendarProvider");return s}function ye(){return e.useContext(N)}function Ie(){const{view:s,setView:n,selectedDate:t,setSelectedDate:r,slotDuration:g}=U();return{view:s,setView:n,selectedDate:t,setSelectedDate:r,slotDuration:g}}function he(){const{events:s,setEvents:n,filteredEvents:t}=U();return{events:s,setEvents:n,filteredEvents:t}}function Te(){const{selectedScheduleTypeIds:s,setSelectedScheduleTypeIds:n,selectedUserId:t,setSelectedUserId:r,searchQuery:g,setSearchQuery:i}=U();return{selectedScheduleTypeIds:s,setSelectedScheduleTypeIds:n,selectedUserId:t,setSelectedUserId:r,searchQuery:g,setSearchQuery:i}}function ve(){const{workingHours:s,setWorkingHours:n,visibleHours:t,setVisibleHours:r,showWorkingHoursOnly:g,setShowWorkingHoursOnly:i}=U();return{workingHours:s,setWorkingHours:n,visibleHours:t,setVisibleHours:r,showWorkingHoursOnly:g,setShowWorkingHoursOnly:i}}const A=e.createContext(void 0);function W(s){const n=new Date(s.date);return typeof s.hour=="number"&&n.setHours(s.hour,s.minute??0,0,0),n}function Oe(s){const n=new Date(s),t=n.getMinutes(),r=Math.floor(t/30)*30;return n.setMinutes(r,0,0),n}function Ee(s,n){return s.getFullYear()===n.getFullYear()&&s.getMonth()===n.getMonth()&&s.getDate()===n.getDate()}function re(s,n,t,r,g=30){const i=W(s),S=W(n);let c=i,a=S;if(S<i&&(c=S,a=i),t==="day")if(Ee(c,a)){const D=Oe(new Date);c=new Date(c),c.setHours(D.getHours(),D.getMinutes(),0,0),a=new Date(c.getTime()+r*60*1e3)}else c.setHours(0,0,0,0),a.setHours(23,59,59,999);else{const f=g*60*1e3;a=new Date(a.getTime()+f);const D=a.getTime()-c.getTime(),l=r*60*1e3;D<l&&(a=new Date(c.getTime()+l))}return{startDate:c,endDate:a}}function Pe(s,n,t,r){const g=W(s),i=W(n),S=W(t),c=i<=S?i:S,a=i<=S?S:i;if(r==="day"){const f=new Date(g);f.setHours(0,0,0,0);const D=new Date(c);D.setHours(0,0,0,0);const l=new Date(a);return l.setHours(0,0,0,0),f>=D&&f<=l}return g>=c&&g<=a}function xe({children:s,mode:n="time",onSelect:t,minDurationMinutes:r=30,slotDurationMinutes:g=30,enabled:i=!0}){const[S,c]=e.useState(null),a=e.useRef(!1),f=e.useRef(!1),D=e.useRef(null),l=e.useCallback(()=>{f.current=!0,D.current&&clearTimeout(D.current),D.current=setTimeout(()=>{f.current=!1},300)},[]),m=e.useCallback(o=>{!i||f.current||(a.current=!0,c({start:o,end:o,isSelecting:!0}))},[i]),T=e.useCallback(o=>{i&&a.current&&c(d=>d?{...d,end:o}:null)},[i]),I=e.useCallback(()=>{a.current&&(a.current=!1,c(o=>{if(!o)return null;const d=re(o.start,o.end,n,r,g);return t?.(d),{...o,isSelecting:!1}}),setTimeout(()=>{c(null)},100))},[n,r,g,t]),H=e.useCallback(()=>{a.current=!1,c(null)},[]),w=e.useCallback(o=>S?Pe(o,S.start,S.end,n):!1,[S,n]),b=e.useCallback(()=>S?re(S.start,S.end,n,r,g):null,[S,n,r,g]),y=e.useMemo(()=>({isSelecting:S?.isSelecting??!1,startSelection:m,updateSelection:T,endSelection:I,cancelSelection:H,isSlotSelected:w,getSelectionResult:b,mode:n,suppressSelection:l}),[S?.isSelecting,m,T,I,H,w,b,n,l]);return F.jsx(A.Provider,{value:y,children:s})}function Re(){const s=e.useContext(A);if(!s)throw new Error("useSlotSelectionContext must be used within a SlotSelectionProvider");return s}function We(){return e.useContext(A)}exports.DEFAULT_SLOT_DURATION=ue;exports.DEFAULT_VISIBLE_HOURS=oe;exports.DEFAULT_WORKING_HOURS=ae;exports.DragDropProvider=De;exports.InnoCalendarProvider=He;exports.SlotSelectionProvider=xe;exports.useCalendarPreferences=le;exports.useDragDrop=we;exports.useInnoCalendar=U;exports.useInnoCalendarEvents=he;exports.useInnoCalendarFilters=Te;exports.useInnoCalendarTimeConfig=ve;exports.useInnoCalendarView=Ie;exports.useOptionalDragDrop=be;exports.useOptionalInnoCalendar=ye;exports.useOptionalSlotSelection=We;exports.useSlotSelectionContext=Re;
|
|
2
|
+
//# sourceMappingURL=slot-selection-context-CmE-aWgt.cjs.map
|