calendarkit-pro 1.2.0 → 1.3.0

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/index.js CHANGED
@@ -1,46 +1,64 @@
1
- 'use strict';
1
+ "use client";
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
2
30
 
3
- var React15 = require('react');
4
- var core = require('@dnd-kit/core');
5
- var modifiers = require('@dnd-kit/modifiers');
6
- var framerMotion = require('framer-motion');
7
- var dateFns = require('date-fns');
8
- var classVarianceAuthority = require('class-variance-authority');
9
- var clsx = require('clsx');
10
- var tailwindMerge = require('tailwind-merge');
11
- var lucideReact = require('lucide-react');
12
- var dateFnsTz = require('date-fns-tz');
13
- var utilities = require('@dnd-kit/utilities');
14
- var rrule = require('rrule');
31
+ // src/index.tsx
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ Scheduler: () => Scheduler,
35
+ cn: () => cn
36
+ });
37
+ module.exports = __toCommonJS(index_exports);
38
+ var import_react20 = __toESM(require("react"));
39
+ var import_core3 = require("@dnd-kit/core");
40
+ var import_modifiers = require("@dnd-kit/modifiers");
41
+ var import_framer_motion4 = require("framer-motion");
15
42
 
16
- function _interopNamespace(e) {
17
- if (e && e.__esModule) return e;
18
- var n = Object.create(null);
19
- if (e) {
20
- Object.keys(e).forEach(function (k) {
21
- if (k !== 'default') {
22
- var d = Object.getOwnPropertyDescriptor(e, k);
23
- Object.defineProperty(n, k, d.get ? d : {
24
- enumerable: true,
25
- get: function () { return e[k]; }
26
- });
27
- }
28
- });
29
- }
30
- n.default = e;
31
- return Object.freeze(n);
32
- }
43
+ // src/components/CalendarHeader.tsx
44
+ var import_react = __toESM(require("react"));
45
+ var import_date_fns = require("date-fns");
33
46
 
34
- var React15__namespace = /*#__PURE__*/_interopNamespace(React15);
47
+ // src/components/ui/button.tsx
48
+ var React = __toESM(require("react"));
49
+ var import_class_variance_authority = require("class-variance-authority");
35
50
 
51
+ // src/utils.ts
52
+ var import_clsx = require("clsx");
53
+ var import_tailwind_merge = require("tailwind-merge");
36
54
  function cn(...inputs) {
37
- return tailwindMerge.twMerge(clsx.clsx(inputs));
55
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
38
56
  }
39
57
  var isEventDragDisabled = (event) => event?.draggable === false;
40
58
  var isEventResizeDisabled = (event) => event?.resizable === false || event?.resizable === void 0 && isEventDragDisabled(event);
41
59
 
42
60
  // src/components/ui/button.tsx
43
- var buttonVariants = classVarianceAuthority.cva(
61
+ var buttonVariants = (0, import_class_variance_authority.cva)(
44
62
  "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
45
63
  {
46
64
  variants: {
@@ -65,10 +83,10 @@ var buttonVariants = classVarianceAuthority.cva(
65
83
  }
66
84
  }
67
85
  );
68
- var Button = React15__namespace.forwardRef(
69
- ({ className, variant, size, asChild = false, ...props }, ref) => {
86
+ var Button = React.forwardRef(
87
+ ({ className, variant, size, ...props }, ref) => {
70
88
  const Comp = "button";
71
- return /* @__PURE__ */ React15__namespace.createElement(
89
+ return /* @__PURE__ */ React.createElement(
72
90
  Comp,
73
91
  {
74
92
  className: cn(buttonVariants({ variant, size, className })),
@@ -79,6 +97,9 @@ var Button = React15__namespace.forwardRef(
79
97
  }
80
98
  );
81
99
  Button.displayName = "Button";
100
+
101
+ // src/components/CalendarHeader.tsx
102
+ var import_lucide_react = require("lucide-react");
82
103
  var CalendarHeader = ({
83
104
  currentDate,
84
105
  onPrev,
@@ -96,12 +117,12 @@ var CalendarHeader = ({
96
117
  locale
97
118
  }) => {
98
119
  const viewConfig = [
99
- { key: "month", icon: lucideReact.CalendarDays },
100
- { key: "week", icon: lucideReact.CalendarRange },
101
- { key: "day", icon: lucideReact.Calendar },
102
- { key: "agenda", icon: lucideReact.ListTodo }
120
+ { key: "month", icon: import_lucide_react.CalendarDays },
121
+ { key: "week", icon: import_lucide_react.CalendarRange },
122
+ { key: "day", icon: import_lucide_react.Calendar },
123
+ { key: "agenda", icon: import_lucide_react.ListTodo }
103
124
  ];
104
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col md:flex-row items-center justify-between px-3 md:px-5 py-3 border-b-[0px] border-border/50 bg-gradient-to-r from-background via-background to-muted/20 gap-3 md:gap-0 min-h-[64px]" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2 w-full md:w-auto justify-between md:justify-start" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2 md:gap-3" }, /* @__PURE__ */ React15__namespace.default.createElement(
125
+ return /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col md:flex-row items-center justify-between px-3 md:px-5 py-3 border-b-[0px] border-border/50 bg-gradient-to-r from-background via-background to-muted/20 gap-3 md:gap-0 min-h-[64px]" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 w-full md:w-auto justify-between md:justify-start" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 md:gap-3" }, /* @__PURE__ */ import_react.default.createElement(
105
126
  Button,
106
127
  {
107
128
  variant: "ghost",
@@ -109,8 +130,8 @@ var CalendarHeader = ({
109
130
  className: "text-muted-foreground hover:text-foreground hover:bg-accent/80 rounded-xl h-10 w-10 hidden md:inline-flex transition-all duration-200",
110
131
  onClick: onMenuClick
111
132
  },
112
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Menu, { className: "h-5 w-5" })
113
- ), /* @__PURE__ */ React15__namespace.default.createElement(
133
+ /* @__PURE__ */ import_react.default.createElement(import_lucide_react.Menu, { className: "h-5 w-5" })
134
+ ), /* @__PURE__ */ import_react.default.createElement(
114
135
  Button,
115
136
  {
116
137
  variant: "outline",
@@ -118,7 +139,7 @@ var CalendarHeader = ({
118
139
  className: "h-9 px-5 rounded-xl text-sm font-medium hidden sm:inline-flex border-[0.5px] border-border/60 hover:border-primary/40 hover:bg-primary/5 hover:text-primary transition-all duration-200"
119
140
  },
120
141
  translations.today
121
- ), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center bg-muted/40 rounded-xl p-0.5" }, /* @__PURE__ */ React15__namespace.default.createElement(
142
+ ), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center bg-muted/40 rounded-xl p-0.5" }, /* @__PURE__ */ import_react.default.createElement(
122
143
  Button,
123
144
  {
124
145
  variant: "ghost",
@@ -126,8 +147,8 @@ var CalendarHeader = ({
126
147
  onClick: onPrev,
127
148
  className: "rounded-lg h-8 w-8 hover:bg-background/80 transition-all duration-200"
128
149
  },
129
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.ChevronLeft, { className: "h-4 w-4 text-muted-foreground" })
130
- ), /* @__PURE__ */ React15__namespace.default.createElement(
150
+ /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronLeft, { className: "h-4 w-4 text-muted-foreground" })
151
+ ), /* @__PURE__ */ import_react.default.createElement(
131
152
  Button,
132
153
  {
133
154
  variant: "ghost",
@@ -135,8 +156,8 @@ var CalendarHeader = ({
135
156
  onClick: onNext,
136
157
  className: "rounded-lg h-8 w-8 hover:bg-background/80 transition-all duration-200"
137
158
  },
138
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
139
- )), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "ml-2 md:ml-4" }, /* @__PURE__ */ React15__namespace.default.createElement("h2", { className: "text-lg md:text-xl font-semibold text-foreground whitespace-nowrap capitalize tracking-tight" }, dateFns.format(currentDate, "MMMM yyyy", { locale }))))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2 md:gap-3 w-full md:w-auto justify-end" }, onLanguageChange && language && /* @__PURE__ */ React15__namespace.default.createElement(
159
+ /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
160
+ )), /* @__PURE__ */ import_react.default.createElement("div", { className: "ml-2 md:ml-4" }, /* @__PURE__ */ import_react.default.createElement("h2", { className: "text-lg md:text-xl font-semibold text-foreground whitespace-nowrap capitalize tracking-tight" }, (0, import_date_fns.format)(currentDate, "MMMM yyyy", { locale }))))), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 md:gap-3 w-full md:w-auto justify-end" }, onLanguageChange && language && /* @__PURE__ */ import_react.default.createElement(
140
161
  Button,
141
162
  {
142
163
  variant: "ghost",
@@ -145,7 +166,7 @@ var CalendarHeader = ({
145
166
  className: "h-9 px-3 rounded-xl text-xs font-semibold text-muted-foreground hover:text-foreground hover:bg-accent/80 transition-all duration-200 uppercase tracking-wider"
146
167
  },
147
168
  language
148
- ), onThemeToggle && /* @__PURE__ */ React15__namespace.default.createElement(
169
+ ), onThemeToggle && /* @__PURE__ */ import_react.default.createElement(
149
170
  Button,
150
171
  {
151
172
  variant: "ghost",
@@ -153,8 +174,8 @@ var CalendarHeader = ({
153
174
  className: "rounded-xl h-9 w-9 hover:bg-accent/80 transition-all duration-200",
154
175
  onClick: onThemeToggle
155
176
  },
156
- isDarkMode ? /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Sun, { className: "h-4 w-4 text-amber-500" }) : /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Moon, { className: "h-4 w-4 text-muted-foreground" })
157
- ), !hideViewSwitcher && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center bg-muted/50 backdrop-blur-sm rounded-xl p-1" }, viewConfig.map(({ key, icon: Icon }) => /* @__PURE__ */ React15__namespace.default.createElement(
177
+ isDarkMode ? /* @__PURE__ */ import_react.default.createElement(import_lucide_react.Sun, { className: "h-4 w-4 text-amber-500" }) : /* @__PURE__ */ import_react.default.createElement(import_lucide_react.Moon, { className: "h-4 w-4 text-muted-foreground" })
178
+ ), !hideViewSwitcher && /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center bg-muted/50 backdrop-blur-sm rounded-xl p-1" }, viewConfig.map(({ key, icon: Icon }) => /* @__PURE__ */ import_react.default.createElement(
158
179
  Button,
159
180
  {
160
181
  key,
@@ -166,24 +187,40 @@ var CalendarHeader = ({
166
187
  view === key ? "bg-background shadow-sm text-foreground font-medium border-[0.5px] border-border/50" : "text-muted-foreground hover:text-foreground hover:bg-background/50"
167
188
  )
168
189
  },
169
- /* @__PURE__ */ React15__namespace.default.createElement(Icon, { className: "h-3.5 w-3.5" }),
170
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "hidden sm:inline" }, translations[key])
190
+ /* @__PURE__ */ import_react.default.createElement(Icon, { className: "h-3.5 w-3.5" }),
191
+ /* @__PURE__ */ import_react.default.createElement("span", { className: "hidden sm:inline" }, translations[key])
171
192
  )))));
172
193
  };
173
- var getMonthGrid = (date, weekStartOn = 0) => {
174
- const monthStart = dateFns.startOfMonth(date);
175
- const monthEnd = dateFns.endOfMonth(monthStart);
176
- const startDate = dateFns.startOfWeek(monthStart, { weekStartsOn: weekStartOn });
177
- const endDate = dateFns.endOfWeek(monthEnd, { weekStartsOn: weekStartOn });
178
- return dateFns.eachDayOfInterval({
179
- start: startDate,
180
- end: endDate
194
+
195
+ // src/components/Sidebar.tsx
196
+ var import_react3 = __toESM(require("react"));
197
+ var import_lucide_react3 = require("lucide-react");
198
+
199
+ // src/components/MiniCalendar.tsx
200
+ var import_react2 = __toESM(require("react"));
201
+ var import_date_fns3 = require("date-fns");
202
+
203
+ // src/core/week.ts
204
+ var import_date_fns2 = require("date-fns");
205
+ function resolveWeekStartsOn(locale, fallback) {
206
+ return locale?.options?.weekStartsOn ?? fallback;
207
+ }
208
+ function getWeekDays(date, weekStartsOn) {
209
+ return (0, import_date_fns2.eachDayOfInterval)({
210
+ start: (0, import_date_fns2.startOfWeek)(date, { weekStartsOn }),
211
+ end: (0, import_date_fns2.endOfWeek)(date, { weekStartsOn })
181
212
  });
182
- };
183
- var uses24HourClock = (locale) => {
184
- if (!locale) return false;
185
- return !/[ap]\.?m/i.test(dateFns.format(new Date(2e3, 0, 1, 13, 0), "p", { locale }));
186
- };
213
+ }
214
+ function getMonthGrid(date, weekStartsOn) {
215
+ const monthStart = (0, import_date_fns2.startOfMonth)(date);
216
+ return (0, import_date_fns2.eachDayOfInterval)({
217
+ start: (0, import_date_fns2.startOfWeek)(monthStart, { weekStartsOn }),
218
+ end: (0, import_date_fns2.endOfWeek)((0, import_date_fns2.endOfMonth)(monthStart), { weekStartsOn })
219
+ });
220
+ }
221
+
222
+ // src/components/MiniCalendar.tsx
223
+ var import_lucide_react2 = require("lucide-react");
187
224
  var MiniCalendar = ({
188
225
  currentDate,
189
226
  onDateChange,
@@ -191,12 +228,12 @@ var MiniCalendar = ({
191
228
  className,
192
229
  locale
193
230
  }) => {
194
- const [viewDate, setViewDate] = React15__namespace.default.useState(currentDate);
195
- React15__namespace.default.useEffect(() => {
231
+ const [viewDate, setViewDate] = import_react2.default.useState(currentDate);
232
+ import_react2.default.useEffect(() => {
196
233
  setViewDate(currentDate);
197
234
  }, [currentDate]);
198
- const weekStartsOn = locale?.options?.weekStartsOn ?? 0;
199
- const days = React15__namespace.default.useMemo(
235
+ const weekStartsOn = resolveWeekStartsOn(locale, 0);
236
+ const days = import_react2.default.useMemo(
200
237
  () => getMonthGrid(viewDate, weekStartsOn),
201
238
  [viewDate, weekStartsOn]
202
239
  );
@@ -205,13 +242,13 @@ var MiniCalendar = ({
205
242
  return locale.localize.day(dayIndex, { width: "narrow" });
206
243
  }) : ["S", "M", "T", "W", "T", "F", "S"];
207
244
  const handlePrev = () => {
208
- const newDate = dateFns.subMonths(viewDate, 1);
245
+ const newDate = (0, import_date_fns3.subMonths)(viewDate, 1);
209
246
  setViewDate(newDate);
210
247
  onDateChange(newDate);
211
248
  if (onViewChange) onViewChange("month");
212
249
  };
213
250
  const handleNext = () => {
214
- const newDate = dateFns.addMonths(viewDate, 1);
251
+ const newDate = (0, import_date_fns3.addMonths)(viewDate, 1);
215
252
  setViewDate(newDate);
216
253
  onDateChange(newDate);
217
254
  if (onViewChange) onViewChange("month");
@@ -220,7 +257,7 @@ var MiniCalendar = ({
220
257
  onDateChange(day);
221
258
  if (onViewChange) onViewChange("day");
222
259
  };
223
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { className: cn("px-4 w-[260px]", className) }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center justify-between mb-4" }, /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm font-semibold text-foreground capitalize" }, dateFns.format(viewDate, "MMMM yyyy", { locale })), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center bg-muted/40 rounded-lg p-0.5" }, /* @__PURE__ */ React15__namespace.default.createElement(
260
+ return /* @__PURE__ */ import_react2.default.createElement("div", { className: cn("px-4 w-[260px]", className) }, /* @__PURE__ */ import_react2.default.createElement("div", { className: "flex items-center justify-between mb-4" }, /* @__PURE__ */ import_react2.default.createElement("span", { className: "text-sm font-semibold text-foreground capitalize" }, (0, import_date_fns3.format)(viewDate, "MMMM yyyy", { locale })), /* @__PURE__ */ import_react2.default.createElement("div", { className: "flex items-center bg-muted/40 rounded-lg p-0.5" }, /* @__PURE__ */ import_react2.default.createElement(
224
261
  Button,
225
262
  {
226
263
  variant: "ghost",
@@ -229,8 +266,8 @@ var MiniCalendar = ({
229
266
  onClick: handlePrev,
230
267
  "aria-label": "Previous month"
231
268
  },
232
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.ChevronLeft, { className: "h-4 w-4" })
233
- ), /* @__PURE__ */ React15__namespace.default.createElement(
269
+ /* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.ChevronLeft, { className: "h-4 w-4" })
270
+ ), /* @__PURE__ */ import_react2.default.createElement(
234
271
  Button,
235
272
  {
236
273
  variant: "ghost",
@@ -239,12 +276,12 @@ var MiniCalendar = ({
239
276
  onClick: handleNext,
240
277
  "aria-label": "Next month"
241
278
  },
242
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.ChevronRight, { className: "h-4 w-4" })
243
- ))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "grid grid-cols-7 gap-y-2 text-center mb-2" }, weekDays.map((day, i) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: `${day}-${i}`, className: "text-[10px] text-muted-foreground/70 font-semibold uppercase" }, day))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "grid grid-cols-7 gap-y-1 text-center" }, days.map((day) => {
244
- const isSelected = dateFns.isSameDay(day, currentDate);
245
- const isCurrentMonth = dateFns.isSameMonth(day, viewDate);
246
- const isTodayDate = dateFns.isToday(day);
247
- return /* @__PURE__ */ React15__namespace.default.createElement(
279
+ /* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.ChevronRight, { className: "h-4 w-4" })
280
+ ))), /* @__PURE__ */ import_react2.default.createElement("div", { className: "grid grid-cols-7 gap-y-2 text-center mb-2" }, weekDays.map((day, i) => /* @__PURE__ */ import_react2.default.createElement("div", { key: `${day}-${i}`, className: "text-[10px] text-muted-foreground/70 font-semibold uppercase" }, day))), /* @__PURE__ */ import_react2.default.createElement("div", { className: "grid grid-cols-7 gap-y-1 text-center" }, days.map((day) => {
281
+ const isSelected = (0, import_date_fns3.isSameDay)(day, currentDate);
282
+ const isCurrentMonth = (0, import_date_fns3.isSameMonth)(day, viewDate);
283
+ const isTodayDate = (0, import_date_fns3.isToday)(day);
284
+ return /* @__PURE__ */ import_react2.default.createElement(
248
285
  "button",
249
286
  {
250
287
  key: day.toISOString(),
@@ -257,10 +294,202 @@ var MiniCalendar = ({
257
294
  !isSelected && isTodayDate && "bg-primary/10 text-primary ring-1 ring-primary/30"
258
295
  )
259
296
  },
260
- dateFns.format(day, "d")
297
+ (0, import_date_fns3.format)(day, "d")
261
298
  );
262
299
  })));
263
300
  };
301
+
302
+ // src/components/Sidebar.tsx
303
+ var import_date_fns_tz = require("date-fns-tz");
304
+ var import_date_fns5 = require("date-fns");
305
+
306
+ // src/core/format.ts
307
+ var import_date_fns4 = require("date-fns");
308
+
309
+ // src/locales/index.ts
310
+ var en = {
311
+ today: "Today",
312
+ month: "Month",
313
+ week: "Week",
314
+ day: "Day",
315
+ agenda: "Agenda",
316
+ resource: "Resources",
317
+ createEvent: "Create Event",
318
+ editEvent: "Edit Event",
319
+ delete: "Delete",
320
+ save: "Save",
321
+ cancel: "Cancel",
322
+ title: "Add title",
323
+ start: "Start",
324
+ end: "End",
325
+ allDay: "All Day",
326
+ description: "Description",
327
+ repeat: "Repeat",
328
+ noRepeat: "Does not repeat",
329
+ selectCalendar: "Select Calendar",
330
+ selectType: "Select Type",
331
+ daily: "Daily",
332
+ weekly: "Weekly",
333
+ monthly: "Monthly",
334
+ yearly: "Yearly",
335
+ search: "Search events...",
336
+ allTypes: "All Types",
337
+ timezone: "Time zone",
338
+ localTime: "Local Time",
339
+ create: "Create",
340
+ calendars: "Calendars",
341
+ event: "Event",
342
+ task: "Task",
343
+ appointmentSchedule: "Appointment schedule",
344
+ new: "New",
345
+ dateAndTime: "Date & Time",
346
+ whosJoining: "Who's joining?",
347
+ suggestedTimes: "Suggested times for guests",
348
+ viewSuggestions: "View suggestions",
349
+ whereWillItBe: "Where will it be?",
350
+ location: "Enter address",
351
+ descriptionAndAttachments: "Description",
352
+ dragAndDrop: "Drag & drop files or",
353
+ guests: "Guests",
354
+ addGuests: "Add guests",
355
+ addAttachment: "Upload files",
356
+ moreOptions: "More options",
357
+ doesNotRepeat: "Does not repeat",
358
+ locationHelpText: 'Enter a physical address (e.g. "123 Main St") to generate the map.',
359
+ notes: "Notes...",
360
+ guestCount: "guest",
361
+ guestsCount: "guests",
362
+ repeatFor: "Repeat for",
363
+ times: "times",
364
+ until: "Until",
365
+ endRepeat: "End repeat",
366
+ never: "Never",
367
+ afterOccurrences: "After occurrences",
368
+ onDate: "On date",
369
+ tomorrow: "Tomorrow",
370
+ edit: "Edit",
371
+ duplicate: "Duplicate",
372
+ eventSingular: "event",
373
+ eventPlural: "events",
374
+ allCaughtUp: "All caught up!",
375
+ noEventsScheduled: "No events scheduled",
376
+ noUpcoming: "Your schedule is clear",
377
+ noUpcomingHint: "No upcoming events to show. Create a new event to start planning."
378
+ };
379
+ var fr = {
380
+ today: "Aujourd'hui",
381
+ month: "Mois",
382
+ week: "Semaine",
383
+ day: "Jour",
384
+ agenda: "Agenda",
385
+ resource: "Ressources",
386
+ createEvent: "Cr\xE9er un \xE9v\xE9nement",
387
+ editEvent: "Modifier l'\xE9v\xE9nement",
388
+ delete: "Supprimer",
389
+ save: "Enregistrer",
390
+ cancel: "Annuler",
391
+ title: "Ajouter un titre",
392
+ start: "D\xE9but",
393
+ end: "Fin",
394
+ allDay: "Toute la journ\xE9e",
395
+ description: "Description",
396
+ repeat: "R\xE9p\xE9ter",
397
+ noRepeat: "Ne se r\xE9p\xE8te pas",
398
+ selectCalendar: "S\xE9lectionner un calendrier",
399
+ selectType: "S\xE9lectionner un type",
400
+ daily: "Quotidien",
401
+ weekly: "Hebdomadaire",
402
+ monthly: "Mensuel",
403
+ yearly: "Annuel",
404
+ search: "Rechercher...",
405
+ allTypes: "Tous les types",
406
+ timezone: "Fuseau horaire",
407
+ localTime: "Heure locale",
408
+ create: "Cr\xE9er",
409
+ calendars: "Calendriers",
410
+ event: "\xC9v\xE9nement",
411
+ task: "T\xE2che",
412
+ appointmentSchedule: "Planning de rendez-vous",
413
+ new: "Nouveau",
414
+ dateAndTime: "Date et heure",
415
+ whosJoining: "Qui participe ?",
416
+ suggestedTimes: "Horaires sugg\xE9r\xE9s",
417
+ viewSuggestions: "Voir les suggestions",
418
+ whereWillItBe: "O\xF9 aura lieu ?",
419
+ location: "Entrer une adresse",
420
+ descriptionAndAttachments: "Description",
421
+ dragAndDrop: "Glisser-d\xE9poser des fichiers ou",
422
+ guests: "Invit\xE9s",
423
+ addGuests: "Ajouter des invit\xE9s",
424
+ addAttachment: "T\xE9l\xE9charger des fichiers",
425
+ moreOptions: "Plus d'options",
426
+ doesNotRepeat: "Ne se r\xE9p\xE8te pas",
427
+ locationHelpText: 'Entrez une adresse physique (ex: "123 Rue Principale") pour g\xE9n\xE9rer la carte.',
428
+ notes: "Notes...",
429
+ guestCount: "invit\xE9",
430
+ guestsCount: "invit\xE9s",
431
+ repeatFor: "R\xE9p\xE9ter pendant",
432
+ times: "fois",
433
+ until: "Jusqu'au",
434
+ endRepeat: "Fin de r\xE9p\xE9tition",
435
+ never: "Jamais",
436
+ afterOccurrences: "Apr\xE8s occurrences",
437
+ onDate: "\xC0 la date",
438
+ tomorrow: "Demain",
439
+ edit: "Modifier",
440
+ duplicate: "Dupliquer",
441
+ eventSingular: "\xE9v\xE9nement",
442
+ eventPlural: "\xE9v\xE9nements",
443
+ allCaughtUp: "Tout est \xE0 jour !",
444
+ noEventsScheduled: "Aucun \xE9v\xE9nement pr\xE9vu",
445
+ noUpcoming: "Votre planning est libre",
446
+ noUpcomingHint: "Aucun \xE9v\xE9nement \xE0 venir. Cr\xE9ez un nouvel \xE9v\xE9nement pour commencer \xE0 planifier."
447
+ };
448
+
449
+ // src/core/format.ts
450
+ var clockCache = /* @__PURE__ */ new WeakMap();
451
+ function uses24HourClock(locale) {
452
+ if (!locale) return false;
453
+ let is24 = clockCache.get(locale);
454
+ if (is24 === void 0) {
455
+ is24 = !/[ap]\.?m/i.test((0, import_date_fns4.format)(new Date(2e3, 0, 1, 13, 0), "p", { locale }));
456
+ clockCache.set(locale, is24);
457
+ }
458
+ return is24;
459
+ }
460
+ var H24 = { hour: "H:mm", time: "H:mm", compact: "H:mm" };
461
+ var H12 = { hour: "h a", time: "h:mm a", compact: "h:mm" };
462
+ function timeFormats(locale) {
463
+ return uses24HourClock(locale) ? H24 : H12;
464
+ }
465
+ var MAX_FORMATTERS = 50;
466
+ var formatters = /* @__PURE__ */ new Map();
467
+ function getDateTimeFormat(locale, timeZone, options) {
468
+ const key = `${locale}|${timeZone ?? ""}|${JSON.stringify(options)}`;
469
+ let formatter = formatters.get(key);
470
+ if (formatter) {
471
+ formatters.delete(key);
472
+ } else {
473
+ formatter = new Intl.DateTimeFormat(locale, { ...options, timeZone });
474
+ if (formatters.size >= MAX_FORMATTERS) {
475
+ formatters.delete(formatters.keys().next().value);
476
+ }
477
+ }
478
+ formatters.set(key, formatter);
479
+ return formatter;
480
+ }
481
+ function timeZoneAbbreviation(date, timeZone) {
482
+ try {
483
+ return getDateTimeFormat("en-US", timeZone, { timeZoneName: "short" }).formatToParts(date).find((part) => part.type === "timeZoneName")?.value ?? "";
484
+ } catch {
485
+ return "";
486
+ }
487
+ }
488
+ function resolveTranslations(language, overrides) {
489
+ return { ...language === "fr" ? fr : en, ...overrides };
490
+ }
491
+
492
+ // src/components/Sidebar.tsx
264
493
  var Sidebar = ({
265
494
  currentDate,
266
495
  onDateChange,
@@ -275,11 +504,11 @@ var Sidebar = ({
275
504
  translations,
276
505
  locale
277
506
  }) => {
278
- const [calendarsOpen, setCalendarsOpen] = React15.useState(true);
279
- const [timezoneOpen, setTimezoneOpen] = React15.useState(false);
280
- const [now, setNow] = React15.useState(null);
281
- const [hasMounted, setHasMounted] = React15.useState(false);
282
- React15.useEffect(() => {
507
+ const [calendarsOpen, setCalendarsOpen] = (0, import_react3.useState)(true);
508
+ const [timezoneOpen, setTimezoneOpen] = (0, import_react3.useState)(false);
509
+ const [now, setNow] = (0, import_react3.useState)(null);
510
+ const [hasMounted, setHasMounted] = (0, import_react3.useState)(false);
511
+ (0, import_react3.useEffect)(() => {
283
512
  setHasMounted(true);
284
513
  setNow(/* @__PURE__ */ new Date());
285
514
  const timer = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
@@ -291,14 +520,7 @@ var Sidebar = ({
291
520
  { id: "3", label: "Tasks", color: "#6366f1", active: true }
292
521
  ];
293
522
  const displayCalendars = calendars || defaultCalendars;
294
- const getAcronym = (tz) => {
295
- if (!tz || !now) return "LOC";
296
- try {
297
- return new Intl.DateTimeFormat("en-US", { timeZone: tz, timeZoneName: "short" }).formatToParts(now).find((part) => part.type === "timeZoneName")?.value || "";
298
- } catch (e) {
299
- return "";
300
- }
301
- };
523
+ const getAcronym = (tz) => !tz || !now ? "LOC" : timeZoneAbbreviation(now, tz);
302
524
  const timezones = [
303
525
  { value: "", label: translations?.localTime || "Local Time", acronym: "LOC" },
304
526
  { value: "UTC", label: "UTC", acronym: "UTC" },
@@ -316,56 +538,53 @@ var Sidebar = ({
316
538
  ];
317
539
  const formatTzLabel = (tz, showTime = true) => {
318
540
  if (!hasMounted || !now || !showTime) {
319
- return /* @__PURE__ */ React15__namespace.default.createElement("span", null, tz.label);
541
+ return /* @__PURE__ */ import_react3.default.createElement("span", null, tz.label);
320
542
  }
321
543
  let time = "";
322
544
  let acronym = tz.acronym;
323
545
  try {
324
546
  if (!tz.value) {
325
- time = dateFns.format(now, "HH:mm");
326
- try {
327
- acronym = new Intl.DateTimeFormat("en-US", { timeZoneName: "short" }).formatToParts(now).find((part) => part.type === "timeZoneName")?.value || "LOC";
328
- } catch (e) {
329
- }
547
+ time = (0, import_date_fns5.format)(now, "HH:mm");
548
+ acronym = timeZoneAbbreviation(now) || "LOC";
330
549
  } else {
331
- const zDate = dateFnsTz.toZonedTime(now, tz.value);
332
- time = dateFns.format(zDate, "HH:mm");
550
+ const zDate = (0, import_date_fns_tz.toZonedTime)(now, tz.value);
551
+ time = (0, import_date_fns5.format)(zDate, "HH:mm");
333
552
  const dynAcronym = getAcronym(tz.value);
334
553
  if (dynAcronym && !dynAcronym.includes("GMT") && !dynAcronym.includes("Time")) {
335
554
  acronym = dynAcronym;
336
555
  }
337
556
  }
338
- } catch (e) {
339
- return /* @__PURE__ */ React15__namespace.default.createElement("span", null, tz.label);
557
+ } catch {
558
+ return /* @__PURE__ */ import_react3.default.createElement("span", null, tz.label);
340
559
  }
341
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex justify-between w-full" }, /* @__PURE__ */ React15__namespace.default.createElement("span", null, tz.label), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-muted-foreground ml-2 tabular-nums" }, time, " ", /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-xs opacity-75" }, "(", acronym, ")")));
560
+ return /* @__PURE__ */ import_react3.default.createElement("div", { className: "flex justify-between w-full" }, /* @__PURE__ */ import_react3.default.createElement("span", null, tz.label), /* @__PURE__ */ import_react3.default.createElement("span", { className: "text-muted-foreground ml-2 tabular-nums" }, time, " ", /* @__PURE__ */ import_react3.default.createElement("span", { className: "text-xs opacity-75" }, "(", acronym, ")")));
342
561
  };
343
562
  const selectedTzObj = timezones.find((t) => t.value === (timezone || ""));
344
563
  const selectedTimezoneLabel = selectedTzObj ? formatTzLabel(selectedTzObj) : translations?.localTime || "Local Time";
345
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { className: cn("flex flex-col w-[260px] overflow-x-hidden h-full bg-gradient-to-b scrollbar-hide from-background via-background to-muted/10 pt-4 pb-4 overflow-y-auto hidden lg:flex", className) }, !readOnly && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "px-4 mb-6" }, /* @__PURE__ */ React15__namespace.default.createElement(
564
+ return /* @__PURE__ */ import_react3.default.createElement("div", { className: cn("flex flex-col w-[260px] overflow-x-hidden h-full bg-gradient-to-b scrollbar-hide from-background via-background to-muted/10 pt-4 pb-4 overflow-y-auto hidden lg:flex", className) }, !readOnly && /* @__PURE__ */ import_react3.default.createElement("div", { className: "px-4 mb-6" }, /* @__PURE__ */ import_react3.default.createElement(
346
565
  Button,
347
566
  {
348
567
  className: "w-full rounded-2xl shadow-lg bg-primary text-primary-foreground hover:bg-primary/90 h-12 gap-3 justify-center transition-all duration-300 hover:shadow-xl hover:shadow-primary/20 hover:scale-[1.02] active:scale-[0.98] font-semibold",
349
568
  onClick: onEventCreate
350
569
  },
351
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Plus, { className: "w-5 h-5" }),
352
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm" }, translations?.create || "Create")
353
- )), /* @__PURE__ */ React15__namespace.default.createElement(MiniCalendar, { currentDate, onDateChange, onViewChange, locale }), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 px-4 space-y-5 mt-5" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "bg-muted/20 rounded-2xl p-3 border-[0px] border-border/30" }, /* @__PURE__ */ React15__namespace.default.createElement(
570
+ /* @__PURE__ */ import_react3.default.createElement(import_lucide_react3.Plus, { className: "w-5 h-5" }),
571
+ /* @__PURE__ */ import_react3.default.createElement("span", { className: "text-sm" }, translations?.create || "Create")
572
+ )), /* @__PURE__ */ import_react3.default.createElement(MiniCalendar, { currentDate, onDateChange, onViewChange, locale }), /* @__PURE__ */ import_react3.default.createElement("div", { className: "flex-1 px-4 space-y-5 mt-5" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "bg-muted/20 rounded-2xl p-3 border-[0px] border-border/30" }, /* @__PURE__ */ import_react3.default.createElement(
354
573
  "div",
355
574
  {
356
575
  className: "flex items-center justify-between cursor-pointer hover:bg-accent/50 p-2 -m-1 rounded-xl mb-2 transition-all duration-200",
357
576
  onClick: () => setCalendarsOpen(!calendarsOpen)
358
577
  },
359
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm font-semibold text-foreground" }, translations?.calendars || "Calendars"),
360
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.ChevronDown, { className: cn("w-4 h-4 text-muted-foreground transition-transform duration-200", calendarsOpen && "rotate-180") })
361
- ), calendarsOpen && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "space-y-1" }, displayCalendars.map((cal) => /* @__PURE__ */ React15__namespace.default.createElement(
578
+ /* @__PURE__ */ import_react3.default.createElement("span", { className: "text-sm font-semibold text-foreground" }, translations?.calendars || "Calendars"),
579
+ /* @__PURE__ */ import_react3.default.createElement(import_lucide_react3.ChevronDown, { className: cn("w-4 h-4 text-muted-foreground transition-transform duration-200", calendarsOpen && "rotate-180") })
580
+ ), calendarsOpen && /* @__PURE__ */ import_react3.default.createElement("div", { className: "space-y-1" }, displayCalendars.map((cal) => /* @__PURE__ */ import_react3.default.createElement(
362
581
  "div",
363
582
  {
364
583
  key: cal.id,
365
584
  className: "flex items-center gap-3 py-2 px-2 hover:bg-accent/60 rounded-xl cursor-pointer group transition-all duration-200",
366
585
  onClick: () => onCalendarToggle?.(cal.id, !(cal.active ?? true))
367
586
  },
368
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "relative flex items-center justify-center" }, /* @__PURE__ */ React15__namespace.default.createElement(
587
+ /* @__PURE__ */ import_react3.default.createElement("div", { className: "relative flex items-center justify-center" }, /* @__PURE__ */ import_react3.default.createElement(
369
588
  "input",
370
589
  {
371
590
  type: "checkbox",
@@ -378,7 +597,7 @@ var Sidebar = ({
378
597
  style: { "--primary-color": cal.color },
379
598
  "data-cal-id": cal.id
380
599
  }
381
- ), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none opacity-0 peer-checked:opacity-100 transition-opacity" }, /* @__PURE__ */ React15__namespace.default.createElement("svg", { className: "w-3.5 h-3.5 text-white", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 3 }, /* @__PURE__ */ React15__namespace.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }))), /* @__PURE__ */ React15__namespace.default.createElement("style", null, `
600
+ ), /* @__PURE__ */ import_react3.default.createElement("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none opacity-0 peer-checked:opacity-100 transition-opacity" }, /* @__PURE__ */ import_react3.default.createElement("svg", { className: "w-3.5 h-3.5 text-white", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 3 }, /* @__PURE__ */ import_react3.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }))), /* @__PURE__ */ import_react3.default.createElement("style", null, `
382
601
  input[type="checkbox"][data-cal-id="${cal.id}"]:checked {
383
602
  background-color: ${cal.color} !important;
384
603
  border-color: ${cal.color} !important;
@@ -387,23 +606,23 @@ var Sidebar = ({
387
606
  --tw-ring-color: ${cal.color}40 !important;
388
607
  }
389
608
  `)),
390
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2 flex-1 min-w-0" }, /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm text-foreground/90 truncate font-medium" }, cal.label)),
391
- /* @__PURE__ */ React15__namespace.default.createElement(
609
+ /* @__PURE__ */ import_react3.default.createElement("div", { className: "flex items-center gap-2 flex-1 min-w-0" }, /* @__PURE__ */ import_react3.default.createElement("span", { className: "text-sm text-foreground/90 truncate font-medium" }, cal.label)),
610
+ /* @__PURE__ */ import_react3.default.createElement(
392
611
  "div",
393
612
  {
394
613
  className: "w-2 h-2 rounded-full opacity-60 group-hover:opacity-100 transition-opacity",
395
614
  style: { backgroundColor: cal.color }
396
615
  }
397
616
  )
398
- ))))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "mt-auto px-4 pt-5" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "bg-muted/20 rounded-2xl p-3" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2 mb-3" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "p-1.5 bg-primary/10 rounded-lg" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Globe, { className: "w-4 h-4 text-primary" })), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm font-semibold text-foreground" }, translations?.timezone || "Timezone")), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React15__namespace.default.createElement(
617
+ ))))), /* @__PURE__ */ import_react3.default.createElement("div", { className: "mt-auto px-4 pt-5" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "bg-muted/20 rounded-2xl p-3" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "flex items-center gap-2 mb-3" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "p-1.5 bg-primary/10 rounded-lg" }, /* @__PURE__ */ import_react3.default.createElement(import_lucide_react3.Globe, { className: "w-4 h-4 text-primary" })), /* @__PURE__ */ import_react3.default.createElement("span", { className: "text-sm font-semibold text-foreground" }, translations?.timezone || "Timezone")), /* @__PURE__ */ import_react3.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react3.default.createElement(
399
618
  "button",
400
619
  {
401
620
  onClick: () => setTimezoneOpen(!timezoneOpen),
402
621
  className: "w-full flex items-center justify-between bg-blue-200/40 hover:bg-blue-200/80 rounded-xl py-2.5 pl-4 pr-3 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary/50 transition-all duration-200 text-left"
403
622
  },
404
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 truncate mr-2 font-medium" }, selectedTimezoneLabel),
405
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.ChevronDown, { className: cn("w-4 h-4 text-muted-foreground transition-transform duration-200", timezoneOpen && "rotate-180") })
406
- ), timezoneOpen && /* @__PURE__ */ React15__namespace.default.createElement(React15__namespace.default.Fragment, null, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setTimezoneOpen(false) }), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute bottom-full left-0 w-full mb-2 bg-background rounded-xl shadow-2xl z-50 max-h-[260px] overflow-y-auto p-1.5 animate-in fade-in zoom-in-95 duration-200 backdrop-blur-none" }, timezones.map((tz) => /* @__PURE__ */ React15__namespace.default.createElement(
623
+ /* @__PURE__ */ import_react3.default.createElement("div", { className: "flex-1 truncate mr-2 font-medium" }, selectedTimezoneLabel),
624
+ /* @__PURE__ */ import_react3.default.createElement(import_lucide_react3.ChevronDown, { className: cn("w-4 h-4 text-muted-foreground transition-transform duration-200", timezoneOpen && "rotate-180") })
625
+ ), timezoneOpen && /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setTimezoneOpen(false) }), /* @__PURE__ */ import_react3.default.createElement("div", { className: "absolute bottom-full left-0 w-full mb-2 bg-background rounded-xl shadow-2xl z-50 max-h-[260px] overflow-y-auto p-1.5 animate-in fade-in zoom-in-95 duration-200 backdrop-blur-none" }, timezones.map((tz) => /* @__PURE__ */ import_react3.default.createElement(
407
626
  "div",
408
627
  {
409
628
  key: tz.value,
@@ -419,26 +638,202 @@ var Sidebar = ({
419
638
  formatTzLabel(tz)
420
639
  ))))))));
421
640
  };
422
- var DraggableEvent = ({ event, children, className, style: propStyle, ...props }) => {
641
+
642
+ // src/views/MonthView.tsx
643
+ var import_react6 = __toESM(require("react"));
644
+ var import_date_fns8 = require("date-fns");
645
+
646
+ // src/core/events.ts
647
+ var import_date_fns7 = require("date-fns");
648
+
649
+ // src/core/timezone.ts
650
+ var import_date_fns6 = require("date-fns");
651
+ var import_date_fns_tz2 = require("date-fns-tz");
652
+
653
+ // src/core/warn.ts
654
+ var warned = /* @__PURE__ */ new Set();
655
+ function isProductionBuild() {
656
+ try {
657
+ return process.env.NODE_ENV === "production";
658
+ } catch {
659
+ return false;
660
+ }
661
+ }
662
+ function warnOnce(key, message) {
663
+ if (isProductionBuild() || warned.has(key)) return;
664
+ warned.add(key);
665
+ console.warn(`[calendarkit-pro] ${message}`);
666
+ }
667
+
668
+ // src/core/timezone.ts
669
+ var validity = /* @__PURE__ */ new Map();
670
+ function resolveTimeZone(tz) {
671
+ if (!tz) return void 0;
672
+ let valid = validity.get(tz);
673
+ if (valid === void 0) {
674
+ try {
675
+ new Intl.DateTimeFormat("en-US", { timeZone: tz });
676
+ valid = true;
677
+ } catch {
678
+ valid = false;
679
+ }
680
+ validity.set(tz, valid);
681
+ }
682
+ if (!valid) {
683
+ warnOnce(`invalid-timezone:${tz}`, `Unknown timezone "${tz}", falling back to local time.`);
684
+ return void 0;
685
+ }
686
+ return tz;
687
+ }
688
+ function toDisplay(date, tz) {
689
+ const zone = resolveTimeZone(tz);
690
+ return zone ? (0, import_date_fns_tz2.toZonedTime)(date, zone) : date;
691
+ }
692
+ function fromDisplay(wall, tz) {
693
+ const zone = resolveTimeZone(tz);
694
+ return zone ? (0, import_date_fns_tz2.fromZonedTime)(wall, zone) : new Date(wall);
695
+ }
696
+ function minutesSinceDisplayMidnight(date, tz) {
697
+ const wall = toDisplay(date, tz);
698
+ return wall.getHours() * 60 + wall.getMinutes();
699
+ }
700
+ function isSameDisplayDay(date, day, tz) {
701
+ return (0, import_date_fns6.isSameDay)(toDisplay(date, tz), day);
702
+ }
703
+ function displayToday(tz, now = /* @__PURE__ */ new Date()) {
704
+ return (0, import_date_fns6.startOfDay)(toDisplay(now, tz));
705
+ }
706
+
707
+ // src/core/events.ts
708
+ var toDate = (value) => value === void 0 || value === null ? void 0 : value instanceof Date ? value : new Date(value);
709
+ var isValidDate = (date) => !!date && !Number.isNaN(date.getTime());
710
+ var normalizedEvent = /* @__PURE__ */ new WeakMap();
711
+ var normalizedList = /* @__PURE__ */ new WeakMap();
712
+ function normalizeEvent(event) {
713
+ const cached = normalizedEvent.get(event);
714
+ if (cached !== void 0) return cached;
715
+ const start = toDate(event.start);
716
+ const end = toDate(event.end);
717
+ let result = null;
718
+ if (!isValidDate(start) || !isValidDate(end)) {
719
+ warnOnce(`invalid-date:${event.id}`, `Event "${event.id}" has an invalid start or end date and was skipped.`);
720
+ } else if (end.getTime() < start.getTime()) {
721
+ warnOnce(`end-before-start:${event.id}`, `Event "${event.id}" ends before it starts and was skipped.`);
722
+ } else {
723
+ const needsCopy = start !== event.start || end !== event.end || needsRecurrenceCopy(event);
724
+ result = needsCopy ? {
725
+ ...event,
726
+ start,
727
+ end,
728
+ recurrence: event.recurrence && {
729
+ ...event.recurrence,
730
+ until: toDate(event.recurrence.until),
731
+ exdates: event.recurrence.exdates?.map((d) => toDate(d))
732
+ }
733
+ } : event;
734
+ }
735
+ normalizedEvent.set(event, result);
736
+ return result;
737
+ }
738
+ function needsRecurrenceCopy(event) {
739
+ const r = event.recurrence;
740
+ if (!r) return false;
741
+ return r.until !== void 0 && !(r.until instanceof Date) || !!r.exdates?.some((d) => !(d instanceof Date));
742
+ }
743
+ function normalizeEvents(events) {
744
+ const cached = normalizedList.get(events);
745
+ if (cached) return cached;
746
+ const seen = /* @__PURE__ */ new Set();
747
+ const result = [];
748
+ for (const event of events) {
749
+ const normalized = normalizeEvent(event);
750
+ if (!normalized) continue;
751
+ if (seen.has(normalized.id)) {
752
+ warnOnce(`duplicate-id:${normalized.id}`, `Duplicate event id "${normalized.id}": ids must be unique.`);
753
+ }
754
+ seen.add(normalized.id);
755
+ result.push(normalized);
756
+ }
757
+ normalizedList.set(events, result);
758
+ return result;
759
+ }
760
+ var dayKey = (wall) => (0, import_date_fns7.format)(wall, "yyyy-MM-dd");
761
+ function memoByZone(cache, events, tz, compute) {
762
+ let byZone = cache.get(events);
763
+ if (!byZone) {
764
+ byZone = /* @__PURE__ */ new Map();
765
+ cache.set(events, byZone);
766
+ }
767
+ const key = tz ?? "";
768
+ let value = byZone.get(key);
769
+ if (value === void 0) {
770
+ value = compute();
771
+ byZone.set(key, value);
772
+ }
773
+ return value;
774
+ }
775
+ var startDayCache = /* @__PURE__ */ new WeakMap();
776
+ function eventsByStartDay(events, tz) {
777
+ return memoByZone(startDayCache, events, tz, () => {
778
+ const map = /* @__PURE__ */ new Map();
779
+ for (const event of events) {
780
+ const key = dayKey(toDisplay(event.start, tz));
781
+ const bucket = map.get(key);
782
+ if (bucket) bucket.push(event);
783
+ else map.set(key, [event]);
784
+ }
785
+ return map;
786
+ });
787
+ }
788
+ var segmentCache = /* @__PURE__ */ new WeakMap();
789
+ function segmentsByDisplayDay(events, tz, range) {
790
+ const cacheKey = range ? `${tz ?? ""}|${range.start.getTime()}|${range.end.getTime()}` : tz;
791
+ return memoByZone(segmentCache, events, cacheKey, () => {
792
+ const map = /* @__PURE__ */ new Map();
793
+ for (const event of events) {
794
+ const wallStart = toDisplay(event.start, tz);
795
+ const rawEnd = toDisplay(event.end, tz);
796
+ const wallEnd = rawEnd < wallStart ? wallStart : rawEnd;
797
+ if (range && (wallEnd < range.start || wallStart >= range.end)) continue;
798
+ let day = (0, import_date_fns7.startOfDay)(range && wallStart < range.start ? range.start : wallStart);
799
+ const stop = range && wallEnd > range.end ? range.end : wallEnd;
800
+ do {
801
+ const next = (0, import_date_fns7.addDays)(day, 1);
802
+ const start = wallStart > day ? wallStart : day;
803
+ const end = wallEnd < next ? wallEnd : next;
804
+ if (end > start || wallStart.getTime() === wallEnd.getTime()) {
805
+ const key = dayKey(day);
806
+ const bucket = map.get(key);
807
+ const segment = { event, start, end };
808
+ if (bucket) bucket.push(segment);
809
+ else map.set(key, [segment]);
810
+ }
811
+ day = next;
812
+ } while (day < stop);
813
+ }
814
+ return map;
815
+ });
816
+ }
817
+
818
+ // src/components/dnd/DraggableEvent.tsx
819
+ var import_react4 = __toESM(require("react"));
820
+ var import_core = require("@dnd-kit/core");
821
+ var import_utilities = require("@dnd-kit/utilities");
822
+ var DraggableEventImpl = ({ event, dragId, grabOffsetMs, children, className, style: propStyle, ...props }) => {
423
823
  const dragDisabled = isEventDragDisabled(event);
424
- const { attributes, listeners, setNodeRef, transform, isDragging } = core.useDraggable({
425
- id: event.id,
426
- data: { event },
824
+ const { attributes, listeners, setNodeRef, transform, isDragging } = (0, import_core.useDraggable)({
825
+ id: dragId ?? event.id,
826
+ data: { event, grabOffsetMs },
427
827
  disabled: dragDisabled
428
828
  });
429
829
  const style = {
430
830
  ...propStyle,
431
- transform: utilities.CSS.Translate.toString(transform),
831
+ transform: import_utilities.CSS.Translate.toString(transform),
432
832
  zIndex: isDragging ? 100 : propStyle?.zIndex,
433
- // When dragging, we want the ORIGINAL element to be almost invisible (or fully invisible)
434
- // so that the DragOverlay (the "ghost") is the only thing the user focuses on.
435
- // If we set opacity: 0, it disappears. If 0.1, it's a faint placeholder.
436
- // The user asked for "Make the entire dragged item transparent".
437
- // Usually this means the original item should be faded out while the drag overlay is moving.
833
+ // Hide the original while dragging: the DragOverlay ghost is what the user follows.
438
834
  opacity: isDragging ? 0 : propStyle?.opacity
439
- // Hiding original element completely
440
835
  };
441
- return /* @__PURE__ */ React15__namespace.default.createElement(
836
+ return /* @__PURE__ */ import_react4.default.createElement(
442
837
  "div",
443
838
  {
444
839
  ref: setNodeRef,
@@ -451,32 +846,59 @@ var DraggableEvent = ({ event, children, className, style: propStyle, ...props }
451
846
  children
452
847
  );
453
848
  };
454
- var DroppableCell = ({ id, date, resourceId, children, className, style, onClick }) => {
455
- const { isOver, setNodeRef } = core.useDroppable({
849
+ var DraggableEvent = import_react4.default.memo(DraggableEventImpl);
850
+
851
+ // src/components/dnd/DroppableCell.tsx
852
+ var import_react5 = __toESM(require("react"));
853
+ var import_core2 = require("@dnd-kit/core");
854
+ var QUARTER_HOVER = [
855
+ "hover:bg-blue-50/50 dark:hover:bg-blue-900/10",
856
+ "hover:bg-blue-50/80 dark:hover:bg-blue-900/20",
857
+ "hover:bg-blue-100/50 dark:hover:bg-blue-900/30",
858
+ "hover:bg-blue-100/80 dark:hover:bg-blue-900/40"
859
+ ];
860
+ var QUARTER_ACTIVE = [
861
+ "bg-blue-50/50 dark:bg-blue-900/10 ring-2 ring-primary ring-inset",
862
+ "bg-blue-50/80 dark:bg-blue-900/20 ring-2 ring-primary ring-inset",
863
+ "bg-blue-100/50 dark:bg-blue-900/30 ring-2 ring-primary ring-inset",
864
+ "bg-blue-100/80 dark:bg-blue-900/40 ring-2 ring-primary ring-inset"
865
+ ];
866
+ var quarterOf = (date) => Math.min(3, Math.floor(date.getMinutes() / 15));
867
+ var DroppableCellImpl = ({ id, date, resourceId, children, className, style, onClick, onSlotClick }) => {
868
+ const { isOver, setNodeRef } = (0, import_core2.useDroppable)({
456
869
  id,
457
870
  data: { date, resourceId }
458
871
  });
459
- const minutes = date.getMinutes();
460
- const quarterClass = minutes === 0 ? "hover:bg-blue-50/50 dark:hover:bg-blue-900/10" : minutes === 15 ? "hover:bg-blue-50/80 dark:hover:bg-blue-900/20" : minutes === 30 ? "hover:bg-blue-100/50 dark:hover:bg-blue-900/30" : "hover:bg-blue-100/80 dark:hover:bg-blue-900/40";
461
- const activeQuarterClass = minutes === 0 ? "bg-blue-50/50 dark:bg-blue-900/10 ring-2 ring-primary ring-inset" : minutes === 15 ? "bg-blue-50/80 dark:bg-blue-900/20 ring-2 ring-primary ring-inset" : minutes === 30 ? "bg-blue-100/50 dark:bg-blue-900/30 ring-2 ring-primary ring-inset" : "bg-blue-100/80 dark:bg-blue-900/40 ring-2 ring-primary ring-inset";
462
- return /* @__PURE__ */ React15__namespace.default.createElement(
872
+ const quarter = quarterOf(date);
873
+ return /* @__PURE__ */ import_react5.default.createElement(
463
874
  "div",
464
875
  {
465
876
  ref: setNodeRef,
466
877
  className: cn(
467
878
  className,
468
- quarterClass,
469
- isOver && activeQuarterClass
879
+ QUARTER_HOVER[quarter],
880
+ isOver && QUARTER_ACTIVE[quarter],
881
+ onSlotClick && "cursor-pointer"
470
882
  ),
471
883
  style,
472
- onClick
884
+ onClick: onSlotClick ? () => onSlotClick(date, resourceId) : onClick
473
885
  },
474
886
  children
475
887
  );
476
888
  };
889
+ var shallowEqualStyle = (a, b) => {
890
+ if (a === b) return true;
891
+ if (!a || !b) return false;
892
+ const keys = Object.keys(a);
893
+ return keys.length === Object.keys(b).length && keys.every((key) => a[key] === b[key]);
894
+ };
895
+ var DroppableCell = import_react5.default.memo(
896
+ DroppableCellImpl,
897
+ (prev, next) => prev.id === next.id && prev.date.getTime() === next.date.getTime() && prev.resourceId === next.resourceId && prev.children === next.children && prev.className === next.className && prev.onClick === next.onClick && prev.onSlotClick === next.onSlotClick && shallowEqualStyle(prev.style, next.style)
898
+ );
477
899
 
478
900
  // src/views/MonthView.tsx
479
- var EventItem = React15__namespace.default.memo(({ event, onEventClick }) => /* @__PURE__ */ React15__namespace.default.createElement(DraggableEvent, { event }, /* @__PURE__ */ React15__namespace.default.createElement(
901
+ var EventItem = import_react6.default.memo(({ event, onEventClick }) => /* @__PURE__ */ import_react6.default.createElement(DraggableEvent, { event }, /* @__PURE__ */ import_react6.default.createElement(
480
902
  "div",
481
903
  {
482
904
  className: cn(
@@ -494,7 +916,7 @@ var EventItem = React15__namespace.default.memo(({ event, onEventClick }) => /*
494
916
  onEventClick?.(event);
495
917
  }
496
918
  },
497
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "font-medium" }, event.title)
919
+ /* @__PURE__ */ import_react6.default.createElement("span", { className: "font-medium" }, event.title)
498
920
  )));
499
921
  EventItem.displayName = "EventItem";
500
922
  var MonthView = ({
@@ -505,44 +927,24 @@ var MonthView = ({
505
927
  timezone,
506
928
  locale
507
929
  }) => {
508
- const weekStartsOn = locale?.options?.weekStartsOn ?? 1;
509
- const days = React15.useMemo(
510
- () => getMonthGrid(currentDate, weekStartsOn),
511
- [currentDate, weekStartsOn]
512
- );
513
- const weekDays = React15.useMemo(() => {
514
- const start = dateFns.startOfWeek(currentDate, { weekStartsOn });
515
- const end = dateFns.endOfWeek(currentDate, { weekStartsOn });
516
- return dateFns.eachDayOfInterval({ start, end });
517
- }, [currentDate, weekStartsOn]);
518
- const getZonedDate = React15.useCallback((date) => {
519
- return timezone ? dateFnsTz.toZonedTime(date, timezone) : date;
520
- }, [timezone]);
521
- const eventsByDay = React15.useMemo(() => {
522
- const map = /* @__PURE__ */ new Map();
523
- events.forEach((event) => {
524
- const zonedStart = getZonedDate(event.start);
525
- const key = dateFns.format(zonedStart, "yyyy-MM-dd");
526
- if (!map.has(key)) {
527
- map.set(key, []);
528
- }
529
- map.get(key).push(event);
530
- });
531
- return map;
532
- }, [events, getZonedDate]);
533
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col h-full bg-background border-[0.5px] scrollbar-hide border-border/50 rounded-2xl overflow-hidden min-w-[800px] md:min-w-0 shadow-sm" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "overflow-y-auto flex-1 relative" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "grid grid-cols-7 border-b-[0.5px] border-border/50 bg-gradient-to-r from-muted/30 via-muted/40 to-muted/30 sticky top-0 z-20 backdrop-blur-sm" }, weekDays.map((day) => /* @__PURE__ */ React15__namespace.default.createElement(
930
+ const weekStartsOn = resolveWeekStartsOn(locale, 1);
931
+ const days = (0, import_react6.useMemo)(() => getMonthGrid(currentDate, weekStartsOn), [currentDate, weekStartsOn]);
932
+ const weekDays = (0, import_react6.useMemo)(() => getWeekDays(currentDate, weekStartsOn), [currentDate, weekStartsOn]);
933
+ const eventsByDay = eventsByStartDay(events, timezone);
934
+ const today = displayToday(timezone);
935
+ return /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col h-full bg-background border-[0.5px] scrollbar-hide border-border/50 rounded-2xl overflow-hidden min-w-[800px] md:min-w-0 shadow-sm" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "overflow-y-auto flex-1 relative" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "grid grid-cols-7 border-b-[0.5px] border-border/50 bg-gradient-to-r from-muted/30 via-muted/40 to-muted/30 sticky top-0 z-20 backdrop-blur-sm" }, weekDays.map((day) => /* @__PURE__ */ import_react6.default.createElement(
534
936
  "div",
535
937
  {
536
938
  key: day.toISOString(),
537
939
  className: "py-3 text-center text-xs font-semibold text-muted-foreground border-r-[0.5px] border-border/30 last:border-r-0 uppercase tracking-wider"
538
940
  },
539
- dateFns.format(day, "EEE", { locale })
540
- ))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "grid grid-cols-7", style: { gridAutoRows: "130px" } }, days.map((day) => {
541
- const dayKey = dateFns.format(day, "yyyy-MM-dd");
542
- const dayEvents = eventsByDay.get(dayKey) || [];
543
- const isCurrentMonth = dateFns.isSameMonth(day, currentDate);
941
+ (0, import_date_fns8.format)(day, "EEE", { locale })
942
+ ))), /* @__PURE__ */ import_react6.default.createElement("div", { className: "grid grid-cols-7", style: { gridAutoRows: "130px" } }, days.map((day) => {
943
+ const dayKey2 = (0, import_date_fns8.format)(day, "yyyy-MM-dd");
944
+ const dayEvents = eventsByDay.get(dayKey2) || [];
945
+ const isCurrentMonth = (0, import_date_fns8.isSameMonth)(day, currentDate);
544
946
  const cellId = day.toISOString();
545
- return /* @__PURE__ */ React15__namespace.default.createElement(
947
+ return /* @__PURE__ */ import_react6.default.createElement(
546
948
  DroppableCell,
547
949
  {
548
950
  key: cellId,
@@ -551,18 +953,87 @@ var MonthView = ({
551
953
  className: cn(
552
954
  "h-[130px] p-2 border-b-[0.5px] border-r-[0.5px] border-border/30 last:border-r-0 relative transition-all duration-200 hover:bg-accent/5 flex flex-col gap-1.5 overflow-hidden group",
553
955
  !isCurrentMonth && "bg-muted/5 text-muted-foreground/60",
554
- dateFns.isToday(day) && "bg-primary/5 ring-1 ring-inset ring-primary/20"
956
+ (0, import_date_fns8.isSameDay)(day, today) && "bg-primary/5 ring-1 ring-inset ring-primary/20"
555
957
  ),
556
958
  onClick: () => onDateClick?.(day)
557
959
  },
558
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex justify-between items-start" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: cn(
960
+ /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex justify-between items-start" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: cn(
559
961
  "text-sm font-semibold w-7 h-7 flex items-center justify-center rounded-full transition-all duration-200",
560
- dateFns.isToday(day) ? "bg-primary text-primary-foreground shadow-md shadow-primary/30" : "group-hover:bg-accent"
561
- ) }, dateFns.format(day, "d", { locale })), dayEvents.length > 0 && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-[10px] font-medium text-muted-foreground/60 bg-muted/50 px-1.5 py-0.5 rounded-full" }, dayEvents.length)),
562
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 flex flex-col gap-1 scrollbar-hide overflow-y-auto overflow-x-hidden" }, dayEvents.slice(0, 4).map((event) => /* @__PURE__ */ React15__namespace.default.createElement(EventItem, { key: `${event.id}-${dayKey}`, event, onEventClick })), dayEvents.length > 4 && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-[10px] text-primary font-semibold text-center py-1 px-2 rounded-md bg-primary/5 hover:bg-primary/10 cursor-pointer transition-colors" }, "+", dayEvents.length - 4, " more"))
962
+ (0, import_date_fns8.isSameDay)(day, today) ? "bg-primary text-primary-foreground shadow-md shadow-primary/30" : "group-hover:bg-accent"
963
+ ) }, (0, import_date_fns8.format)(day, "d", { locale })), dayEvents.length > 0 && /* @__PURE__ */ import_react6.default.createElement("div", { className: "text-[10px] font-medium text-muted-foreground/60 bg-muted/50 px-1.5 py-0.5 rounded-full" }, dayEvents.length)),
964
+ /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex-1 flex flex-col gap-1 scrollbar-hide overflow-y-auto overflow-x-hidden" }, dayEvents.slice(0, 4).map((event) => /* @__PURE__ */ import_react6.default.createElement(EventItem, { key: `${event.id}-${dayKey2}`, event, onEventClick })), dayEvents.length > 4 && /* @__PURE__ */ import_react6.default.createElement("div", { className: "text-[10px] text-primary font-semibold text-center py-1 px-2 rounded-md bg-primary/5 hover:bg-primary/10 cursor-pointer transition-colors" }, "+", dayEvents.length - 4, " more"))
563
965
  );
564
966
  }))));
565
967
  };
968
+
969
+ // src/views/WeekView.tsx
970
+ var import_react8 = __toESM(require("react"));
971
+ var import_date_fns9 = require("date-fns");
972
+
973
+ // src/core/layout.ts
974
+ var layoutCache = /* @__PURE__ */ new WeakMap();
975
+ function layoutDayEvents(segments) {
976
+ const cached = layoutCache.get(segments);
977
+ if (cached) return cached;
978
+ const sorted = [...segments].sort(
979
+ (a, b) => a.start.getTime() - b.start.getTime() || b.end.getTime() - a.end.getTime() || (a.event.id < b.event.id ? -1 : a.event.id > b.event.id ? 1 : 0)
980
+ );
981
+ const result = [];
982
+ let cluster = [];
983
+ let columnEnds = [];
984
+ let clusterEnd = -Infinity;
985
+ const closeCluster = () => {
986
+ for (const placed of cluster) placed.columns = columnEnds.length;
987
+ cluster = [];
988
+ columnEnds = [];
989
+ };
990
+ for (const segment of sorted) {
991
+ const start = segment.start.getTime();
992
+ const end = Math.max(segment.end.getTime(), start + 1);
993
+ if (start >= clusterEnd) closeCluster();
994
+ let column = columnEnds.findIndex((columnEnd) => columnEnd <= start);
995
+ if (column === -1) {
996
+ column = columnEnds.length;
997
+ columnEnds.push(end);
998
+ } else {
999
+ columnEnds[column] = end;
1000
+ }
1001
+ const placed = { ...segment, column, columns: 1 };
1002
+ cluster.push(placed);
1003
+ result.push(placed);
1004
+ clusterEnd = Math.max(clusterEnd, end);
1005
+ }
1006
+ closeCluster();
1007
+ layoutCache.set(segments, result);
1008
+ return result;
1009
+ }
1010
+
1011
+ // src/components/dnd/ResizableEvent.tsx
1012
+ var import_react7 = __toESM(require("react"));
1013
+
1014
+ // src/core/dnd.ts
1015
+ function computeDrop({ event, overDate, overResourceId, grabOffsetMs = 0, view, tz }) {
1016
+ let wallStart;
1017
+ if (view === "month") {
1018
+ const original = toDisplay(event.start, tz);
1019
+ wallStart = new Date(overDate);
1020
+ wallStart.setHours(original.getHours(), original.getMinutes(), original.getSeconds(), original.getMilliseconds());
1021
+ } else {
1022
+ wallStart = new Date(overDate.getTime() - grabOffsetMs);
1023
+ wallStart.setSeconds(0, 0);
1024
+ }
1025
+ const start = fromDisplay(wallStart, tz);
1026
+ const end = new Date(start.getTime() + (event.end.getTime() - event.start.getTime()));
1027
+ const resourceId = overResourceId ?? event.resourceId;
1028
+ if (start.getTime() === event.start.getTime() && resourceId === event.resourceId) return null;
1029
+ return { start, end, resourceId };
1030
+ }
1031
+ function computeResizeEnd(event, deltaMinutes, minDuration = 15) {
1032
+ const minEnd = event.start.getTime() + minDuration * 6e4;
1033
+ return new Date(Math.max(event.end.getTime() + deltaMinutes * 6e4, minEnd));
1034
+ }
1035
+
1036
+ // src/components/dnd/ResizableEvent.tsx
566
1037
  var ResizableEvent = ({
567
1038
  event,
568
1039
  hourHeight,
@@ -574,13 +1045,13 @@ var ResizableEvent = ({
574
1045
  readonly
575
1046
  }) => {
576
1047
  const resizeLocked = readonly || isEventResizeDisabled(event);
577
- const [isResizing, setIsResizing] = React15.useState(false);
578
- const [resizeHeight, setResizeHeight] = React15.useState(null);
579
- const containerRef = React15.useRef(null);
580
- const startYRef = React15.useRef(0);
581
- const startHeightRef = React15.useRef(0);
582
- const resizeHeightRef = React15.useRef(null);
583
- const handleResizeStart = React15.useCallback((e) => {
1048
+ const [isResizing, setIsResizing] = (0, import_react7.useState)(false);
1049
+ const [resizeHeight, setResizeHeight] = (0, import_react7.useState)(null);
1050
+ const containerRef = (0, import_react7.useRef)(null);
1051
+ const startYRef = (0, import_react7.useRef)(0);
1052
+ const startHeightRef = (0, import_react7.useRef)(0);
1053
+ const resizeHeightRef = (0, import_react7.useRef)(null);
1054
+ const handleResizeStart = (0, import_react7.useCallback)((e) => {
584
1055
  e.preventDefault();
585
1056
  e.stopPropagation();
586
1057
  const clientY = "touches" in e ? e.touches[0].clientY : e.clientY;
@@ -604,14 +1075,8 @@ var ResizableEvent = ({
604
1075
  setIsResizing(false);
605
1076
  const finalHeight = resizeHeightRef.current;
606
1077
  if (finalHeight !== null && containerRef.current && onResize) {
607
- const originalHeight = startHeightRef.current;
608
- const heightDiff = finalHeight - originalHeight;
609
- const minutesDiff = heightDiff / hourHeight * 60;
610
- const newEnd = new Date(event.end);
611
- newEnd.setMinutes(newEnd.getMinutes() + minutesDiff);
612
- if (newEnd > event.start) {
613
- onResize(event, newEnd);
614
- }
1078
+ const minutesDiff = (finalHeight - startHeightRef.current) / hourHeight * 60;
1079
+ onResize(event, computeResizeEnd(event, minutesDiff, minDuration));
615
1080
  }
616
1081
  resizeHeightRef.current = null;
617
1082
  setResizeHeight(null);
@@ -625,10 +1090,10 @@ var ResizableEvent = ({
625
1090
  document.addEventListener("touchmove", handleMove, { passive: false });
626
1091
  document.addEventListener("touchend", handleEnd);
627
1092
  }, [event, hourHeight, minDuration, onResize]);
628
- const handlePointerDown = React15.useCallback((e) => {
1093
+ const handlePointerDown = (0, import_react7.useCallback)((e) => {
629
1094
  e.stopPropagation();
630
1095
  }, []);
631
- return /* @__PURE__ */ React15__namespace.default.createElement(
1096
+ return /* @__PURE__ */ import_react7.default.createElement(
632
1097
  "div",
633
1098
  {
634
1099
  ref: containerRef,
@@ -639,7 +1104,7 @@ var ResizableEvent = ({
639
1104
  }
640
1105
  },
641
1106
  children,
642
- /* @__PURE__ */ React15__namespace.default.createElement(
1107
+ /* @__PURE__ */ import_react7.default.createElement(
643
1108
  "div",
644
1109
  {
645
1110
  className: cn(
@@ -652,17 +1117,26 @@ var ResizableEvent = ({
652
1117
  onMouseDown: resizeLocked ? void 0 : handleResizeStart,
653
1118
  onTouchStart: resizeLocked ? void 0 : handleResizeStart
654
1119
  },
655
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: cn(
1120
+ /* @__PURE__ */ import_react7.default.createElement("div", { className: cn(
656
1121
  "w-8 h-1 rounded-full transition-all",
657
1122
  isResizing ? "bg-primary" : "bg-muted-foreground/30 group-hover:bg-primary/50"
658
1123
  ) })
659
1124
  ),
660
- isResizing && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute inset-0 border-2 border-primary border-dashed rounded-md pointer-events-none bg-primary/5" })
1125
+ isResizing && /* @__PURE__ */ import_react7.default.createElement("div", { className: "absolute inset-0 border-2 border-primary border-dashed rounded-md pointer-events-none bg-primary/5" })
661
1126
  );
662
1127
  };
663
1128
 
664
1129
  // src/views/WeekView.tsx
665
- var WeekView = ({
1130
+ var HOUR_HEIGHT = 60;
1131
+ var HOURS = Array.from({ length: 24 }, (_, i) => i);
1132
+ var QUARTERS = [0, 15, 30, 45];
1133
+ var NO_SEGMENTS = [];
1134
+ var slotDate = (day, hour, minute) => {
1135
+ const date = new Date(day);
1136
+ date.setHours(hour, minute, 0, 0);
1137
+ return date;
1138
+ };
1139
+ var WeekViewImpl = ({
666
1140
  currentDate,
667
1141
  events,
668
1142
  onEventClick,
@@ -672,151 +1146,110 @@ var WeekView = ({
672
1146
  locale,
673
1147
  readonly
674
1148
  }) => {
675
- const weekStartsOn = locale?.options?.weekStartsOn ?? 1;
676
- const start = dateFns.startOfWeek(currentDate, { weekStartsOn });
677
- const end = dateFns.endOfWeek(currentDate, { weekStartsOn });
678
- const weekDays = dateFns.eachDayOfInterval({ start, end });
679
- const hours = Array.from({ length: 24 }, (_, i) => i);
680
- const hourHeight = 60;
681
- const scrollContainerRef = React15__namespace.default.useRef(null);
682
- const [now, setNow] = React15__namespace.default.useState(/* @__PURE__ */ new Date());
683
- React15__namespace.default.useEffect(() => {
1149
+ const weekDays = import_react8.default.useMemo(
1150
+ () => getWeekDays(currentDate, resolveWeekStartsOn(locale, 1)),
1151
+ [currentDate, locale]
1152
+ );
1153
+ const visibleRange = import_react8.default.useMemo(
1154
+ () => ({ start: weekDays[0], end: (0, import_date_fns9.addDays)(weekDays[weekDays.length - 1], 1) }),
1155
+ [weekDays]
1156
+ );
1157
+ const scrollContainerRef = import_react8.default.useRef(null);
1158
+ const [now, setNow] = import_react8.default.useState(() => /* @__PURE__ */ new Date());
1159
+ import_react8.default.useEffect(() => {
684
1160
  const interval = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
685
1161
  return () => clearInterval(interval);
686
1162
  }, []);
687
- React15__namespace.default.useEffect(() => {
1163
+ import_react8.default.useEffect(() => {
688
1164
  if (scrollContainerRef.current) {
689
- const scrollToActualTime = () => {
690
- const currentHour = now.getHours();
691
- const offsetHour = 4;
692
- return (currentHour - offsetHour) * hourHeight;
693
- };
694
- scrollContainerRef.current.scrollTop = scrollToActualTime();
1165
+ const offsetHour = 4;
1166
+ scrollContainerRef.current.scrollTop = (toDisplay(/* @__PURE__ */ new Date(), timezone).getHours() - offsetHour) * HOUR_HEIGHT;
695
1167
  }
696
- }, []);
697
- const getZonedDate = (date) => {
698
- return timezone ? dateFnsTz.toZonedTime(date, timezone) : date;
699
- };
700
- const zonedNow = getZonedDate(/* @__PURE__ */ new Date());
701
- const getTimezoneDisplay = (tz) => {
702
- const date = now;
703
- let displayTime = "";
704
- let acronym = "";
705
- if (!tz) {
706
- displayTime = dateFns.format(date, "HH:mm");
707
- try {
708
- acronym = new Intl.DateTimeFormat("en-US", { timeZoneName: "short" }).formatToParts(date).find((part) => part.type === "timeZoneName")?.value || "";
709
- } catch (e) {
710
- acronym = "LOC";
711
- }
712
- } else {
713
- try {
714
- const zDate = dateFnsTz.toZonedTime(date, tz);
715
- displayTime = dateFns.format(zDate, "HH:mm");
716
- acronym = new Intl.DateTimeFormat("en-US", { timeZone: tz, timeZoneName: "short" }).formatToParts(date).find((part) => part.type === "timeZoneName")?.value || "";
717
- } catch (e) {
718
- displayTime = dateFns.format(date, "HH:mm");
719
- acronym = tz;
720
- }
721
- }
722
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col items-center justify-center leading-tight" }, /* @__PURE__ */ React15__namespace.default.createElement("span", null, displayTime), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-[10px] opacity-75" }, "(", acronym, ")"));
723
- };
724
- const is24h = uses24HourClock(locale);
725
- const timeFormat = is24h ? "H:mm" : "h a";
726
- const eventTimeFormat = is24h ? "H:mm" : "h:mm a";
727
- const nowFormat = is24h ? "H:mm" : "h:mm";
728
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col h-full bg-background border-[0.5px] border-border/50 rounded-2xl overflow-hidden min-w-[800px] md:min-w-0 shadow-sm" }, /* @__PURE__ */ React15__namespace.default.createElement(
1168
+ }, [timezone]);
1169
+ const segmentsByDay = segmentsByDisplayDay(events, timezone, visibleRange);
1170
+ const today = displayToday(timezone, now);
1171
+ const zonedNow = toDisplay(now, timezone);
1172
+ const nowTop = minutesSinceDisplayMidnight(now, timezone) / 60 * HOUR_HEIGHT;
1173
+ const showsToday = weekDays.some((day) => (0, import_date_fns9.isSameDay)(day, today));
1174
+ const zone = resolveTimeZone(timezone);
1175
+ const zoneLabel = timeZoneAbbreviation(now, zone) || zone || "LOC";
1176
+ const formats = timeFormats(locale);
1177
+ return /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex flex-col h-full bg-background border-[0.5px] border-border/50 rounded-2xl overflow-hidden min-w-[800px] md:min-w-0 shadow-sm" }, /* @__PURE__ */ import_react8.default.createElement(
729
1178
  "div",
730
1179
  {
731
1180
  ref: scrollContainerRef,
732
1181
  className: "flex-1 overflow-y-auto scrollbar-hide relative bg-background scroll-smooth"
733
1182
  },
734
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex border-b-[0.5px] border-border/50 bg-gradient-to-r from-muted/20 via-background to-muted/20 z-20 sticky top-0 backdrop-blur-sm" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-none p-3 text-center text-xs font-semibold text-muted-foreground w-16 flex items-center justify-center border-r-[0.5px] border-border/30 bg-muted/10" }, getTimezoneDisplay(timezone)), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 grid grid-cols-7" }, weekDays.map((day, index) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: day.toISOString(), className: cn("py-3 px-2 text-center", index > 0 && "border-l-[0.5px] border-border/30") }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider mb-1.5" }, dateFns.format(day, "EEE", { locale })), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: cn(
1183
+ /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex border-b-[0.5px] border-border/50 bg-gradient-to-r from-muted/20 via-background to-muted/20 z-20 sticky top-0 backdrop-blur-sm" }, /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex-none p-3 text-center text-xs font-semibold text-muted-foreground w-16 flex items-center justify-center border-r-[0.5px] border-border/30 bg-muted/10" }, /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex flex-col items-center justify-center leading-tight" }, /* @__PURE__ */ import_react8.default.createElement("span", null, (0, import_date_fns9.format)(zonedNow, "HH:mm")), /* @__PURE__ */ import_react8.default.createElement("span", { className: "text-[10px] opacity-75" }, "(", zoneLabel, ")"))), /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex-1 grid grid-cols-7" }, weekDays.map((day, index) => /* @__PURE__ */ import_react8.default.createElement("div", { key: day.toISOString(), className: cn("py-3 px-2 text-center", index > 0 && "border-l-[0.5px] border-border/30") }, /* @__PURE__ */ import_react8.default.createElement("div", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider mb-1.5" }, (0, import_date_fns9.format)(day, "EEE", { locale })), /* @__PURE__ */ import_react8.default.createElement("div", { className: cn(
735
1184
  "w-9 h-9 flex items-center justify-center rounded-xl mx-auto text-sm font-semibold transition-all duration-200",
736
- dateFns.isToday(day) ? "bg-primary text-primary-foreground shadow-lg shadow-primary/30 scale-110" : "text-foreground hover:bg-accent/80"
737
- ) }, dateFns.format(day, "d", { locale })))))),
738
- /* @__PURE__ */ React15__namespace.default.createElement(
1185
+ (0, import_date_fns9.isSameDay)(day, today) ? "bg-primary text-primary-foreground shadow-lg shadow-primary/30 scale-110" : "text-foreground hover:bg-accent/80"
1186
+ ) }, (0, import_date_fns9.format)(day, "d", { locale })))))),
1187
+ /* @__PURE__ */ import_react8.default.createElement(
739
1188
  "div",
740
1189
  {
741
1190
  className: "flex min-w-full relative",
742
- style: { height: hours.length * hourHeight }
1191
+ style: { height: HOURS.length * HOUR_HEIGHT }
743
1192
  },
744
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-none w-16 border-r-[0.5px] border-border/30 relative bg-muted/5" }, hours.map((hour) => /* @__PURE__ */ React15__namespace.default.createElement(
1193
+ /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex-none w-16 border-r-[0.5px] border-border/30 relative bg-muted/5" }, HOURS.map((hour) => /* @__PURE__ */ import_react8.default.createElement(
745
1194
  "div",
746
1195
  {
747
1196
  key: hour,
748
1197
  className: "relative w-full text-[11px] text-muted-foreground/80 text-right pr-3 font-medium tabular-nums box-border",
749
- style: { height: hourHeight }
1198
+ style: { height: HOUR_HEIGHT }
750
1199
  },
751
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "block -translate-y-1/2" }, hour !== 0 && dateFns.format((/* @__PURE__ */ new Date()).setHours(hour, 0, 0, 0), timeFormat, { locale }))
752
- ))),
753
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 grid grid-cols-7 relative" }, weekDays.map((day, dayIndex) => {
754
- const dayEvents = events.filter((e) => {
755
- const zonedStart = getZonedDate(e.start);
756
- return dateFns.isSameDay(zonedStart, day);
757
- });
758
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { key: day.toISOString(), className: cn("relative h-full", dayIndex > 0 && "border-l-[0.5px] border-border/30") }, hours.map((hour) => {
759
- return /* @__PURE__ */ React15__namespace.default.createElement(
760
- "div",
761
- {
762
- key: hour,
763
- className: "w-full border-b-[0.5px] border-dashed border-border/20 box-border relative hover:bg-accent/5 transition-colors",
764
- style: { height: hourHeight }
765
- },
766
- [0, 15, 30, 45].map((minute) => {
767
- const cellDate = new Date(day);
768
- cellDate.setHours(hour, minute, 0, 0);
769
- const cellId = cellDate.toISOString();
770
- return /* @__PURE__ */ React15__namespace.default.createElement(
771
- DroppableCell,
772
- {
773
- key: minute,
774
- id: cellId,
775
- date: cellDate,
776
- className: "w-full absolute left-0 right-0 z-0 transition-colors",
777
- style: {
778
- height: "25%",
779
- top: `${minute / 60 * 100}%`
780
- }
1200
+ /* @__PURE__ */ import_react8.default.createElement("span", { className: "block -translate-y-1/2" }, hour !== 0 && (0, import_date_fns9.format)(slotDate(currentDate, hour, 0), formats.hour, { locale }))
1201
+ )), showsToday && /* @__PURE__ */ import_react8.default.createElement(
1202
+ "div",
1203
+ {
1204
+ className: "absolute left-0 w-full pointer-events-none z-30 flex justify-end pr-2",
1205
+ style: { top: `${nowTop}px` }
1206
+ },
1207
+ /* @__PURE__ */ import_react8.default.createElement("span", { className: "text-[10px] font-bold text-primary-foreground bg-primary px-1.5 py-0.5 rounded-md shadow-md -translate-y-1/2 backdrop-blur-none" }, (0, import_date_fns9.format)(zonedNow, formats.compact, { locale }))
1208
+ )),
1209
+ /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex-1 grid grid-cols-7 relative" }, weekDays.map((day, dayIndex) => {
1210
+ const dayKey2 = (0, import_date_fns9.format)(day, "yyyy-MM-dd");
1211
+ const positioned = layoutDayEvents(segmentsByDay.get(dayKey2) ?? NO_SEGMENTS);
1212
+ return /* @__PURE__ */ import_react8.default.createElement("div", { key: dayKey2, className: cn("relative h-full", dayIndex > 0 && "border-l-[0.5px] border-border/30") }, HOURS.map((hour) => /* @__PURE__ */ import_react8.default.createElement(
1213
+ "div",
1214
+ {
1215
+ key: hour,
1216
+ className: "w-full border-b-[0.5px] border-dashed border-border/20 box-border relative hover:bg-accent/5 transition-colors",
1217
+ style: { height: HOUR_HEIGHT }
1218
+ },
1219
+ QUARTERS.map((minute) => {
1220
+ const cellDate = slotDate(day, hour, minute);
1221
+ return /* @__PURE__ */ import_react8.default.createElement(
1222
+ DroppableCell,
1223
+ {
1224
+ key: minute,
1225
+ id: cellDate.toISOString(),
1226
+ date: cellDate,
1227
+ className: "w-full absolute left-0 right-0 z-0 transition-colors",
1228
+ style: {
1229
+ height: "25%",
1230
+ top: `${minute / 60 * 100}%`
781
1231
  },
782
- /* @__PURE__ */ React15__namespace.default.createElement(
783
- "div",
784
- {
785
- className: "w-full h-full bg-transparent cursor-pointer",
786
- onClick: () => onTimeSlotClick?.(cellDate)
787
- }
788
- )
789
- );
790
- })
791
- );
792
- }), dayEvents.map((event) => {
793
- const overlappingEvents = dayEvents.filter((e) => {
794
- if (e.id === event.id) return false;
795
- const s1 = getZonedDate(event.start).getTime();
796
- const e1 = getZonedDate(event.end).getTime();
797
- const s2 = getZonedDate(e.start).getTime();
798
- const e2 = getZonedDate(e.end).getTime();
799
- return s1 < e2 && e1 > s2;
800
- });
801
- const group = [event, ...overlappingEvents].sort(
802
- (a, b) => getZonedDate(a.start).getTime() - getZonedDate(b.start).getTime() || (a.id > b.id ? 1 : -1)
803
- // stable sort
804
- );
805
- const index = group.findIndex((e) => e.id === event.id);
806
- const count = group.length;
807
- const widthPercent = 100 / count;
808
- const leftPercent = index * widthPercent;
809
- const zonedEventStart = getZonedDate(event.start);
810
- const zonedEventEnd = getZonedDate(event.end);
811
- const startMinutes = zonedEventStart.getHours() * 60 + zonedEventStart.getMinutes();
812
- const durationMinutes = dateFns.differenceInMinutes(zonedEventEnd, zonedEventStart);
813
- const top = startMinutes / 60 * hourHeight;
814
- const height = durationMinutes / 60 * hourHeight;
1232
+ onSlotClick: onTimeSlotClick
1233
+ }
1234
+ );
1235
+ })
1236
+ )), positioned.map(({ event, start, end, column, columns }) => {
1237
+ const widthPercent = 100 / columns;
1238
+ const leftPercent = column * widthPercent;
1239
+ const zonedEventStart = toDisplay(event.start, timezone);
1240
+ const zonedEventEnd = toDisplay(event.end, timezone);
1241
+ const startMinutes = start.getHours() * 60 + start.getMinutes();
1242
+ const durationMinutes = (0, import_date_fns9.differenceInMinutes)(end, start);
1243
+ const top = startMinutes / 60 * HOUR_HEIGHT;
1244
+ const height = durationMinutes / 60 * HOUR_HEIGHT;
815
1245
  const isShortEvent = durationMinutes < 60;
816
- return /* @__PURE__ */ React15__namespace.default.createElement(
1246
+ const isLastSegment = end.getTime() === zonedEventEnd.getTime();
1247
+ return /* @__PURE__ */ import_react8.default.createElement(
817
1248
  DraggableEvent,
818
1249
  {
819
- key: `${event.id}-${day.toISOString()}`,
1250
+ key: `${event.id}-${dayKey2}`,
1251
+ dragId: `${event.id}@${dayKey2}`,
1252
+ grabOffsetMs: start.getTime() - zonedEventStart.getTime(),
820
1253
  event,
821
1254
  className: `absolute z-10 transition-all ${readonly ? "cursor-default" : ""}`,
822
1255
  style: {
@@ -825,20 +1258,20 @@ var WeekView = ({
825
1258
  left: `${leftPercent}%`,
826
1259
  width: `${widthPercent}%`,
827
1260
  // Add minimal spacing between overlapping events
828
- paddingRight: count > 1 ? "2px" : "0"
1261
+ paddingRight: columns > 1 ? "2px" : "0"
829
1262
  }
830
1263
  },
831
- /* @__PURE__ */ React15__namespace.default.createElement(
1264
+ /* @__PURE__ */ import_react8.default.createElement(
832
1265
  ResizableEvent,
833
1266
  {
834
- readonly,
1267
+ readonly: readonly || !isLastSegment,
835
1268
  event,
836
- hourHeight,
1269
+ hourHeight: HOUR_HEIGHT,
837
1270
  onResize: onEventResize,
838
1271
  className: "h-full",
839
1272
  style: { height: "100%" }
840
1273
  },
841
- /* @__PURE__ */ React15__namespace.default.createElement(
1274
+ /* @__PURE__ */ import_react8.default.createElement(
842
1275
  "div",
843
1276
  {
844
1277
  className: cn(
@@ -848,7 +1281,7 @@ var WeekView = ({
848
1281
  !event.color && "border-primary/20 bg-primary/10",
849
1282
  isShortEvent ? "px-1 flex items-center justify-center" : "p-2",
850
1283
  // Add active border for overlapped events to distinguish them
851
- count > 1 && "border-l-4 border-l-primary/50"
1284
+ columns > 1 && "border-l-4 border-l-primary/50"
852
1285
  ),
853
1286
  style: {
854
1287
  height: "100%",
@@ -861,41 +1294,43 @@ var WeekView = ({
861
1294
  e.stopPropagation();
862
1295
  onEventClick?.(event);
863
1296
  },
864
- title: count > 1 ? `${event.title} (${index + 1}/${count})` : void 0
1297
+ title: columns > 1 ? `${event.title} (${column + 1}/${columns})` : void 0
865
1298
  },
866
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col h-full overflow-hidden w-full" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: cn(
1299
+ /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex flex-col h-full overflow-hidden w-full" }, /* @__PURE__ */ import_react8.default.createElement("div", { className: cn(
867
1300
  "font-semibold truncate text-foreground/90 leading-tight",
868
1301
  isShortEvent ? "text-xs text-center" : "text-xs"
869
- ) }, event.title), !isShortEvent && /* @__PURE__ */ React15__namespace.default.createElement(React15__namespace.default.Fragment, null, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-[10px] text-muted-foreground truncate mt-0.5 font-medium leading-tight" }, dateFns.format(zonedEventStart, eventTimeFormat, { locale }), " - ", dateFns.format(zonedEventEnd, eventTimeFormat, { locale })), event.description && height > 50 && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-[10px] text-muted-foreground/80 truncate mt-1 leading-tight opacity-80" }, event.description)), count > 1 && !isShortEvent && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute top-1 right-1 bg-background/80 backdrop-blur-sm rounded-full w-4 h-4 flex items-center justify-center text-[9px] font-bold text-muted-foreground border border-border shadow-sm" }, count))
1302
+ ) }, event.title), !isShortEvent && /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null, /* @__PURE__ */ import_react8.default.createElement("div", { className: "text-[10px] text-muted-foreground truncate mt-0.5 font-medium leading-tight" }, (0, import_date_fns9.format)(zonedEventStart, formats.time, { locale }), " - ", (0, import_date_fns9.format)(zonedEventEnd, formats.time, { locale })), event.description && height > 50 && /* @__PURE__ */ import_react8.default.createElement("div", { className: "text-[10px] text-muted-foreground/80 truncate mt-1 leading-tight opacity-80" }, event.description)), columns > 1 && !isShortEvent && /* @__PURE__ */ import_react8.default.createElement("div", { className: "absolute top-1 right-1 bg-background/80 backdrop-blur-sm rounded-full w-4 h-4 flex items-center justify-center text-[9px] font-bold text-muted-foreground border border-border shadow-sm" }, columns))
870
1303
  )
871
1304
  )
872
1305
  );
873
- }), dateFns.isToday(day) && /* @__PURE__ */ React15__namespace.default.createElement(
1306
+ }), (0, import_date_fns9.isSameDay)(day, today) && /* @__PURE__ */ import_react8.default.createElement(
874
1307
  "div",
875
1308
  {
876
1309
  className: "absolute left-0 right-0 z-20 pointer-events-none flex items-center",
877
- style: {
878
- top: `${(zonedNow.getHours() * 60 + zonedNow.getMinutes()) / 60 * hourHeight}px`
879
- }
1310
+ style: { top: `${nowTop}px` }
880
1311
  },
881
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "h-[2px] w-full bg-gradient-to-r from-primary via-primary to-primary/50" }),
882
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute -left-1.5 w-3 h-3 bg-primary rounded-full shadow-lg shadow-primary/40 ring-2 ring-background animate-pulse" })
1312
+ /* @__PURE__ */ import_react8.default.createElement("div", { className: "h-[2px] w-full bg-gradient-to-r from-primary via-primary to-primary/50" }),
1313
+ /* @__PURE__ */ import_react8.default.createElement("div", { className: "absolute -left-1.5 w-3 h-3 bg-primary rounded-full shadow-lg shadow-primary/40 ring-2 ring-background animate-pulse" })
883
1314
  ));
884
1315
  }))
885
- ),
886
- /* @__PURE__ */ React15__namespace.default.createElement(
887
- "div",
888
- {
889
- className: "absolute left-0 w-16 pointer-events-none z-30 flex justify-end pr-2",
890
- style: {
891
- top: `${(zonedNow.getHours() * 60 + zonedNow.getMinutes()) / 60 * hourHeight + 80}px`
892
- }
893
- },
894
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-[10px] font-bold text-primary-foreground bg-primary px-1.5 py-0.5 rounded-md shadow-md -translate-y-1/2 backdrop-blur-none" }, dateFns.format(zonedNow, nowFormat, { locale }))
895
1316
  )
896
1317
  ));
897
1318
  };
898
- var DayView = ({
1319
+ var WeekView = import_react8.default.memo(WeekViewImpl);
1320
+
1321
+ // src/views/DayView.tsx
1322
+ var import_react9 = __toESM(require("react"));
1323
+ var import_date_fns10 = require("date-fns");
1324
+ var HOUR_HEIGHT2 = 80;
1325
+ var HOURS2 = Array.from({ length: 24 }, (_, i) => i);
1326
+ var QUARTERS2 = [0, 15, 30, 45];
1327
+ var NO_SEGMENTS2 = [];
1328
+ var slotDate2 = (day, hour, minute) => {
1329
+ const date = new Date(day);
1330
+ date.setHours(hour, minute, 0, 0);
1331
+ return date;
1332
+ };
1333
+ var DayViewImpl = ({
899
1334
  currentDate,
900
1335
  events,
901
1336
  onEventClick,
@@ -905,114 +1340,84 @@ var DayView = ({
905
1340
  locale,
906
1341
  readonly
907
1342
  }) => {
908
- const hours = Array.from({ length: 24 }, (_, i) => i);
909
- const hourHeight = 80;
910
- const scrollContainerRef = React15__namespace.default.useRef(null);
911
- const [now, setNow] = React15__namespace.default.useState(/* @__PURE__ */ new Date());
912
- React15__namespace.default.useEffect(() => {
1343
+ const visibleRange = import_react9.default.useMemo(() => {
1344
+ const start = (0, import_date_fns10.startOfDay)(currentDate);
1345
+ return { start, end: (0, import_date_fns10.addDays)(start, 1) };
1346
+ }, [currentDate]);
1347
+ const scrollContainerRef = import_react9.default.useRef(null);
1348
+ const [now, setNow] = import_react9.default.useState(() => /* @__PURE__ */ new Date());
1349
+ import_react9.default.useEffect(() => {
913
1350
  const interval = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
914
1351
  return () => clearInterval(interval);
915
1352
  }, []);
916
- React15__namespace.default.useEffect(() => {
1353
+ import_react9.default.useEffect(() => {
917
1354
  if (scrollContainerRef.current) {
918
- const scrollToActualTime = () => {
919
- const currentHour = now.getHours();
920
- const offsetHour = 3;
921
- return (currentHour - offsetHour) * hourHeight;
922
- };
923
- scrollContainerRef.current.scrollTop = scrollToActualTime();
1355
+ const offsetHour = 3;
1356
+ scrollContainerRef.current.scrollTop = (toDisplay(/* @__PURE__ */ new Date(), timezone).getHours() - offsetHour) * HOUR_HEIGHT2;
924
1357
  }
925
- }, []);
926
- const getZonedDate = (date) => {
927
- return timezone ? dateFnsTz.toZonedTime(date, timezone) : date;
928
- };
929
- const zonedNow = getZonedDate(now);
930
- const dayEvents = events.filter((e) => {
931
- const zonedStart = getZonedDate(e.start);
932
- return dateFns.isSameDay(zonedStart, currentDate);
933
- });
934
- const is24h = uses24HourClock(locale);
935
- const timeFormat = is24h ? "H:mm" : "h a";
936
- const eventTimeFormat = is24h ? "H:mm" : "h:mm a";
937
- const nowFormat = is24h ? "H:mm" : "h:mm a";
938
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col h-full bg-background border-[0.5px] border-border/50 rounded-2xl overflow-hidden shadow-sm" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "px-6 py-4 border-b-[0.5px] border-border/50 bg-gradient-to-r from-muted/20 via-background to-muted/20 text-center shrink-0" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center justify-center gap-3" }, /* @__PURE__ */ React15__namespace.default.createElement("h2", { className: "text-xl font-semibold capitalize text-foreground" }, dateFns.format(currentDate, "EEEE, MMMM d, yyyy", { locale })), dateFns.isToday(currentDate) && /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-xs font-semibold bg-primary text-primary-foreground px-3 py-1 rounded-full shadow-md shadow-primary/20" }, "Today"))), /* @__PURE__ */ React15__namespace.default.createElement("div", { ref: scrollContainerRef, className: "flex-1 overflow-y-auto relative" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex relative", style: { height: hours.length * hourHeight } }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "w-20 bg-muted/5 border-r-[0.5px] border-border/30 relative" }, hours.map((hour) => /* @__PURE__ */ React15__namespace.default.createElement(
1358
+ }, [timezone]);
1359
+ const dayKey2 = (0, import_date_fns10.format)(currentDate, "yyyy-MM-dd");
1360
+ const positioned = layoutDayEvents(segmentsByDisplayDay(events, timezone, visibleRange).get(dayKey2) ?? NO_SEGMENTS2);
1361
+ const isToday2 = (0, import_date_fns10.isSameDay)(currentDate, displayToday(timezone, now));
1362
+ const zonedNow = toDisplay(now, timezone);
1363
+ const nowTop = minutesSinceDisplayMidnight(now, timezone) / 60 * HOUR_HEIGHT2;
1364
+ const formats = timeFormats(locale);
1365
+ return /* @__PURE__ */ import_react9.default.createElement("div", { className: "flex flex-col h-full bg-background border-[0.5px] border-border/50 rounded-2xl overflow-hidden shadow-sm" }, /* @__PURE__ */ import_react9.default.createElement("div", { className: "px-6 py-4 border-b-[0.5px] border-border/50 bg-gradient-to-r from-muted/20 via-background to-muted/20 text-center shrink-0" }, /* @__PURE__ */ import_react9.default.createElement("div", { className: "flex items-center justify-center gap-3" }, /* @__PURE__ */ import_react9.default.createElement("h2", { className: "text-xl font-semibold capitalize text-foreground" }, (0, import_date_fns10.format)(currentDate, "EEEE, MMMM d, yyyy", { locale })), isToday2 && /* @__PURE__ */ import_react9.default.createElement("span", { className: "text-xs font-semibold bg-primary text-primary-foreground px-3 py-1 rounded-full shadow-md shadow-primary/20" }, "Today"))), /* @__PURE__ */ import_react9.default.createElement("div", { ref: scrollContainerRef, className: "flex-1 overflow-y-auto relative" }, /* @__PURE__ */ import_react9.default.createElement("div", { className: "flex relative", style: { height: HOURS2.length * HOUR_HEIGHT2 } }, /* @__PURE__ */ import_react9.default.createElement("div", { className: "w-20 bg-muted/5 border-r-[0.5px] border-border/30 relative" }, HOURS2.map((hour) => /* @__PURE__ */ import_react9.default.createElement(
939
1366
  "div",
940
1367
  {
941
1368
  key: hour,
942
1369
  className: "relative w-full",
943
- style: { height: hourHeight }
1370
+ style: { height: HOUR_HEIGHT2 }
944
1371
  },
945
- hour !== 0 && /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "absolute w-full text-center -top-3 left-1/2 -translate-x-1/2 text-[11px] text-muted-foreground/80 font-medium tabular-nums bg-background px-1.5 py-0.5 rounded-md" }, dateFns.format((/* @__PURE__ */ new Date()).setHours(hour, 0, 0, 0), timeFormat, { locale }))
946
- )), dateFns.isToday(currentDate) && /* @__PURE__ */ React15__namespace.default.createElement(
1372
+ hour !== 0 && /* @__PURE__ */ import_react9.default.createElement("span", { className: "absolute w-full text-center -top-3 left-1/2 -translate-x-1/2 text-[11px] text-muted-foreground/80 font-medium tabular-nums bg-background px-1.5 py-0.5 rounded-md" }, (0, import_date_fns10.format)(slotDate2(currentDate, hour, 0), formats.hour, { locale }))
1373
+ )), isToday2 && /* @__PURE__ */ import_react9.default.createElement(
947
1374
  "div",
948
1375
  {
949
1376
  className: "absolute left-0 w-full pointer-events-none z-30 flex justify-end pr-2",
950
- style: {
951
- top: `${(zonedNow.getHours() * 60 + zonedNow.getMinutes()) / 60 * hourHeight}px`
952
- }
1377
+ style: { top: `${nowTop}px` }
953
1378
  },
954
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-[10px] font-bold text-white bg-primary px-2 py-1 rounded-lg shadow-md shadow-primary/30 -translate-y-1/2" }, dateFns.format(zonedNow, nowFormat, { locale }))
955
- )), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 relative" }, hours.map((hour) => {
956
- return /* @__PURE__ */ React15__namespace.default.createElement(
957
- "div",
958
- {
959
- key: hour,
960
- className: "border-b-[0.5px] border-dashed border-border/20 box-border relative hover:bg-accent/5 transition-colors",
961
- style: { height: hourHeight }
962
- },
963
- [0, 15, 30, 45].map((minute) => {
964
- const cellDate = new Date(currentDate);
965
- cellDate.setHours(hour, minute, 0, 0);
966
- const cellId = cellDate.toISOString();
967
- return /* @__PURE__ */ React15__namespace.default.createElement(
968
- DroppableCell,
969
- {
970
- key: minute,
971
- id: cellId,
972
- date: cellDate,
973
- className: "w-full absolute left-0 right-0 z-0 transition-colors",
974
- style: {
975
- height: "25%",
976
- top: `${minute / 60 * 100}%`
977
- }
1379
+ /* @__PURE__ */ import_react9.default.createElement("span", { className: "text-[10px] font-bold text-white bg-primary px-2 py-1 rounded-lg shadow-md shadow-primary/30 -translate-y-1/2" }, (0, import_date_fns10.format)(zonedNow, formats.time, { locale }))
1380
+ )), /* @__PURE__ */ import_react9.default.createElement("div", { className: "flex-1 relative" }, HOURS2.map((hour) => /* @__PURE__ */ import_react9.default.createElement(
1381
+ "div",
1382
+ {
1383
+ key: hour,
1384
+ className: "border-b-[0.5px] border-dashed border-border/20 box-border relative hover:bg-accent/5 transition-colors",
1385
+ style: { height: HOUR_HEIGHT2 }
1386
+ },
1387
+ QUARTERS2.map((minute) => {
1388
+ const cellDate = slotDate2(currentDate, hour, minute);
1389
+ return /* @__PURE__ */ import_react9.default.createElement(
1390
+ DroppableCell,
1391
+ {
1392
+ key: minute,
1393
+ id: cellDate.toISOString(),
1394
+ date: cellDate,
1395
+ className: "w-full absolute left-0 right-0 z-0 transition-colors",
1396
+ style: {
1397
+ height: "25%",
1398
+ top: `${minute / 60 * 100}%`
978
1399
  },
979
- /* @__PURE__ */ React15__namespace.default.createElement(
980
- "div",
981
- {
982
- className: "h-full w-full bg-transparent cursor-pointer",
983
- onClick: () => onTimeSlotClick?.(cellDate)
984
- }
985
- )
986
- );
987
- })
988
- );
989
- }), dayEvents.map((event) => {
990
- const overlappingEvents = dayEvents.filter((e) => {
991
- if (e.id === event.id) return false;
992
- const s1 = getZonedDate(event.start).getTime();
993
- const e1 = getZonedDate(event.end).getTime();
994
- const s2 = getZonedDate(e.start).getTime();
995
- const e2 = getZonedDate(e.end).getTime();
996
- return s1 < e2 && e1 > s2;
997
- });
998
- const group = [event, ...overlappingEvents].sort(
999
- (a, b) => getZonedDate(a.start).getTime() - getZonedDate(b.start).getTime() || (a.id > b.id ? 1 : -1)
1000
- );
1001
- const index = group.findIndex((e) => e.id === event.id);
1002
- const count = group.length;
1003
- const widthPercent = 100 / count;
1004
- const leftPercent = index * widthPercent;
1005
- const zonedStart = getZonedDate(event.start);
1006
- const zonedEnd = getZonedDate(event.end);
1007
- const startMinutes = zonedStart.getHours() * 60 + zonedStart.getMinutes();
1008
- const durationMinutes = dateFns.differenceInMinutes(zonedEnd, zonedStart);
1009
- const top = startMinutes / 60 * hourHeight;
1010
- const height = durationMinutes / 60 * hourHeight;
1400
+ onSlotClick: onTimeSlotClick
1401
+ }
1402
+ );
1403
+ })
1404
+ )), positioned.map(({ event, start, end, column, columns }) => {
1405
+ const widthPercent = 100 / columns;
1406
+ const leftPercent = column * widthPercent;
1407
+ const zonedStart = toDisplay(event.start, timezone);
1408
+ const zonedEnd = toDisplay(event.end, timezone);
1409
+ const startMinutes = start.getHours() * 60 + start.getMinutes();
1410
+ const durationMinutes = (0, import_date_fns10.differenceInMinutes)(end, start);
1411
+ const top = startMinutes / 60 * HOUR_HEIGHT2;
1412
+ const height = durationMinutes / 60 * HOUR_HEIGHT2;
1011
1413
  const isShortEvent = durationMinutes < 45;
1012
- return /* @__PURE__ */ React15__namespace.default.createElement(
1414
+ const isLastSegment = end.getTime() === zonedEnd.getTime();
1415
+ return /* @__PURE__ */ import_react9.default.createElement(
1013
1416
  DraggableEvent,
1014
1417
  {
1015
- key: `${event.id}-${currentDate.toISOString()}`,
1418
+ key: `${event.id}-${dayKey2}`,
1419
+ dragId: `${event.id}@${dayKey2}`,
1420
+ grabOffsetMs: start.getTime() - zonedStart.getTime(),
1016
1421
  event,
1017
1422
  className: `absolute z-10 transition-all ${readonly ? "cursor-default" : ""}`,
1018
1423
  style: {
@@ -1020,20 +1425,20 @@ var DayView = ({
1020
1425
  height: `${Math.max(height, 28)}px`,
1021
1426
  left: `calc(${leftPercent}% + 4px)`,
1022
1427
  width: `calc(${widthPercent}% - 8px)`,
1023
- paddingRight: count > 1 ? "2px" : "0"
1428
+ paddingRight: columns > 1 ? "2px" : "0"
1024
1429
  }
1025
1430
  },
1026
- /* @__PURE__ */ React15__namespace.default.createElement(
1431
+ /* @__PURE__ */ import_react9.default.createElement(
1027
1432
  ResizableEvent,
1028
1433
  {
1029
- readonly,
1434
+ readonly: readonly || !isLastSegment,
1030
1435
  event,
1031
- hourHeight,
1436
+ hourHeight: HOUR_HEIGHT2,
1032
1437
  onResize: onEventResize,
1033
1438
  className: "h-full",
1034
1439
  style: { height: "100%" }
1035
1440
  },
1036
- /* @__PURE__ */ React15__namespace.default.createElement(
1441
+ /* @__PURE__ */ import_react9.default.createElement(
1037
1442
  "div",
1038
1443
  {
1039
1444
  className: cn(
@@ -1042,61 +1447,72 @@ var DayView = ({
1042
1447
  readonly || isEventDragDisabled(event) ? "cursor-default" : "cursor-grab active:cursor-grabbing",
1043
1448
  !event.color && "bg-primary/10 border-primary/20",
1044
1449
  isShortEvent ? "px-2 flex items-center" : "px-3 py-2",
1045
- count > 1 && "border-l-4"
1450
+ columns > 1 && "border-l-4"
1046
1451
  ),
1047
1452
  style: {
1048
1453
  backgroundColor: event.color ? `${event.color}15` : void 0,
1049
1454
  borderColor: event.color ? `${event.color}30` : void 0,
1050
1455
  borderLeftColor: event.color || "var(--primary)",
1051
- borderLeftWidth: count > 1 ? "4px" : "3px"
1456
+ borderLeftWidth: columns > 1 ? "4px" : "3px"
1052
1457
  },
1053
1458
  onClick: (e) => {
1054
1459
  e.stopPropagation();
1055
1460
  onEventClick?.(event);
1056
1461
  },
1057
- title: count > 1 ? `${event.title} (${index + 1}/${count})` : void 0
1462
+ title: columns > 1 ? `${event.title} (${column + 1}/${columns})` : void 0
1058
1463
  },
1059
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col h-full overflow-hidden w-full" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: cn(
1464
+ /* @__PURE__ */ import_react9.default.createElement("div", { className: "flex flex-col h-full overflow-hidden w-full" }, /* @__PURE__ */ import_react9.default.createElement("div", { className: cn(
1060
1465
  "font-semibold truncate leading-tight",
1061
1466
  isShortEvent ? "text-xs" : "text-sm",
1062
1467
  event.color ? "text-foreground" : "text-foreground/90"
1063
- ) }, event.title), !isShortEvent && /* @__PURE__ */ React15__namespace.default.createElement(React15__namespace.default.Fragment, null, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-xs text-muted-foreground mt-0.5 font-medium" }, dateFns.format(zonedStart, eventTimeFormat, { locale }), " - ", dateFns.format(zonedEnd, eventTimeFormat, { locale })), event.description && height > 60 && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-xs text-muted-foreground/80 mt-1 line-clamp-2" }, event.description)), count > 1 && !isShortEvent && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute top-1.5 right-1.5 bg-background/90 backdrop-blur-sm rounded-full w-5 h-5 flex items-center justify-center text-[10px] font-bold text-muted-foreground border border-border shadow-sm" }, count))
1468
+ ) }, event.title), !isShortEvent && /* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, /* @__PURE__ */ import_react9.default.createElement("div", { className: "text-xs text-muted-foreground mt-0.5 font-medium" }, (0, import_date_fns10.format)(zonedStart, formats.time, { locale }), " - ", (0, import_date_fns10.format)(zonedEnd, formats.time, { locale })), event.description && height > 60 && /* @__PURE__ */ import_react9.default.createElement("div", { className: "text-xs text-muted-foreground/80 mt-1 line-clamp-2" }, event.description)), columns > 1 && !isShortEvent && /* @__PURE__ */ import_react9.default.createElement("div", { className: "absolute top-1.5 right-1.5 bg-background/90 backdrop-blur-sm rounded-full w-5 h-5 flex items-center justify-center text-[10px] font-bold text-muted-foreground border border-border shadow-sm" }, columns))
1064
1469
  )
1065
1470
  )
1066
1471
  );
1067
- }), dateFns.isToday(currentDate) && /* @__PURE__ */ React15__namespace.default.createElement(
1472
+ }), isToday2 && /* @__PURE__ */ import_react9.default.createElement(
1068
1473
  "div",
1069
1474
  {
1070
1475
  className: "absolute left-0 right-0 z-20 pointer-events-none flex items-center",
1071
- style: {
1072
- top: `${(zonedNow.getHours() * 60 + zonedNow.getMinutes()) / 60 * hourHeight}px`
1073
- }
1476
+ style: { top: `${nowTop}px` }
1074
1477
  },
1075
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "h-[2px] w-full bg-gradient-to-r from-primary via-primary to-primary/50" }),
1076
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute -left-1.5 w-3 h-3 bg-primary rounded-full shadow-lg shadow-primary/40 ring-2 ring-background animate-pulse" })
1478
+ /* @__PURE__ */ import_react9.default.createElement("div", { className: "h-[2px] w-full bg-gradient-to-r from-primary via-primary to-primary/50" }),
1479
+ /* @__PURE__ */ import_react9.default.createElement("div", { className: "absolute -left-1.5 w-3 h-3 bg-primary rounded-full shadow-lg shadow-primary/40 ring-2 ring-background animate-pulse" })
1077
1480
  )))));
1078
1481
  };
1079
- var AgendaEmptyState = ({ onCreateEvent, translations }) => /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col items-center justify-center h-full min-h-[400px] py-12" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "relative mb-8" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "p-8 bg-gradient-to-br from-green-50 to-blue-50 dark:from-green-900/10 dark:to-blue-900/10 rounded-3xl border border-border/30" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "w-12 h-12 rounded-2xl bg-green-100 dark:bg-green-900/30 flex items-center justify-center" }, /* @__PURE__ */ React15__namespace.default.createElement("svg", { className: "w-6 h-6 text-green-600 dark:text-green-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2 }, /* @__PURE__ */ React15__namespace.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-left" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "font-medium text-foreground" }, translations?.allCaughtUp || "All caught up!"), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-sm text-muted-foreground" }, translations?.noEventsScheduled || "No events scheduled"))))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-center max-w-sm" }, /* @__PURE__ */ React15__namespace.default.createElement("h3", { className: "text-lg font-semibold text-foreground mb-2" }, translations?.noUpcoming || "Your schedule is clear"), /* @__PURE__ */ React15__namespace.default.createElement("p", { className: "text-sm text-muted-foreground mb-6" }, translations?.noUpcomingHint || "No upcoming events to show. Create a new event to start planning."), onCreateEvent && /* @__PURE__ */ React15__namespace.default.createElement(
1482
+ var DayView = import_react9.default.memo(DayViewImpl);
1483
+
1484
+ // src/views/AgendaView.tsx
1485
+ var import_react11 = __toESM(require("react"));
1486
+ var import_date_fns11 = require("date-fns");
1487
+
1488
+ // src/components/EmptyState.tsx
1489
+ var import_react10 = __toESM(require("react"));
1490
+ var import_lucide_react4 = require("lucide-react");
1491
+ var AgendaEmptyState = ({ onCreateEvent, translations }) => /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex flex-col items-center justify-center h-full min-h-[400px] py-12" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "relative mb-8" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "p-8 bg-gradient-to-br from-green-50 to-blue-50 dark:from-green-900/10 dark:to-blue-900/10 rounded-3xl border border-border/30" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "w-12 h-12 rounded-2xl bg-green-100 dark:bg-green-900/30 flex items-center justify-center" }, /* @__PURE__ */ import_react10.default.createElement("svg", { className: "w-6 h-6 text-green-600 dark:text-green-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2 }, /* @__PURE__ */ import_react10.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }))), /* @__PURE__ */ import_react10.default.createElement("div", { className: "text-left" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "font-medium text-foreground" }, translations?.allCaughtUp || "All caught up!"), /* @__PURE__ */ import_react10.default.createElement("div", { className: "text-sm text-muted-foreground" }, translations?.noEventsScheduled || "No events scheduled"))))), /* @__PURE__ */ import_react10.default.createElement("div", { className: "text-center max-w-sm" }, /* @__PURE__ */ import_react10.default.createElement("h3", { className: "text-lg font-semibold text-foreground mb-2" }, translations?.noUpcoming || "Your schedule is clear"), /* @__PURE__ */ import_react10.default.createElement("p", { className: "text-sm text-muted-foreground mb-6" }, translations?.noUpcomingHint || "No upcoming events to show. Create a new event to start planning."), onCreateEvent && /* @__PURE__ */ import_react10.default.createElement(
1080
1492
  "button",
1081
1493
  {
1082
1494
  onClick: onCreateEvent,
1083
1495
  className: "inline-flex items-center gap-2 px-5 py-2.5 bg-primary text-primary-foreground rounded-xl font-medium text-sm shadow-lg shadow-primary/20 hover:shadow-xl hover:shadow-primary/30 hover:scale-105 active:scale-95 transition-all duration-200"
1084
1496
  },
1085
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Plus, { className: "w-4 h-4" }),
1497
+ /* @__PURE__ */ import_react10.default.createElement(import_lucide_react4.Plus, { className: "w-4 h-4" }),
1086
1498
  translations?.createEvent || "Create Event"
1087
1499
  )));
1500
+
1501
+ // src/views/AgendaView.tsx
1502
+ var import_framer_motion = require("framer-motion");
1503
+ var import_lucide_react5 = require("lucide-react");
1088
1504
  var formatDuration = (start, end) => {
1089
- const minutes = dateFns.differenceInMinutes(end, start);
1505
+ const minutes = (0, import_date_fns11.differenceInMinutes)(end, start);
1090
1506
  if (minutes < 60) return `${minutes}m`;
1091
1507
  const hours = Math.floor(minutes / 60);
1092
1508
  const remainingMinutes = minutes % 60;
1093
1509
  if (remainingMinutes === 0) return `${hours}h`;
1094
1510
  return `${hours}h ${remainingMinutes}m`;
1095
1511
  };
1096
- var getDateLabel = (date, locale, translations) => {
1097
- if (dateFns.isToday(date)) return translations?.today || "Today";
1098
- if (dateFns.isTomorrow(date)) return translations?.tomorrow || "Tomorrow";
1099
- return dateFns.format(date, "EEEE", { locale });
1512
+ var getDateLabel = (date, today, locale, translations) => {
1513
+ if ((0, import_date_fns11.isSameDay)(date, today)) return translations?.today || "Today";
1514
+ if ((0, import_date_fns11.isSameDay)(date, (0, import_date_fns11.addDays)(today, 1))) return translations?.tomorrow || "Tomorrow";
1515
+ return (0, import_date_fns11.format)(date, "EEEE", { locale });
1100
1516
  };
1101
1517
  var AgendaView = ({
1102
1518
  currentDate,
@@ -1104,24 +1520,24 @@ var AgendaView = ({
1104
1520
  onEventClick,
1105
1521
  onCreateEvent,
1106
1522
  locale,
1107
- translations
1523
+ translations,
1524
+ timezone
1108
1525
  }) => {
1109
1526
  const is24h = uses24HourClock(locale);
1110
- const timePattern = is24h ? "H:mm" : "h:mm a";
1111
- const compactTimePattern = is24h ? "H:mm" : "h:mm";
1112
- const groupedEvents = React15.useMemo(() => {
1113
- const startDate = dateFns.startOfDay(currentDate);
1527
+ const { time: timePattern, compact: compactTimePattern } = timeFormats(locale);
1528
+ const today = displayToday(timezone);
1529
+ const groupedEvents = (0, import_react11.useMemo)(() => {
1530
+ const byDay = eventsByStartDay(events, timezone);
1114
1531
  const groups = [];
1115
- const sortedEvents = [...events].sort((a, b) => a.start.getTime() - b.start.getTime());
1116
1532
  for (let i = 0; i < 30; i++) {
1117
- const day = dateFns.addDays(startDate, i);
1118
- const dayEvents = sortedEvents.filter((event) => dateFns.isSameDay(event.start, day));
1119
- if (dayEvents.length > 0) {
1120
- groups.push({ date: day, events: dayEvents });
1533
+ const day = (0, import_date_fns11.addDays)((0, import_date_fns11.startOfDay)(currentDate), i);
1534
+ const dayEvents = byDay.get((0, import_date_fns11.format)(day, "yyyy-MM-dd"));
1535
+ if (dayEvents?.length) {
1536
+ groups.push({ date: day, events: [...dayEvents].sort((a, b) => a.start.getTime() - b.start.getTime()) });
1121
1537
  }
1122
1538
  }
1123
1539
  return groups;
1124
- }, [currentDate, events]);
1540
+ }, [currentDate, events, timezone]);
1125
1541
  const container = {
1126
1542
  hidden: { opacity: 0 },
1127
1543
  show: {
@@ -1135,30 +1551,30 @@ var AgendaView = ({
1135
1551
  hidden: { opacity: 0, x: -20 },
1136
1552
  show: { opacity: 1, x: 0 }
1137
1553
  };
1138
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col h-full bg-background overflow-y-auto" }, groupedEvents.length === 0 ? /* @__PURE__ */ React15__namespace.default.createElement(AgendaEmptyState, { onCreateEvent, translations }) : /* @__PURE__ */ React15__namespace.default.createElement(
1139
- framerMotion.motion.div,
1554
+ return /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex flex-col h-full bg-background overflow-y-auto" }, groupedEvents.length === 0 ? /* @__PURE__ */ import_react11.default.createElement(AgendaEmptyState, { onCreateEvent, translations }) : /* @__PURE__ */ import_react11.default.createElement(
1555
+ import_framer_motion.motion.div,
1140
1556
  {
1141
1557
  className: "max-w-3xl mx-auto w-full pb-10 px-4 md:px-6",
1142
1558
  variants: container,
1143
1559
  initial: "hidden",
1144
1560
  animate: "show"
1145
1561
  },
1146
- groupedEvents.map((group, groupIndex) => /* @__PURE__ */ React15__namespace.default.createElement(
1147
- framerMotion.motion.div,
1562
+ groupedEvents.map((group) => /* @__PURE__ */ import_react11.default.createElement(
1563
+ import_framer_motion.motion.div,
1148
1564
  {
1149
1565
  key: group.date.toISOString(),
1150
1566
  className: "relative",
1151
1567
  variants: item
1152
1568
  },
1153
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "sticky top-0 bg-background/95 backdrop-blur-md py-4 z-10 border-b border-border/50" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: cn(
1569
+ /* @__PURE__ */ import_react11.default.createElement("div", { className: "sticky top-0 bg-background/95 backdrop-blur-md py-4 z-10 border-b border-border/50" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: cn(
1154
1570
  "flex flex-col items-center justify-center w-16 h-16 rounded-2xl transition-all",
1155
- dateFns.isToday(group.date) ? "bg-primary text-primary-foreground shadow-lg shadow-primary/30" : "bg-muted/50 text-foreground"
1156
- ) }, /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-2xl font-bold leading-none" }, dateFns.format(group.date, "d")), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-xs font-medium uppercase tracking-wide opacity-80" }, dateFns.format(group.date, "MMM", { locale }))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React15__namespace.default.createElement("span", { className: cn(
1571
+ (0, import_date_fns11.isSameDay)(group.date, today) ? "bg-primary text-primary-foreground shadow-lg shadow-primary/30" : "bg-muted/50 text-foreground"
1572
+ ) }, /* @__PURE__ */ import_react11.default.createElement("span", { className: "text-2xl font-bold leading-none" }, (0, import_date_fns11.format)(group.date, "d")), /* @__PURE__ */ import_react11.default.createElement("span", { className: "text-xs font-medium uppercase tracking-wide opacity-80" }, (0, import_date_fns11.format)(group.date, "MMM", { locale }))), /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react11.default.createElement("span", { className: cn(
1157
1573
  "text-lg font-semibold",
1158
- dateFns.isToday(group.date) && "text-primary"
1159
- ) }, getDateLabel(group.date, locale, translations)), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm text-muted-foreground" }, group.events.length, " ", group.events.length !== 1 ? translations?.eventPlural || "events" : translations?.eventSingular || "event")))),
1160
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "py-4 space-y-3" }, group.events.map((event, eventIndex) => /* @__PURE__ */ React15__namespace.default.createElement(
1161
- framerMotion.motion.div,
1574
+ (0, import_date_fns11.isSameDay)(group.date, today) && "text-primary"
1575
+ ) }, getDateLabel(group.date, today, locale, translations)), /* @__PURE__ */ import_react11.default.createElement("span", { className: "text-sm text-muted-foreground" }, group.events.length, " ", group.events.length !== 1 ? translations?.eventPlural || "events" : translations?.eventSingular || "event")))),
1576
+ /* @__PURE__ */ import_react11.default.createElement("div", { className: "py-4 space-y-3" }, group.events.map((event) => /* @__PURE__ */ import_react11.default.createElement(
1577
+ import_framer_motion.motion.div,
1162
1578
  {
1163
1579
  key: event.id,
1164
1580
  onClick: () => onEventClick?.(event),
@@ -1171,44 +1587,49 @@ var AgendaView = ({
1171
1587
  whileHover: { scale: 1.01, y: -2 },
1172
1588
  transition: { duration: 0.2 }
1173
1589
  },
1174
- /* @__PURE__ */ React15__namespace.default.createElement(
1590
+ /* @__PURE__ */ import_react11.default.createElement(
1175
1591
  "div",
1176
1592
  {
1177
1593
  className: "absolute left-0 top-3 bottom-3 w-1 rounded-full",
1178
1594
  style: { backgroundColor: event.color || "var(--primary)" }
1179
1595
  }
1180
1596
  ),
1181
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col items-center min-w-[70px] pl-2" }, event.allDay ? /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col items-center" }, /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-xs font-semibold text-muted-foreground bg-muted/80 px-2.5 py-1 rounded-full" }, translations?.allDay || "All Day")) : /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col items-center" }, /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-base font-semibold text-foreground" }, dateFns.format(event.start, compactTimePattern, { locale })), !is24h && /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-xs text-muted-foreground uppercase" }, dateFns.format(event.start, "a")), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "w-px h-3 bg-border my-1" }), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-xs text-muted-foreground/70 font-medium" }, formatDuration(event.start, event.end)))),
1182
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 min-w-0 space-y-2" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-start justify-between gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement("h4", { className: "text-base font-semibold text-foreground group-hover:text-primary transition-colors line-clamp-1" }, event.title), /* @__PURE__ */ React15__namespace.default.createElement(
1597
+ /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex flex-col items-center min-w-[70px] pl-2" }, event.allDay ? /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex flex-col items-center" }, /* @__PURE__ */ import_react11.default.createElement("span", { className: "text-xs font-semibold text-muted-foreground bg-muted/80 px-2.5 py-1 rounded-full" }, translations?.allDay || "All Day")) : /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex flex-col items-center" }, /* @__PURE__ */ import_react11.default.createElement("span", { className: "text-base font-semibold text-foreground" }, (0, import_date_fns11.format)(toDisplay(event.start, timezone), compactTimePattern, { locale })), !is24h && /* @__PURE__ */ import_react11.default.createElement("span", { className: "text-xs text-muted-foreground uppercase" }, (0, import_date_fns11.format)(toDisplay(event.start, timezone), "a")), /* @__PURE__ */ import_react11.default.createElement("div", { className: "w-px h-3 bg-border my-1" }), /* @__PURE__ */ import_react11.default.createElement("span", { className: "text-xs text-muted-foreground/70 font-medium" }, formatDuration(event.start, event.end)))),
1598
+ /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex-1 min-w-0 space-y-2" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex items-start justify-between gap-2" }, /* @__PURE__ */ import_react11.default.createElement("h4", { className: "text-base font-semibold text-foreground group-hover:text-primary transition-colors line-clamp-1" }, event.title), /* @__PURE__ */ import_react11.default.createElement(
1183
1599
  "div",
1184
1600
  {
1185
1601
  className: "w-3 h-3 rounded-full shrink-0 mt-1.5",
1186
1602
  style: { backgroundColor: event.color || "var(--primary)" }
1187
1603
  }
1188
- )), event.description && /* @__PURE__ */ React15__namespace.default.createElement("p", { className: "text-sm text-muted-foreground line-clamp-2 leading-relaxed" }, event.description), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-wrap items-center gap-3 pt-1" }, !event.allDay && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Clock, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ React15__namespace.default.createElement("span", null, dateFns.format(event.start, timePattern, { locale }), " - ", dateFns.format(event.end, timePattern, { locale }))), event.guests && event.guests.length > 0 && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Users, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ React15__namespace.default.createElement("span", null, event.guests.length, " ", event.guests.length !== 1 ? translations?.guestsCount || "guests" : translations?.guestCount || "guest")), event.attachments && event.attachments.length > 0 && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Paperclip, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ React15__namespace.default.createElement("span", null, event.attachments.length)), event.reminders && event.reminders.length > 0 && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Bell, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ React15__namespace.default.createElement("span", null, event.reminders.length)))),
1189
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute right-4 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-opacity" }, /* @__PURE__ */ React15__namespace.default.createElement("svg", { className: "w-5 h-5 text-muted-foreground", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" }, /* @__PURE__ */ React15__namespace.default.createElement("path", { d: "M9 18l6-6-6-6" })))
1604
+ )), event.description && /* @__PURE__ */ import_react11.default.createElement("p", { className: "text-sm text-muted-foreground line-clamp-2 leading-relaxed" }, event.description), /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex flex-wrap items-center gap-3 pt-1" }, !event.allDay && /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ import_react11.default.createElement(import_lucide_react5.Clock, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ import_react11.default.createElement("span", null, (0, import_date_fns11.format)(toDisplay(event.start, timezone), timePattern, { locale }), " - ", (0, import_date_fns11.format)(toDisplay(event.end, timezone), timePattern, { locale }))), event.guests && event.guests.length > 0 && /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ import_react11.default.createElement(import_lucide_react5.Users, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ import_react11.default.createElement("span", null, event.guests.length, " ", event.guests.length !== 1 ? translations?.guestsCount || "guests" : translations?.guestCount || "guest")), event.attachments && event.attachments.length > 0 && /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ import_react11.default.createElement(import_lucide_react5.Paperclip, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ import_react11.default.createElement("span", null, event.attachments.length)), event.reminders && event.reminders.length > 0 && /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ import_react11.default.createElement(import_lucide_react5.Bell, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ import_react11.default.createElement("span", null, event.reminders.length)))),
1605
+ /* @__PURE__ */ import_react11.default.createElement("div", { className: "absolute right-4 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-opacity" }, /* @__PURE__ */ import_react11.default.createElement("svg", { className: "w-5 h-5 text-muted-foreground", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" }, /* @__PURE__ */ import_react11.default.createElement("path", { d: "M9 18l6-6-6-6" })))
1190
1606
  )))
1191
1607
  ))
1192
1608
  ));
1193
1609
  };
1610
+
1611
+ // src/views/ResourceView.tsx
1612
+ var import_react12 = __toESM(require("react"));
1613
+ var import_date_fns12 = require("date-fns");
1194
1614
  var ResourceView = ({
1195
1615
  currentDate,
1196
1616
  events,
1197
1617
  resources,
1198
1618
  onEventClick,
1199
1619
  onTimeSlotClick,
1200
- locale
1620
+ locale,
1621
+ timezone
1201
1622
  }) => {
1202
- const containerRef = React15.useRef(null);
1623
+ const containerRef = (0, import_react12.useRef)(null);
1203
1624
  const hours = Array.from({ length: 24 }, (_, i) => i);
1204
1625
  const hourWidth = 100;
1205
- const timeFormat = uses24HourClock(locale) ? "H:mm" : "h a";
1626
+ const timeFormat = timeFormats(locale).hour;
1206
1627
  const getEventStyle = (event) => {
1207
- const start = new Date(event.start);
1208
- const end = new Date(event.end);
1209
- const dayStart = dateFns.startOfDay(currentDate);
1210
- const startMinutes = dateFns.differenceInMinutes(start, dayStart);
1211
- const durationMinutes = dateFns.differenceInMinutes(end, start);
1628
+ const start = toDisplay(event.start, timezone);
1629
+ const end = toDisplay(event.end, timezone);
1630
+ const dayStart = (0, import_date_fns12.startOfDay)(currentDate);
1631
+ const startMinutes = (0, import_date_fns12.differenceInMinutes)(start, dayStart);
1632
+ const durationMinutes = (0, import_date_fns12.differenceInMinutes)(end, start);
1212
1633
  const left = startMinutes / 60 * hourWidth;
1213
1634
  const width = durationMinutes / 60 * hourWidth;
1214
1635
  return {
@@ -1217,19 +1638,19 @@ var ResourceView = ({
1217
1638
  // Min width for visibility
1218
1639
  };
1219
1640
  };
1220
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col h-full bg-background overflow-hidden" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex border-b border-border bg-muted/20" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "w-48 shrink-0 border-r border-border p-4 font-semibold text-sm bg-background sticky left-0 z-20" }, "Resources"), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex overflow-hidden" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex relative", style: { width: hours.length * hourWidth } }, hours.map((hour) => /* @__PURE__ */ React15__namespace.default.createElement(
1641
+ return /* @__PURE__ */ import_react12.default.createElement("div", { className: "flex flex-col h-full bg-background overflow-hidden" }, /* @__PURE__ */ import_react12.default.createElement("div", { className: "flex border-b border-border bg-muted/20" }, /* @__PURE__ */ import_react12.default.createElement("div", { className: "w-48 shrink-0 border-r border-border p-4 font-semibold text-sm bg-background sticky left-0 z-20" }, "Resources"), /* @__PURE__ */ import_react12.default.createElement("div", { className: "flex overflow-hidden" }, /* @__PURE__ */ import_react12.default.createElement("div", { className: "flex relative", style: { width: hours.length * hourWidth } }, hours.map((hour) => /* @__PURE__ */ import_react12.default.createElement(
1221
1642
  "div",
1222
1643
  {
1223
1644
  key: hour,
1224
1645
  className: "border-r border-border/50 text-xs text-muted-foreground p-2 font-medium shrink-0",
1225
1646
  style: { width: hourWidth }
1226
1647
  },
1227
- dateFns.format((/* @__PURE__ */ new Date()).setHours(hour, 0, 0, 0), timeFormat, { locale })
1228
- ))))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 overflow-auto relative", ref: containerRef }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "min-w-fit" }, resources.map((resource) => {
1648
+ (0, import_date_fns12.format)((/* @__PURE__ */ new Date()).setHours(hour, 0, 0, 0), timeFormat, { locale })
1649
+ ))))), /* @__PURE__ */ import_react12.default.createElement("div", { className: "flex-1 overflow-auto relative", ref: containerRef }, /* @__PURE__ */ import_react12.default.createElement("div", { className: "min-w-fit" }, resources.map((resource) => {
1229
1650
  const resourceEvents = events.filter(
1230
- (e) => e.resourceId === resource.id && dateFns.isSameDay(new Date(e.start), currentDate)
1651
+ (e) => e.resourceId === resource.id && isSameDisplayDay(e.start, currentDate, timezone)
1231
1652
  );
1232
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { key: resource.id, className: "flex border-b border-border min-h-[100px]" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "w-48 shrink-0 border-r border-border p-4 bg-background sticky left-0 z-10 flex items-center gap-3" }, resource.avatar ? /* @__PURE__ */ React15__namespace.default.createElement("img", { src: resource.avatar, alt: resource.label, className: "w-8 h-8 rounded-full object-cover" }) : /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-xs font-bold text-primary" }, resource.label.substring(0, 2).toUpperCase()), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm font-medium" }, resource.label), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-xs text-muted-foreground" }, "ID: ", resource.id))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "relative flex", style: { width: hours.length * hourWidth } }, hours.map((hour) => /* @__PURE__ */ React15__namespace.default.createElement(
1653
+ return /* @__PURE__ */ import_react12.default.createElement("div", { key: resource.id, className: "flex border-b border-border min-h-[100px]" }, /* @__PURE__ */ import_react12.default.createElement("div", { className: "w-48 shrink-0 border-r border-border p-4 bg-background sticky left-0 z-10 flex items-center gap-3" }, resource.avatar ? /* @__PURE__ */ import_react12.default.createElement("img", { src: resource.avatar, alt: resource.label, className: "w-8 h-8 rounded-full object-cover" }) : /* @__PURE__ */ import_react12.default.createElement("div", { className: "w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-xs font-bold text-primary" }, resource.label.substring(0, 2).toUpperCase()), /* @__PURE__ */ import_react12.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react12.default.createElement("span", { className: "text-sm font-medium" }, resource.label), /* @__PURE__ */ import_react12.default.createElement("span", { className: "text-xs text-muted-foreground" }, "ID: ", resource.id))), /* @__PURE__ */ import_react12.default.createElement("div", { className: "relative flex", style: { width: hours.length * hourWidth } }, hours.map((hour) => /* @__PURE__ */ import_react12.default.createElement(
1233
1654
  "div",
1234
1655
  {
1235
1656
  key: hour,
@@ -1237,24 +1658,22 @@ var ResourceView = ({
1237
1658
  style: { width: hourWidth }
1238
1659
  },
1239
1660
  [0, 15, 30, 45].map((minute) => {
1240
- const slotDate = new Date(currentDate);
1241
- slotDate.setHours(hour, minute, 0, 0);
1242
- const slotId = `${resource.id}-${slotDate.toISOString()}`;
1243
- return /* @__PURE__ */ React15__namespace.default.createElement(
1661
+ const slotDate3 = new Date(currentDate);
1662
+ slotDate3.setHours(hour, minute, 0, 0);
1663
+ const slotId = `${resource.id}-${slotDate3.toISOString()}`;
1664
+ return /* @__PURE__ */ import_react12.default.createElement(
1244
1665
  DroppableCell,
1245
1666
  {
1246
1667
  key: minute,
1247
1668
  id: slotId,
1248
- date: slotDate,
1669
+ date: slotDate3,
1249
1670
  resourceId: resource.id,
1250
1671
  className: "h-full flex-1 border-r border-border/10 last:border-border/30 hover:bg-accent/10 transition-colors",
1251
- onClick: () => {
1252
- onTimeSlotClick?.(slotDate, resource.id);
1253
- }
1672
+ onSlotClick: onTimeSlotClick
1254
1673
  }
1255
1674
  );
1256
1675
  })
1257
- )), resourceEvents.map((event) => /* @__PURE__ */ React15__namespace.default.createElement(
1676
+ )), resourceEvents.map((event) => /* @__PURE__ */ import_react12.default.createElement(
1258
1677
  DraggableEvent,
1259
1678
  {
1260
1679
  key: event.id,
@@ -1271,10 +1690,17 @@ var ResourceView = ({
1271
1690
  color: "#fff"
1272
1691
  }
1273
1692
  },
1274
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "truncate" }, event.title)
1693
+ /* @__PURE__ */ import_react12.default.createElement("div", { className: "truncate" }, event.title)
1275
1694
  ))));
1276
1695
  }))));
1277
1696
  };
1697
+
1698
+ // src/components/EventModal.tsx
1699
+ var import_react14 = __toESM(require("react"));
1700
+
1701
+ // src/components/ui/Modal.tsx
1702
+ var import_react13 = __toESM(require("react"));
1703
+ var import_lucide_react6 = require("lucide-react");
1278
1704
  var Modal = ({
1279
1705
  isOpen,
1280
1706
  onClose,
@@ -1283,8 +1709,8 @@ var Modal = ({
1283
1709
  className,
1284
1710
  hideHeader = false
1285
1711
  }) => {
1286
- const overlayRef = React15.useRef(null);
1287
- React15.useEffect(() => {
1712
+ const overlayRef = (0, import_react13.useRef)(null);
1713
+ (0, import_react13.useEffect)(() => {
1288
1714
  const handleEscape = (e) => {
1289
1715
  if (e.key === "Escape") {
1290
1716
  onClose();
@@ -1298,14 +1724,14 @@ var Modal = ({
1298
1724
  };
1299
1725
  }, [isOpen, onClose]);
1300
1726
  if (!isOpen) return null;
1301
- return /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute inset-0 z-50 flex items-center justify-center p-4 bg-black/40 backdrop-blur-md animate-in fade-in duration-300" }, /* @__PURE__ */ React15__namespace.default.createElement(
1727
+ return /* @__PURE__ */ import_react13.default.createElement("div", { className: "absolute inset-0 z-50 flex items-center justify-center p-4 bg-black/40 backdrop-blur-md animate-in fade-in duration-300" }, /* @__PURE__ */ import_react13.default.createElement(
1302
1728
  "div",
1303
1729
  {
1304
1730
  ref: overlayRef,
1305
1731
  className: "absolute inset-0",
1306
1732
  onClick: onClose
1307
1733
  }
1308
- ), /* @__PURE__ */ React15__namespace.default.createElement(
1734
+ ), /* @__PURE__ */ import_react13.default.createElement(
1309
1735
  "div",
1310
1736
  {
1311
1737
  className: cn(
@@ -1313,7 +1739,7 @@ var Modal = ({
1313
1739
  className
1314
1740
  )
1315
1741
  },
1316
- !hideHeader && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border/50 shrink-0 bg-gradient-to-r from-muted/20 to-background" }, /* @__PURE__ */ React15__namespace.default.createElement("h3", { className: "text-lg font-semibold text-foreground" }, title), /* @__PURE__ */ React15__namespace.default.createElement(
1742
+ !hideHeader && /* @__PURE__ */ import_react13.default.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border/50 shrink-0 bg-gradient-to-r from-muted/20 to-background" }, /* @__PURE__ */ import_react13.default.createElement("h3", { className: "text-lg font-semibold text-foreground" }, title), /* @__PURE__ */ import_react13.default.createElement(
1317
1743
  Button,
1318
1744
  {
1319
1745
  variant: "ghost",
@@ -1321,12 +1747,17 @@ var Modal = ({
1321
1747
  onClick: onClose,
1322
1748
  className: "h-9 w-9 p-0 rounded-xl hover:bg-accent/80 transition-all duration-200"
1323
1749
  },
1324
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.X, { className: "h-4 w-4" }),
1325
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "sr-only" }, "Close")
1750
+ /* @__PURE__ */ import_react13.default.createElement(import_lucide_react6.X, { className: "h-4 w-4" }),
1751
+ /* @__PURE__ */ import_react13.default.createElement("span", { className: "sr-only" }, "Close")
1326
1752
  )),
1327
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: cn("overflow-y-auto flex-1", !hideHeader && "p-6") }, children)
1753
+ /* @__PURE__ */ import_react13.default.createElement("div", { className: cn("overflow-y-auto flex-1", !hideHeader && "p-6") }, children)
1328
1754
  ));
1329
1755
  };
1756
+
1757
+ // src/components/EventModal.tsx
1758
+ var import_date_fns13 = require("date-fns");
1759
+ var import_framer_motion2 = require("framer-motion");
1760
+ var import_lucide_react7 = require("lucide-react");
1330
1761
  var REMINDER_OPTIONS = [
1331
1762
  { value: 0, label: "At time of event" },
1332
1763
  { value: 5, label: "5 minutes before" },
@@ -1368,13 +1799,10 @@ var EventModal = ({
1368
1799
  initialDate,
1369
1800
  onSave,
1370
1801
  onDelete,
1371
- calendars,
1372
- eventTypes,
1373
- translations
1802
+ calendars
1374
1803
  }) => {
1375
- const [mode, setMode] = React15.useState("create");
1376
- const [activeTab, setActiveTab] = React15.useState("details");
1377
- const [formData, setFormData] = React15.useState({
1804
+ const [mode, setMode] = (0, import_react14.useState)("create");
1805
+ const [formData, setFormData] = (0, import_react14.useState)({
1378
1806
  title: "",
1379
1807
  description: "",
1380
1808
  location: "",
@@ -1388,10 +1816,10 @@ var EventModal = ({
1388
1816
  attachments: [],
1389
1817
  reminders: [{ id: "1", type: "notification", time: 30, label: "30 minutes before" }]
1390
1818
  });
1391
- const [isCalendarDropdownOpen, setIsCalendarDropdownOpen] = React15.useState(false);
1392
- const [isColorPickerOpen, setIsColorPickerOpen] = React15.useState(false);
1393
- const [isReminderDropdownOpen, setIsReminderDropdownOpen] = React15.useState(false);
1394
- const [isGuestsDropdownOpen, setIsGuestsDropdownOpen] = React15.useState(false);
1819
+ const [isCalendarDropdownOpen, setIsCalendarDropdownOpen] = (0, import_react14.useState)(false);
1820
+ const [isColorPickerOpen, setIsColorPickerOpen] = (0, import_react14.useState)(false);
1821
+ const [isReminderDropdownOpen, setIsReminderDropdownOpen] = (0, import_react14.useState)(false);
1822
+ const [isGuestsDropdownOpen, setIsGuestsDropdownOpen] = (0, import_react14.useState)(false);
1395
1823
  const fakeGuests = [
1396
1824
  "alice@example.com",
1397
1825
  "bob@example.com",
@@ -1399,9 +1827,8 @@ var EventModal = ({
1399
1827
  "diana@example.com",
1400
1828
  "evan@example.com"
1401
1829
  ];
1402
- React15.useRef(null);
1403
- const [selectedGuests, setSelectedGuests] = React15.useState([]);
1404
- React15.useEffect(() => {
1830
+ const [selectedGuests, setSelectedGuests] = (0, import_react14.useState)([]);
1831
+ (0, import_react14.useEffect)(() => {
1405
1832
  if (isOpen) {
1406
1833
  if (event) {
1407
1834
  setMode("view");
@@ -1431,7 +1858,6 @@ var EventModal = ({
1431
1858
  reminders: [{ id: "1", type: "notification", time: 30, label: "30 minutes before" }]
1432
1859
  });
1433
1860
  setSelectedGuests([]);
1434
- setActiveTab("details");
1435
1861
  }
1436
1862
  }
1437
1863
  }, [isOpen, event, initialDate, calendars]);
@@ -1466,7 +1892,7 @@ var EventModal = ({
1466
1892
  };
1467
1893
  const formatDateForInput = (date) => {
1468
1894
  if (!date) return "";
1469
- return dateFns.format(date, "yyyy-MM-dd'T'HH:mm");
1895
+ return (0, import_date_fns13.format)(date, "yyyy-MM-dd'T'HH:mm");
1470
1896
  };
1471
1897
  const handleDateChange = (field, value) => {
1472
1898
  const date = new Date(value);
@@ -1516,14 +1942,14 @@ var EventModal = ({
1516
1942
  };
1517
1943
  const getDurationText = () => {
1518
1944
  if (!formData.start || !formData.end) return "";
1519
- const mins = dateFns.differenceInMinutes(formData.end, formData.start);
1945
+ const mins = (0, import_date_fns13.differenceInMinutes)(formData.end, formData.start);
1520
1946
  if (mins < 60) return `${mins} min`;
1521
1947
  const hours = Math.floor(mins / 60);
1522
1948
  const remainingMins = mins % 60;
1523
1949
  if (remainingMins === 0) return `${hours} hr`;
1524
1950
  return `${hours} hr ${remainingMins} min`;
1525
1951
  };
1526
- const renderViewMode = () => /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-col bg-background overflow-hidden w-full max-h-[90vh]" }, /* @__PURE__ */ React15__namespace.default.createElement(
1952
+ const renderViewMode = () => /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex flex-col bg-background overflow-hidden w-full max-h-[90vh]" }, /* @__PURE__ */ import_react14.default.createElement(
1527
1953
  "div",
1528
1954
  {
1529
1955
  className: "relative px-6 pt-6 pb-8",
@@ -1531,65 +1957,65 @@ var EventModal = ({
1531
1957
  background: `linear-gradient(135deg, ${event?.color || "#3b82f6"}15 0%, transparent 100%)`
1532
1958
  }
1533
1959
  },
1534
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center justify-between mb-6" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement(
1960
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center justify-between mb-6" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react14.default.createElement(
1535
1961
  "div",
1536
1962
  {
1537
1963
  className: "w-3 h-3 rounded-full",
1538
1964
  style: { backgroundColor: event?.color || "#3b82f6" }
1539
1965
  }
1540
- ), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider" }, calendars?.find((c) => c.id === event?.calendarId)?.label || "Event")), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React15__namespace.default.createElement(
1966
+ ), /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider" }, calendars?.find((c) => c.id === event?.calendarId)?.label || "Event")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react14.default.createElement(
1541
1967
  "button",
1542
1968
  {
1543
1969
  onClick: () => setMode("edit"),
1544
1970
  className: "p-2 hover:bg-background/80 rounded-lg transition-all text-muted-foreground hover:text-foreground",
1545
1971
  title: "Edit"
1546
1972
  },
1547
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Edit2, { className: "w-4 h-4" })
1548
- ), /* @__PURE__ */ React15__namespace.default.createElement(
1973
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Edit2, { className: "w-4 h-4" })
1974
+ ), /* @__PURE__ */ import_react14.default.createElement(
1549
1975
  "button",
1550
1976
  {
1551
1977
  onClick: handleDelete,
1552
1978
  className: "p-2 hover:bg-destructive/10 rounded-lg transition-all text-muted-foreground hover:text-destructive",
1553
1979
  title: "Delete"
1554
1980
  },
1555
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Trash2, { className: "w-4 h-4" })
1556
- ), /* @__PURE__ */ React15__namespace.default.createElement(
1981
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Trash2, { className: "w-4 h-4" })
1982
+ ), /* @__PURE__ */ import_react14.default.createElement(
1557
1983
  "button",
1558
1984
  {
1559
1985
  onClick: onClose,
1560
1986
  className: "p-2 hover:bg-background/80 rounded-lg transition-all text-muted-foreground hover:text-foreground",
1561
1987
  title: "Close"
1562
1988
  },
1563
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.X, { className: "w-4 h-4" })
1989
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.X, { className: "w-4 h-4" })
1564
1990
  ))),
1565
- /* @__PURE__ */ React15__namespace.default.createElement("h1", { className: "text-2xl font-bold text-foreground mb-3 leading-tight" }, event?.title || "(No title)"),
1566
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-3 text-sm" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2 px-3 py-1.5 bg-background/60 backdrop-blur-sm rounded-lg border border-border/30" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Calendar, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "font-medium" }, event?.start && dateFns.format(new Date(event.start), "EEE, MMM d"))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2 px-3 py-1.5 bg-background/60 backdrop-blur-sm rounded-lg border border-border/30" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Clock, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "font-medium" }, event?.start && dateFns.format(new Date(event.start), "h:mm a"), " \u2013 ", event?.end && dateFns.format(new Date(event.end), "h:mm a"))))
1567
- ), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "px-6 pb-6 space-y-4 overflow-y-auto flex-1" }, event?.location && /* @__PURE__ */ React15__namespace.default.createElement(
1568
- framerMotion.motion.div,
1991
+ /* @__PURE__ */ import_react14.default.createElement("h1", { className: "text-2xl font-bold text-foreground mb-3 leading-tight" }, event?.title || "(No title)"),
1992
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-3 text-sm" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2 px-3 py-1.5 bg-background/60 backdrop-blur-sm rounded-lg border border-border/30" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Calendar, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ import_react14.default.createElement("span", { className: "font-medium" }, event?.start && (0, import_date_fns13.format)(new Date(event.start), "EEE, MMM d"))), /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2 px-3 py-1.5 bg-background/60 backdrop-blur-sm rounded-lg border border-border/30" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Clock, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ import_react14.default.createElement("span", { className: "font-medium" }, event?.start && (0, import_date_fns13.format)(new Date(event.start), "h:mm a"), " \u2013 ", event?.end && (0, import_date_fns13.format)(new Date(event.end), "h:mm a"))))
1993
+ ), /* @__PURE__ */ import_react14.default.createElement("div", { className: "px-6 pb-6 space-y-4 overflow-y-auto flex-1" }, event?.location && /* @__PURE__ */ import_react14.default.createElement(
1994
+ import_framer_motion2.motion.div,
1569
1995
  {
1570
1996
  initial: { opacity: 0, y: 10 },
1571
1997
  animate: { opacity: 1, y: 0 },
1572
1998
  className: "flex items-start gap-3 p-4 rounded-2xl bg-muted/30 border border-border/30 group hover:bg-muted/50 transition-all cursor-pointer"
1573
1999
  },
1574
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "p-2 bg-primary/10 rounded-xl" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.MapPin, { className: "w-5 h-5 text-primary" })),
1575
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React15__namespace.default.createElement("p", { className: "text-sm font-medium text-foreground" }, event.location), /* @__PURE__ */ React15__namespace.default.createElement("p", { className: "text-xs text-muted-foreground mt-0.5" }, "Click to open in maps")),
1576
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.ExternalLink, { className: "w-4 h-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" })
1577
- ), event?.guests && event.guests.length > 0 && /* @__PURE__ */ React15__namespace.default.createElement(
1578
- framerMotion.motion.div,
2000
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "p-2 bg-primary/10 rounded-xl" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.MapPin, { className: "w-5 h-5 text-primary" })),
2001
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex-1" }, /* @__PURE__ */ import_react14.default.createElement("p", { className: "text-sm font-medium text-foreground" }, event.location), /* @__PURE__ */ import_react14.default.createElement("p", { className: "text-xs text-muted-foreground mt-0.5" }, "Click to open in maps")),
2002
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.ExternalLink, { className: "w-4 h-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" })
2003
+ ), event?.guests && event.guests.length > 0 && /* @__PURE__ */ import_react14.default.createElement(
2004
+ import_framer_motion2.motion.div,
1579
2005
  {
1580
2006
  initial: { opacity: 0, y: 10 },
1581
2007
  animate: { opacity: 1, y: 0 },
1582
2008
  transition: { delay: 0.05 },
1583
2009
  className: "space-y-3"
1584
2010
  },
1585
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Users, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm font-medium text-foreground" }, event.guests.length, " ", event.guests.length > 1 ? "Guests" : "Guest"))),
1586
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-wrap gap-2" }, event.guests.map((email, index) => /* @__PURE__ */ React15__namespace.default.createElement(
2011
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Users, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-sm font-medium text-foreground" }, event.guests.length, " ", event.guests.length > 1 ? "Guests" : "Guest"))),
2012
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex flex-wrap gap-2" }, event.guests.map((email, index) => /* @__PURE__ */ import_react14.default.createElement(
1587
2013
  "div",
1588
2014
  {
1589
2015
  key: index,
1590
2016
  className: "flex items-center gap-2 px-3 py-2 rounded-xl bg-muted/30 border border-border/30 hover:bg-muted/50 transition-all cursor-pointer group"
1591
2017
  },
1592
- /* @__PURE__ */ React15__namespace.default.createElement(
2018
+ /* @__PURE__ */ import_react14.default.createElement(
1593
2019
  "div",
1594
2020
  {
1595
2021
  className: "w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold text-white",
@@ -1597,18 +2023,18 @@ var EventModal = ({
1597
2023
  },
1598
2024
  email[0].toUpperCase()
1599
2025
  ),
1600
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React15__namespace.default.createElement("p", { className: "text-sm font-medium text-foreground" }, email.split("@")[0]), /* @__PURE__ */ React15__namespace.default.createElement("p", { className: "text-xs text-muted-foreground truncate" }, email))
2026
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react14.default.createElement("p", { className: "text-sm font-medium text-foreground" }, email.split("@")[0]), /* @__PURE__ */ import_react14.default.createElement("p", { className: "text-xs text-muted-foreground truncate" }, email))
1601
2027
  )))
1602
- ), event?.reminders && event.reminders.length > 0 && /* @__PURE__ */ React15__namespace.default.createElement(
1603
- framerMotion.motion.div,
2028
+ ), event?.reminders && event.reminders.length > 0 && /* @__PURE__ */ import_react14.default.createElement(
2029
+ import_framer_motion2.motion.div,
1604
2030
  {
1605
2031
  initial: { opacity: 0, y: 10 },
1606
2032
  animate: { opacity: 1, y: 0 },
1607
2033
  transition: { delay: 0.1 },
1608
2034
  className: "flex items-center gap-3"
1609
2035
  },
1610
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "p-2 bg-amber-500/10 rounded-xl" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Bell, { className: "w-4 h-4 text-amber-500" })),
1611
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-wrap gap-2" }, event.reminders.map((reminder) => /* @__PURE__ */ React15__namespace.default.createElement(
2036
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "p-2 bg-amber-500/10 rounded-xl" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Bell, { className: "w-4 h-4 text-amber-500" })),
2037
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex flex-wrap gap-2" }, event.reminders.map((reminder) => /* @__PURE__ */ import_react14.default.createElement(
1612
2038
  "span",
1613
2039
  {
1614
2040
  key: reminder.id,
@@ -1616,45 +2042,45 @@ var EventModal = ({
1616
2042
  },
1617
2043
  reminder.label || `${reminder.time} min before`
1618
2044
  )))
1619
- ), event?.description && /* @__PURE__ */ React15__namespace.default.createElement(
1620
- framerMotion.motion.div,
2045
+ ), event?.description && /* @__PURE__ */ import_react14.default.createElement(
2046
+ import_framer_motion2.motion.div,
1621
2047
  {
1622
2048
  initial: { opacity: 0, y: 10 },
1623
2049
  animate: { opacity: 1, y: 0 },
1624
2050
  transition: { delay: 0.15 },
1625
2051
  className: "space-y-2"
1626
2052
  },
1627
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.AlignLeft, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm font-medium text-foreground" }, "Notes")),
1628
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-sm text-foreground/80 whitespace-pre-wrap leading-relaxed pl-6 p-3 rounded-xl bg-muted/20 border border-border/30" }, event.description)
1629
- ), event?.attachments && event.attachments.length > 0 && /* @__PURE__ */ React15__namespace.default.createElement(
1630
- framerMotion.motion.div,
2053
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.AlignLeft, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-sm font-medium text-foreground" }, "Notes")),
2054
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "text-sm text-foreground/80 whitespace-pre-wrap leading-relaxed pl-6 p-3 rounded-xl bg-muted/20 border border-border/30" }, event.description)
2055
+ ), event?.attachments && event.attachments.length > 0 && /* @__PURE__ */ import_react14.default.createElement(
2056
+ import_framer_motion2.motion.div,
1631
2057
  {
1632
2058
  initial: { opacity: 0, y: 10 },
1633
2059
  animate: { opacity: 1, y: 0 },
1634
2060
  transition: { delay: 0.2 },
1635
2061
  className: "space-y-2"
1636
2062
  },
1637
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Paperclip, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm font-medium text-foreground" }, "Attachments")),
1638
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "grid gap-2" }, event.attachments.map((att) => /* @__PURE__ */ React15__namespace.default.createElement(
2063
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Paperclip, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-sm font-medium text-foreground" }, "Attachments")),
2064
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "grid gap-2" }, event.attachments.map((att) => /* @__PURE__ */ import_react14.default.createElement(
1639
2065
  "div",
1640
2066
  {
1641
2067
  key: att.id,
1642
2068
  onClick: () => handleDownload(att),
1643
2069
  className: "flex items-center gap-3 p-3 rounded-xl border border-border/30 bg-muted/20 hover:bg-muted/40 transition-all cursor-pointer group"
1644
2070
  },
1645
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "p-2 bg-primary/10 rounded-lg" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.File, { className: "w-4 h-4 text-primary" })),
1646
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React15__namespace.default.createElement("p", { className: "text-sm font-medium text-foreground truncate" }, att.name), /* @__PURE__ */ React15__namespace.default.createElement("p", { className: "text-xs text-muted-foreground" }, att.size)),
1647
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Download, { className: "w-4 h-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" })
2071
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "p-2 bg-primary/10 rounded-lg" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.File, { className: "w-4 h-4 text-primary" })),
2072
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react14.default.createElement("p", { className: "text-sm font-medium text-foreground truncate" }, att.name), /* @__PURE__ */ import_react14.default.createElement("p", { className: "text-xs text-muted-foreground" }, att.size)),
2073
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Download, { className: "w-4 h-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" })
1648
2074
  )))
1649
2075
  )));
1650
- const renderEditMode = () => /* @__PURE__ */ React15__namespace.default.createElement("form", { onSubmit: handleSubmit, className: "flex flex-col bg-background overflow-hidden w-full max-h-[85vh]" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center justify-between px-5 py-4 border-b border-border/50 shrink-0" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React15__namespace.default.createElement(
2076
+ const renderEditMode = () => /* @__PURE__ */ import_react14.default.createElement("form", { onSubmit: handleSubmit, className: "flex flex-col bg-background overflow-hidden w-full max-h-[85vh]" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center justify-between px-5 py-4 border-b border-border/50 shrink-0" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ import_react14.default.createElement(
1651
2077
  "button",
1652
2078
  {
1653
2079
  type: "button",
1654
2080
  onClick: () => setIsColorPickerOpen(!isColorPickerOpen),
1655
2081
  className: "relative p-1"
1656
2082
  },
1657
- /* @__PURE__ */ React15__namespace.default.createElement(
2083
+ /* @__PURE__ */ import_react14.default.createElement(
1658
2084
  "div",
1659
2085
  {
1660
2086
  className: "w-5 h-5 rounded-full cursor-pointer hover:scale-110 transition-transform",
@@ -1664,7 +2090,7 @@ var EventModal = ({
1664
2090
  }
1665
2091
  }
1666
2092
  ),
1667
- isColorPickerOpen && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute top-full left-0 mt-2 p-2 bg-background border border-border rounded-xl shadow-xl z-50 flex flex-wrap gap-1.5 w-[180px]" }, COLOR_PALETTE.map((color) => /* @__PURE__ */ React15__namespace.default.createElement(
2093
+ isColorPickerOpen && /* @__PURE__ */ import_react14.default.createElement("div", { className: "absolute top-full left-0 mt-2 p-2 bg-background border border-border rounded-xl shadow-xl z-50 flex flex-wrap gap-1.5 w-[180px]" }, COLOR_PALETTE.map((color) => /* @__PURE__ */ import_react14.default.createElement(
1668
2094
  "button",
1669
2095
  {
1670
2096
  key: color,
@@ -1680,15 +2106,15 @@ var EventModal = ({
1680
2106
  style: { backgroundColor: color, color }
1681
2107
  }
1682
2108
  )))
1683
- ), /* @__PURE__ */ React15__namespace.default.createElement("h2", { className: "text-lg font-semibold text-foreground" }, mode === "edit" ? "Edit Event" : "New Event")), /* @__PURE__ */ React15__namespace.default.createElement(
2109
+ ), /* @__PURE__ */ import_react14.default.createElement("h2", { className: "text-lg font-semibold text-foreground" }, mode === "edit" ? "Edit Event" : "New Event")), /* @__PURE__ */ import_react14.default.createElement(
1684
2110
  "button",
1685
2111
  {
1686
2112
  type: "button",
1687
2113
  onClick: onClose,
1688
2114
  className: "p-2 hover:bg-accent rounded-xl transition-all text-muted-foreground hover:text-foreground"
1689
2115
  },
1690
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.X, { className: "w-4 h-4" })
1691
- )), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 overflow-y-auto" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "px-5 py-4 space-y-5" }, /* @__PURE__ */ React15__namespace.default.createElement("div", null, /* @__PURE__ */ React15__namespace.default.createElement(
2116
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.X, { className: "w-4 h-4" })
2117
+ )), /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex-1 overflow-y-auto" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "px-5 py-4 space-y-5" }, /* @__PURE__ */ import_react14.default.createElement("div", null, /* @__PURE__ */ import_react14.default.createElement(
1692
2118
  "input",
1693
2119
  {
1694
2120
  type: "text",
@@ -1699,7 +2125,7 @@ var EventModal = ({
1699
2125
  onChange: (e) => setFormData({ ...formData, title: e.target.value }),
1700
2126
  placeholder: "Add title"
1701
2127
  }
1702
- )), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-3 p-4 rounded-2xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "p-2 bg-primary/10 rounded-xl shrink-0" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Clock, { className: "w-5 h-5 text-primary" })), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 grid grid-cols-2 gap-3" }, /* @__PURE__ */ React15__namespace.default.createElement("div", null, /* @__PURE__ */ React15__namespace.default.createElement("label", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider mb-1 block" }, "Start"), /* @__PURE__ */ React15__namespace.default.createElement(
2128
+ )), /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-3 p-4 rounded-2xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "p-2 bg-primary/10 rounded-xl shrink-0" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Clock, { className: "w-5 h-5 text-primary" })), /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex-1 grid grid-cols-2 gap-3" }, /* @__PURE__ */ import_react14.default.createElement("div", null, /* @__PURE__ */ import_react14.default.createElement("label", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider mb-1 block" }, "Start"), /* @__PURE__ */ import_react14.default.createElement(
1703
2129
  "input",
1704
2130
  {
1705
2131
  type: "datetime-local",
@@ -1707,7 +2133,7 @@ var EventModal = ({
1707
2133
  value: formatDateForInput(formData.start),
1708
2134
  onChange: (e) => handleDateChange("start", e.target.value)
1709
2135
  }
1710
- )), /* @__PURE__ */ React15__namespace.default.createElement("div", null, /* @__PURE__ */ React15__namespace.default.createElement("label", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider mb-1 block" }, "End"), /* @__PURE__ */ React15__namespace.default.createElement(
2136
+ )), /* @__PURE__ */ import_react14.default.createElement("div", null, /* @__PURE__ */ import_react14.default.createElement("label", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider mb-1 block" }, "End"), /* @__PURE__ */ import_react14.default.createElement(
1711
2137
  "input",
1712
2138
  {
1713
2139
  type: "datetime-local",
@@ -1715,16 +2141,16 @@ var EventModal = ({
1715
2141
  value: formatDateForInput(formData.end),
1716
2142
  onChange: (e) => handleDateChange("end", e.target.value)
1717
2143
  }
1718
- )))), getDurationText() && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-xs font-medium px-3 py-1 rounded-full bg-primary/10 text-primary" }, getDurationText())), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Bell, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm font-medium text-foreground" }, "Reminders")), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React15__namespace.default.createElement(
2144
+ )))), getDurationText() && /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-xs font-medium px-3 py-1 rounded-full bg-primary/10 text-primary" }, getDurationText())), /* @__PURE__ */ import_react14.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Bell, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-sm font-medium text-foreground" }, "Reminders")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react14.default.createElement(
1719
2145
  "button",
1720
2146
  {
1721
2147
  type: "button",
1722
2148
  onClick: () => setIsReminderDropdownOpen(!isReminderDropdownOpen),
1723
2149
  className: "flex items-center gap-1 text-xs font-medium text-primary hover:text-primary/80 transition-colors"
1724
2150
  },
1725
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Plus, { className: "w-3.5 h-3.5" }),
2151
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Plus, { className: "w-3.5 h-3.5" }),
1726
2152
  "Add"
1727
- ), isReminderDropdownOpen && /* @__PURE__ */ React15__namespace.default.createElement(React15__namespace.default.Fragment, null, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsReminderDropdownOpen(false) }), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute right-0 top-full mt-1 w-48 bg-background border border-border rounded-xl shadow-xl z-50 py-1 max-h-60 overflow-y-auto" }, REMINDER_OPTIONS.map((option) => /* @__PURE__ */ React15__namespace.default.createElement(
2153
+ ), isReminderDropdownOpen && /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, /* @__PURE__ */ import_react14.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsReminderDropdownOpen(false) }), /* @__PURE__ */ import_react14.default.createElement("div", { className: "absolute right-0 top-full mt-1 w-48 bg-background border border-border rounded-xl shadow-xl z-50 py-1 max-h-60 overflow-y-auto" }, REMINDER_OPTIONS.map((option) => /* @__PURE__ */ import_react14.default.createElement(
1728
2154
  "button",
1729
2155
  {
1730
2156
  key: option.value,
@@ -1733,58 +2159,58 @@ var EventModal = ({
1733
2159
  className: "w-full px-3 py-2 text-left text-sm hover:bg-accent transition-colors"
1734
2160
  },
1735
2161
  option.label
1736
- )))))), formData.reminders && formData.reminders.length > 0 && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-wrap gap-2" }, formData.reminders.map((reminder) => /* @__PURE__ */ React15__namespace.default.createElement(
2162
+ )))))), formData.reminders && formData.reminders.length > 0 && /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex flex-wrap gap-2" }, formData.reminders.map((reminder) => /* @__PURE__ */ import_react14.default.createElement(
1737
2163
  "div",
1738
2164
  {
1739
2165
  key: reminder.id,
1740
2166
  className: "flex items-center gap-2 px-3 py-1.5 rounded-full bg-amber-500/10 border border-amber-500/20"
1741
2167
  },
1742
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.BellRing, { className: "w-3.5 h-3.5 text-amber-500" }),
1743
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-xs font-medium text-amber-600 dark:text-amber-400" }, reminder.label),
1744
- /* @__PURE__ */ React15__namespace.default.createElement(
2168
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.BellRing, { className: "w-3.5 h-3.5 text-amber-500" }),
2169
+ /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-xs font-medium text-amber-600 dark:text-amber-400" }, reminder.label),
2170
+ /* @__PURE__ */ import_react14.default.createElement(
1745
2171
  "button",
1746
2172
  {
1747
2173
  type: "button",
1748
2174
  onClick: () => removeReminder(reminder.id),
1749
2175
  className: "p-0.5 hover:bg-amber-500/20 rounded-full transition-colors"
1750
2176
  },
1751
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.X, { className: "w-3 h-3 text-amber-500" })
2177
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.X, { className: "w-3 h-3 text-amber-500" })
1752
2178
  )
1753
- )))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Users, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm font-medium text-foreground" }, "Guests")), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React15__namespace.default.createElement(
2179
+ )))), /* @__PURE__ */ import_react14.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Users, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-sm font-medium text-foreground" }, "Guests")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react14.default.createElement(
1754
2180
  "button",
1755
2181
  {
1756
2182
  type: "button",
1757
2183
  onClick: () => setIsGuestsDropdownOpen(!isGuestsDropdownOpen),
1758
2184
  className: "w-full flex items-center justify-between px-4 py-3 bg-muted/20 border border-border/30 rounded-xl text-sm text-left hover:bg-muted/30 transition-all"
1759
2185
  },
1760
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: selectedGuests.length > 0 ? "text-foreground font-medium" : "text-muted-foreground" }, selectedGuests.length > 0 ? `${selectedGuests.length} guest${selectedGuests.length > 1 ? "s" : ""} added` : "Add guests"),
1761
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.ChevronDown, { className: cn("w-4 h-4 text-muted-foreground transition-transform", isGuestsDropdownOpen && "rotate-180") })
1762
- ), isGuestsDropdownOpen && /* @__PURE__ */ React15__namespace.default.createElement(React15__namespace.default.Fragment, null, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsGuestsDropdownOpen(false) }), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute z-50 w-full mt-2 bg-background border border-border rounded-xl shadow-xl max-h-48 overflow-y-auto" }, fakeGuests.map((email) => /* @__PURE__ */ React15__namespace.default.createElement(
2186
+ /* @__PURE__ */ import_react14.default.createElement("span", { className: selectedGuests.length > 0 ? "text-foreground font-medium" : "text-muted-foreground" }, selectedGuests.length > 0 ? `${selectedGuests.length} guest${selectedGuests.length > 1 ? "s" : ""} added` : "Add guests"),
2187
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.ChevronDown, { className: cn("w-4 h-4 text-muted-foreground transition-transform", isGuestsDropdownOpen && "rotate-180") })
2188
+ ), isGuestsDropdownOpen && /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, /* @__PURE__ */ import_react14.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsGuestsDropdownOpen(false) }), /* @__PURE__ */ import_react14.default.createElement("div", { className: "absolute z-50 w-full mt-2 bg-background border border-border rounded-xl shadow-xl max-h-48 overflow-y-auto" }, fakeGuests.map((email) => /* @__PURE__ */ import_react14.default.createElement(
1763
2189
  "div",
1764
2190
  {
1765
2191
  key: email,
1766
2192
  className: "px-4 py-3 hover:bg-accent cursor-pointer flex items-center gap-3 transition-colors",
1767
2193
  onClick: () => toggleGuest(email)
1768
2194
  },
1769
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: cn(
2195
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: cn(
1770
2196
  "w-5 h-5 rounded-md border-2 flex items-center justify-center transition-all",
1771
2197
  selectedGuests.includes(email) ? "bg-primary border-primary" : "border-border"
1772
- ) }, selectedGuests.includes(email) && /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Check, { className: "w-3 h-3 text-primary-foreground" })),
1773
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement(
2198
+ ) }, selectedGuests.includes(email) && /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Check, { className: "w-3 h-3 text-primary-foreground" })),
2199
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react14.default.createElement(
1774
2200
  "div",
1775
2201
  {
1776
2202
  className: "w-7 h-7 rounded-full flex items-center justify-center text-xs font-semibold text-white",
1777
2203
  style: { backgroundColor: `hsl(${fakeGuests.indexOf(email) * 60}, 70%, 50%)` }
1778
2204
  },
1779
2205
  email[0].toUpperCase()
1780
- ), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm" }, email))
1781
- ))))), selectedGuests.length > 0 && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-wrap gap-2 mt-2" }, selectedGuests.map((email) => /* @__PURE__ */ React15__namespace.default.createElement(
2206
+ ), /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-sm" }, email))
2207
+ ))))), selectedGuests.length > 0 && /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex flex-wrap gap-2 mt-2" }, selectedGuests.map((email) => /* @__PURE__ */ import_react14.default.createElement(
1782
2208
  "div",
1783
2209
  {
1784
2210
  key: email,
1785
2211
  className: "flex items-center gap-2 pl-1 pr-2 py-1 bg-muted/30 border border-border/30 rounded-full"
1786
2212
  },
1787
- /* @__PURE__ */ React15__namespace.default.createElement(
2213
+ /* @__PURE__ */ import_react14.default.createElement(
1788
2214
  "div",
1789
2215
  {
1790
2216
  className: "w-6 h-6 rounded-full flex items-center justify-center text-xs font-semibold text-white",
@@ -1792,17 +2218,17 @@ var EventModal = ({
1792
2218
  },
1793
2219
  email[0].toUpperCase()
1794
2220
  ),
1795
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-xs font-medium text-foreground" }, email.split("@")[0]),
1796
- /* @__PURE__ */ React15__namespace.default.createElement(
2221
+ /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-xs font-medium text-foreground" }, email.split("@")[0]),
2222
+ /* @__PURE__ */ import_react14.default.createElement(
1797
2223
  "button",
1798
2224
  {
1799
2225
  type: "button",
1800
2226
  onClick: () => toggleGuest(email),
1801
2227
  className: "p-0.5 hover:bg-destructive/10 rounded-full transition-colors"
1802
2228
  },
1803
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.X, { className: "w-3 h-3 text-muted-foreground" })
2229
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.X, { className: "w-3 h-3 text-muted-foreground" })
1804
2230
  )
1805
- )))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-3 p-3 rounded-xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.MapPin, { className: "w-5 h-5 text-muted-foreground shrink-0" }), /* @__PURE__ */ React15__namespace.default.createElement(
2231
+ )))), /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-3 p-3 rounded-xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.MapPin, { className: "w-5 h-5 text-muted-foreground shrink-0" }), /* @__PURE__ */ import_react14.default.createElement(
1806
2232
  "input",
1807
2233
  {
1808
2234
  type: "text",
@@ -1811,7 +2237,7 @@ var EventModal = ({
1811
2237
  value: formData.location || "",
1812
2238
  onChange: (e) => setFormData({ ...formData, location: e.target.value })
1813
2239
  }
1814
- )), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.AlignLeft, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm font-medium text-foreground" }, "Notes")), /* @__PURE__ */ React15__namespace.default.createElement(
2240
+ )), /* @__PURE__ */ import_react14.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.AlignLeft, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-sm font-medium text-foreground" }, "Notes")), /* @__PURE__ */ import_react14.default.createElement(
1815
2241
  "textarea",
1816
2242
  {
1817
2243
  className: "w-full bg-muted/20 border border-border/30 rounded-xl px-4 py-3 text-sm min-h-[100px] resize-none text-foreground placeholder-muted-foreground focus:border-primary focus:ring-2 focus:ring-primary/20 transition-all",
@@ -1819,7 +2245,7 @@ var EventModal = ({
1819
2245
  value: formData.description || "",
1820
2246
  onChange: (e) => setFormData({ ...formData, description: e.target.value })
1821
2247
  }
1822
- )), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-3 p-3 rounded-xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Repeat, { className: "w-5 h-5 text-muted-foreground shrink-0" }), /* @__PURE__ */ React15__namespace.default.createElement(
2248
+ )), /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-3 p-3 rounded-xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Repeat, { className: "w-5 h-5 text-muted-foreground shrink-0" }), /* @__PURE__ */ import_react14.default.createElement(
1823
2249
  "select",
1824
2250
  {
1825
2251
  className: "flex-1 bg-transparent text-sm text-foreground focus:outline-none cursor-pointer",
@@ -1838,28 +2264,28 @@ var EventModal = ({
1838
2264
  }
1839
2265
  }
1840
2266
  },
1841
- /* @__PURE__ */ React15__namespace.default.createElement("option", { value: "" }, "Does not repeat"),
1842
- /* @__PURE__ */ React15__namespace.default.createElement("option", { value: "DAILY" }, "Daily"),
1843
- /* @__PURE__ */ React15__namespace.default.createElement("option", { value: "WEEKLY" }, "Weekly"),
1844
- /* @__PURE__ */ React15__namespace.default.createElement("option", { value: "MONTHLY" }, "Monthly"),
1845
- /* @__PURE__ */ React15__namespace.default.createElement("option", { value: "YEARLY" }, "Yearly")
1846
- )), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center justify-between p-3 rounded-xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Tag, { className: "w-5 h-5 text-muted-foreground" }), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm text-foreground" }, "Calendar")), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "relative" }, /* @__PURE__ */ React15__namespace.default.createElement(
2267
+ /* @__PURE__ */ import_react14.default.createElement("option", { value: "" }, "Does not repeat"),
2268
+ /* @__PURE__ */ import_react14.default.createElement("option", { value: "DAILY" }, "Daily"),
2269
+ /* @__PURE__ */ import_react14.default.createElement("option", { value: "WEEKLY" }, "Weekly"),
2270
+ /* @__PURE__ */ import_react14.default.createElement("option", { value: "MONTHLY" }, "Monthly"),
2271
+ /* @__PURE__ */ import_react14.default.createElement("option", { value: "YEARLY" }, "Yearly")
2272
+ )), /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center justify-between p-3 rounded-xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Tag, { className: "w-5 h-5 text-muted-foreground" }), /* @__PURE__ */ import_react14.default.createElement("span", { className: "text-sm text-foreground" }, "Calendar")), /* @__PURE__ */ import_react14.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react14.default.createElement(
1847
2273
  "button",
1848
2274
  {
1849
2275
  type: "button",
1850
2276
  onClick: () => setIsCalendarDropdownOpen(!isCalendarDropdownOpen),
1851
2277
  className: "flex items-center gap-2 px-3 py-1.5 bg-background border border-border/50 rounded-lg text-sm hover:bg-accent/50 transition-all"
1852
2278
  },
1853
- /* @__PURE__ */ React15__namespace.default.createElement(
2279
+ /* @__PURE__ */ import_react14.default.createElement(
1854
2280
  "div",
1855
2281
  {
1856
2282
  className: "w-3 h-3 rounded-full",
1857
2283
  style: { backgroundColor: calendars?.find((c) => c.id === formData.calendarId)?.color || "#3b82f6" }
1858
2284
  }
1859
2285
  ),
1860
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "font-medium" }, calendars?.find((c) => c.id === formData.calendarId)?.label || "Select"),
1861
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.ChevronDown, { className: "w-3.5 h-3.5 text-muted-foreground" })
1862
- ), isCalendarDropdownOpen && /* @__PURE__ */ React15__namespace.default.createElement(React15__namespace.default.Fragment, null, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsCalendarDropdownOpen(false) }), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute right-0 bottom-full mb-2 w-48 bg-background border border-border rounded-xl shadow-xl z-50 py-1" }, calendars?.map((cal) => /* @__PURE__ */ React15__namespace.default.createElement(
2286
+ /* @__PURE__ */ import_react14.default.createElement("span", { className: "font-medium" }, calendars?.find((c) => c.id === formData.calendarId)?.label || "Select"),
2287
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.ChevronDown, { className: "w-3.5 h-3.5 text-muted-foreground" })
2288
+ ), isCalendarDropdownOpen && /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, /* @__PURE__ */ import_react14.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsCalendarDropdownOpen(false) }), /* @__PURE__ */ import_react14.default.createElement("div", { className: "absolute right-0 bottom-full mb-2 w-48 bg-background border border-border rounded-xl shadow-xl z-50 py-1" }, calendars?.map((cal) => /* @__PURE__ */ import_react14.default.createElement(
1863
2289
  "button",
1864
2290
  {
1865
2291
  key: cal.id,
@@ -1874,19 +2300,19 @@ var EventModal = ({
1874
2300
  setIsCalendarDropdownOpen(false);
1875
2301
  }
1876
2302
  },
1877
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "w-3 h-3 rounded-full", style: { backgroundColor: cal.color } }),
1878
- /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "flex-1 text-sm" }, cal.label),
1879
- formData.calendarId === cal.id && /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Check, { className: "w-4 h-4 text-primary" })
1880
- )))))))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "px-5 py-4 border-t border-border/50 flex items-center justify-between bg-muted/10 shrink-0" }, mode === "edit" && /* @__PURE__ */ React15__namespace.default.createElement(
2303
+ /* @__PURE__ */ import_react14.default.createElement("div", { className: "w-3 h-3 rounded-full", style: { backgroundColor: cal.color } }),
2304
+ /* @__PURE__ */ import_react14.default.createElement("span", { className: "flex-1 text-sm" }, cal.label),
2305
+ formData.calendarId === cal.id && /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Check, { className: "w-4 h-4 text-primary" })
2306
+ )))))))), /* @__PURE__ */ import_react14.default.createElement("div", { className: "px-5 py-4 border-t border-border/50 flex items-center justify-between bg-muted/10 shrink-0" }, mode === "edit" && /* @__PURE__ */ import_react14.default.createElement(
1881
2307
  "button",
1882
2308
  {
1883
2309
  type: "button",
1884
2310
  onClick: handleDelete,
1885
2311
  className: "flex items-center gap-2 px-4 py-2 text-destructive hover:bg-destructive/10 rounded-xl transition-all text-sm font-medium"
1886
2312
  },
1887
- /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Trash2, { className: "w-4 h-4" }),
2313
+ /* @__PURE__ */ import_react14.default.createElement(import_lucide_react7.Trash2, { className: "w-4 h-4" }),
1888
2314
  "Delete"
1889
- ), mode === "create" && /* @__PURE__ */ React15__namespace.default.createElement("div", null), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement(
2315
+ ), mode === "create" && /* @__PURE__ */ import_react14.default.createElement("div", null), /* @__PURE__ */ import_react14.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react14.default.createElement(
1890
2316
  "button",
1891
2317
  {
1892
2318
  type: "button",
@@ -1894,7 +2320,7 @@ var EventModal = ({
1894
2320
  className: "px-4 py-2.5 text-muted-foreground hover:text-foreground font-medium text-sm rounded-xl transition-all hover:bg-accent"
1895
2321
  },
1896
2322
  "Cancel"
1897
- ), /* @__PURE__ */ React15__namespace.default.createElement(
2323
+ ), /* @__PURE__ */ import_react14.default.createElement(
1898
2324
  "button",
1899
2325
  {
1900
2326
  type: "submit",
@@ -1902,8 +2328,8 @@ var EventModal = ({
1902
2328
  },
1903
2329
  mode === "edit" ? "Save Changes" : "Create Event"
1904
2330
  ))));
1905
- return /* @__PURE__ */ React15__namespace.default.createElement(Modal, { isOpen, onClose, hideHeader: true, className: "p-0 overflow-hidden max-w-lg rounded-2xl shadow-2xl" }, /* @__PURE__ */ React15__namespace.default.createElement(framerMotion.AnimatePresence, { mode: "wait" }, mode === "view" && event ? /* @__PURE__ */ React15__namespace.default.createElement(
1906
- framerMotion.motion.div,
2331
+ return /* @__PURE__ */ import_react14.default.createElement(Modal, { isOpen, onClose, hideHeader: true, className: "p-0 overflow-hidden max-w-lg rounded-2xl shadow-2xl" }, /* @__PURE__ */ import_react14.default.createElement(import_framer_motion2.AnimatePresence, { mode: "wait" }, mode === "view" && event ? /* @__PURE__ */ import_react14.default.createElement(
2332
+ import_framer_motion2.motion.div,
1907
2333
  {
1908
2334
  key: "view",
1909
2335
  initial: { opacity: 0 },
@@ -1912,8 +2338,8 @@ var EventModal = ({
1912
2338
  transition: { duration: 0.15 }
1913
2339
  },
1914
2340
  renderViewMode()
1915
- ) : /* @__PURE__ */ React15__namespace.default.createElement(
1916
- framerMotion.motion.div,
2341
+ ) : /* @__PURE__ */ import_react14.default.createElement(
2342
+ import_framer_motion2.motion.div,
1917
2343
  {
1918
2344
  key: "edit",
1919
2345
  initial: { opacity: 0 },
@@ -1924,9 +2350,12 @@ var EventModal = ({
1924
2350
  renderEditMode()
1925
2351
  )));
1926
2352
  };
1927
- var Skeleton = ({ className, style }) => /* @__PURE__ */ React15__namespace.default.createElement("div", { className: cn("animate-pulse bg-muted/40 rounded", className), style });
1928
- var MonthViewSkeleton = () => /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "grid grid-cols-7 border-b border-border/50 bg-muted/10" }, Array.from({ length: 7 }).map((_, i) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: i, className: "py-3 px-2 text-center border-r border-border/30 last:border-r-0" }, /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-4 w-8 mx-auto" })))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "grid grid-cols-7 flex-1" }, Array.from({ length: 35 }).map((_, i) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: i, className: "min-h-[120px] border-r border-b border-border/30 p-2" }, /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-4 w-6 mb-2" }), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "space-y-1" }, Math.random() > 0.5 && /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-5 w-full rounded-md" }), Math.random() > 0.7 && /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-5 w-3/4 rounded-md" }))))));
1929
- var WeekViewSkeleton = () => /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex border-b border-border/50 bg-muted/10" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "w-16 p-3 border-r border-border/30" }, /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-8 w-10 mx-auto" })), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 grid grid-cols-7" }, Array.from({ length: 7 }).map((_, i) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: i, className: "py-3 px-2 text-center border-r border-border/30 last:border-r-0" }, /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-3 w-8 mx-auto mb-1" }), /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-8 w-8 mx-auto rounded-xl" }))))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-1", style: { height: "600px" } }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "w-16 border-r border-border/30" }, Array.from({ length: 10 }).map((_, i) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: i, className: "h-[60px] relative" }, /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-4 w-10 absolute right-2 -translate-y-1/2" })))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 grid grid-cols-7 relative" }, Array.from({ length: 7 }).map((_, colIdx) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: colIdx, className: "relative border-r border-border/30 last:border-r-0" }, Array.from({ length: 10 }).map((_2, rowIdx) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: rowIdx, className: "h-[60px] border-b border-dashed border-border/20" })), Math.random() > 0.3 && /* @__PURE__ */ React15__namespace.default.createElement(
2353
+
2354
+ // src/components/Skeleton.tsx
2355
+ var import_react15 = __toESM(require("react"));
2356
+ var Skeleton = ({ className, style }) => /* @__PURE__ */ import_react15.default.createElement("div", { className: cn("animate-pulse bg-muted/40 rounded", className), style });
2357
+ var MonthViewSkeleton = () => /* @__PURE__ */ import_react15.default.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden" }, /* @__PURE__ */ import_react15.default.createElement("div", { className: "grid grid-cols-7 border-b border-border/50 bg-muted/10" }, Array.from({ length: 7 }).map((_, i) => /* @__PURE__ */ import_react15.default.createElement("div", { key: i, className: "py-3 px-2 text-center border-r border-border/30 last:border-r-0" }, /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-4 w-8 mx-auto" })))), /* @__PURE__ */ import_react15.default.createElement("div", { className: "grid grid-cols-7 flex-1" }, Array.from({ length: 35 }).map((_, i) => /* @__PURE__ */ import_react15.default.createElement("div", { key: i, className: "min-h-[120px] border-r border-b border-border/30 p-2" }, /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-4 w-6 mb-2" }), /* @__PURE__ */ import_react15.default.createElement("div", { className: "space-y-1" }, Math.random() > 0.5 && /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-5 w-full rounded-md" }), Math.random() > 0.7 && /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-5 w-3/4 rounded-md" }))))));
2358
+ var WeekViewSkeleton = () => /* @__PURE__ */ import_react15.default.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden" }, /* @__PURE__ */ import_react15.default.createElement("div", { className: "flex border-b border-border/50 bg-muted/10" }, /* @__PURE__ */ import_react15.default.createElement("div", { className: "w-16 p-3 border-r border-border/30" }, /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-8 w-10 mx-auto" })), /* @__PURE__ */ import_react15.default.createElement("div", { className: "flex-1 grid grid-cols-7" }, Array.from({ length: 7 }).map((_, i) => /* @__PURE__ */ import_react15.default.createElement("div", { key: i, className: "py-3 px-2 text-center border-r border-border/30 last:border-r-0" }, /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-3 w-8 mx-auto mb-1" }), /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-8 w-8 mx-auto rounded-xl" }))))), /* @__PURE__ */ import_react15.default.createElement("div", { className: "flex flex-1", style: { height: "600px" } }, /* @__PURE__ */ import_react15.default.createElement("div", { className: "w-16 border-r border-border/30" }, Array.from({ length: 10 }).map((_, i) => /* @__PURE__ */ import_react15.default.createElement("div", { key: i, className: "h-[60px] relative" }, /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-4 w-10 absolute right-2 -translate-y-1/2" })))), /* @__PURE__ */ import_react15.default.createElement("div", { className: "flex-1 grid grid-cols-7 relative" }, Array.from({ length: 7 }).map((_, colIdx) => /* @__PURE__ */ import_react15.default.createElement("div", { key: colIdx, className: "relative border-r border-border/30 last:border-r-0" }, Array.from({ length: 10 }).map((_2, rowIdx) => /* @__PURE__ */ import_react15.default.createElement("div", { key: rowIdx, className: "h-[60px] border-b border-dashed border-border/20" })), Math.random() > 0.3 && /* @__PURE__ */ import_react15.default.createElement(
1930
2359
  Skeleton,
1931
2360
  {
1932
2361
  className: "absolute rounded-md",
@@ -1938,20 +2367,25 @@ var WeekViewSkeleton = () => /* @__PURE__ */ React15__namespace.default.createEl
1938
2367
  }
1939
2368
  }
1940
2369
  ))))));
1941
- var DayViewSkeleton = () => /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "px-6 py-4 border-b border-border/50 bg-muted/10 text-center" }, /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-7 w-64 mx-auto" })), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-1", style: { height: "600px" } }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "w-20 border-r border-border/30 bg-muted/5" }, Array.from({ length: 10 }).map((_, i) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: i, className: "h-[80px] relative" }, /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-4 w-12 absolute left-1/2 -translate-x-1/2 -translate-y-1/2" })))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 relative" }, Array.from({ length: 10 }).map((_, i) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: i, className: "h-[80px] border-b border-dashed border-border/20" })), /* @__PURE__ */ React15__namespace.default.createElement(
2370
+ var DayViewSkeleton = () => /* @__PURE__ */ import_react15.default.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden" }, /* @__PURE__ */ import_react15.default.createElement("div", { className: "px-6 py-4 border-b border-border/50 bg-muted/10 text-center" }, /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-7 w-64 mx-auto" })), /* @__PURE__ */ import_react15.default.createElement("div", { className: "flex flex-1", style: { height: "600px" } }, /* @__PURE__ */ import_react15.default.createElement("div", { className: "w-20 border-r border-border/30 bg-muted/5" }, Array.from({ length: 10 }).map((_, i) => /* @__PURE__ */ import_react15.default.createElement("div", { key: i, className: "h-[80px] relative" }, /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-4 w-12 absolute left-1/2 -translate-x-1/2 -translate-y-1/2" })))), /* @__PURE__ */ import_react15.default.createElement("div", { className: "flex-1 relative" }, Array.from({ length: 10 }).map((_, i) => /* @__PURE__ */ import_react15.default.createElement("div", { key: i, className: "h-[80px] border-b border-dashed border-border/20" })), /* @__PURE__ */ import_react15.default.createElement(
1942
2371
  Skeleton,
1943
2372
  {
1944
2373
  className: "absolute rounded-lg left-4 right-4",
1945
2374
  style: { top: "160px", height: "120px" }
1946
2375
  }
1947
- ), /* @__PURE__ */ React15__namespace.default.createElement(
2376
+ ), /* @__PURE__ */ import_react15.default.createElement(
1948
2377
  Skeleton,
1949
2378
  {
1950
2379
  className: "absolute rounded-lg left-4 right-4",
1951
2380
  style: { top: "400px", height: "80px" }
1952
2381
  }
1953
2382
  ))));
1954
- var AgendaViewSkeleton = () => /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden p-6" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "space-y-6" }, Array.from({ length: 4 }).map((_, dayIdx) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: dayIdx }, /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-5 w-40 mb-4" }), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "space-y-3" }, Array.from({ length: 2 + Math.floor(Math.random() * 3) }).map((_2, eventIdx) => /* @__PURE__ */ React15__namespace.default.createElement("div", { key: eventIdx, className: "flex items-center gap-4 p-3 rounded-xl bg-muted/10" }, /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-10 w-10 rounded-lg" }), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 space-y-2" }, /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-4 w-3/4" }), /* @__PURE__ */ React15__namespace.default.createElement(Skeleton, { className: "h-3 w-1/2" })))))))));
2383
+ var AgendaViewSkeleton = () => /* @__PURE__ */ import_react15.default.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden p-6" }, /* @__PURE__ */ import_react15.default.createElement("div", { className: "space-y-6" }, Array.from({ length: 4 }).map((_, dayIdx) => /* @__PURE__ */ import_react15.default.createElement("div", { key: dayIdx }, /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-5 w-40 mb-4" }), /* @__PURE__ */ import_react15.default.createElement("div", { className: "space-y-3" }, Array.from({ length: 2 + Math.floor(Math.random() * 3) }).map((_2, eventIdx) => /* @__PURE__ */ import_react15.default.createElement("div", { key: eventIdx, className: "flex items-center gap-4 p-3 rounded-xl bg-muted/10" }, /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-10 w-10 rounded-lg" }), /* @__PURE__ */ import_react15.default.createElement("div", { className: "flex-1 space-y-2" }, /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-4 w-3/4" }), /* @__PURE__ */ import_react15.default.createElement(Skeleton, { className: "h-3 w-1/2" })))))))));
2384
+
2385
+ // src/components/ContextMenu.tsx
2386
+ var import_react16 = __toESM(require("react"));
2387
+ var import_lucide_react8 = require("lucide-react");
2388
+ var import_framer_motion3 = require("framer-motion");
1955
2389
  var EventContextMenu = ({
1956
2390
  event,
1957
2391
  position,
@@ -1962,8 +2396,8 @@ var EventContextMenu = ({
1962
2396
  customActions = [],
1963
2397
  translations
1964
2398
  }) => {
1965
- const menuRef = React15.useRef(null);
1966
- React15.useEffect(() => {
2399
+ const menuRef = (0, import_react16.useRef)(null);
2400
+ (0, import_react16.useEffect)(() => {
1967
2401
  const handleKeyDown = (e) => {
1968
2402
  if (e.key === "Escape") {
1969
2403
  onClose();
@@ -1974,7 +2408,7 @@ var EventContextMenu = ({
1974
2408
  return () => document.removeEventListener("keydown", handleKeyDown);
1975
2409
  }
1976
2410
  }, [position, onClose]);
1977
- React15.useEffect(() => {
2411
+ (0, import_react16.useEffect)(() => {
1978
2412
  const handleClickOutside = (e) => {
1979
2413
  if (menuRef.current && !menuRef.current.contains(e.target)) {
1980
2414
  onClose();
@@ -1992,7 +2426,7 @@ var EventContextMenu = ({
1992
2426
  ...onEdit ? [{
1993
2427
  id: "edit",
1994
2428
  label: translations?.edit || "Edit",
1995
- icon: /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Edit3, { className: "w-4 h-4" }),
2429
+ icon: /* @__PURE__ */ import_react16.default.createElement(import_lucide_react8.Edit3, { className: "w-4 h-4" }),
1996
2430
  onClick: () => {
1997
2431
  onEdit(event);
1998
2432
  onClose();
@@ -2001,7 +2435,7 @@ var EventContextMenu = ({
2001
2435
  ...onDuplicate ? [{
2002
2436
  id: "duplicate",
2003
2437
  label: translations?.duplicate || "Duplicate",
2004
- icon: /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Copy, { className: "w-4 h-4" }),
2438
+ icon: /* @__PURE__ */ import_react16.default.createElement(import_lucide_react8.Copy, { className: "w-4 h-4" }),
2005
2439
  onClick: () => {
2006
2440
  onDuplicate(event);
2007
2441
  onClose();
@@ -2011,7 +2445,7 @@ var EventContextMenu = ({
2011
2445
  ...onDelete ? [{
2012
2446
  id: "delete",
2013
2447
  label: translations?.delete || "Delete",
2014
- icon: /* @__PURE__ */ React15__namespace.default.createElement(lucideReact.Trash2, { className: "w-4 h-4" }),
2448
+ icon: /* @__PURE__ */ import_react16.default.createElement(import_lucide_react8.Trash2, { className: "w-4 h-4" }),
2015
2449
  onClick: () => {
2016
2450
  onDelete(event.id);
2017
2451
  onClose();
@@ -2023,8 +2457,8 @@ var EventContextMenu = ({
2023
2457
  x: Math.min(position.x, window.innerWidth - 200),
2024
2458
  y: Math.min(position.y, window.innerHeight - (actions.length * 44 + 80))
2025
2459
  };
2026
- return /* @__PURE__ */ React15__namespace.default.createElement(framerMotion.AnimatePresence, null, /* @__PURE__ */ React15__namespace.default.createElement(
2027
- framerMotion.motion.div,
2460
+ return /* @__PURE__ */ import_react16.default.createElement(import_framer_motion3.AnimatePresence, null, /* @__PURE__ */ import_react16.default.createElement(
2461
+ import_framer_motion3.motion.div,
2028
2462
  {
2029
2463
  ref: menuRef,
2030
2464
  initial: { opacity: 0, scale: 0.95, y: -5 },
@@ -2037,14 +2471,14 @@ var EventContextMenu = ({
2037
2471
  top: adjustedPosition.y
2038
2472
  }
2039
2473
  },
2040
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "px-3 py-2 border-b-[0.5px] border-border bg-muted/30" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React15__namespace.default.createElement(
2474
+ /* @__PURE__ */ import_react16.default.createElement("div", { className: "px-3 py-2 border-b-[0.5px] border-border bg-muted/30" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react16.default.createElement(
2041
2475
  "div",
2042
2476
  {
2043
2477
  className: "w-2.5 h-2.5 rounded-full shrink-0",
2044
2478
  style: { backgroundColor: event.color || "var(--primary)" }
2045
2479
  }
2046
- ), /* @__PURE__ */ React15__namespace.default.createElement("span", { className: "text-sm font-medium truncate text-foreground" }, event.title))),
2047
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "py-1" }, actions.map((action, index) => /* @__PURE__ */ React15__namespace.default.createElement(React15__namespace.default.Fragment, { key: action.id }, index > 0 && action.variant === "danger" && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "h-px bg-border my-1" }), /* @__PURE__ */ React15__namespace.default.createElement(
2480
+ ), /* @__PURE__ */ import_react16.default.createElement("span", { className: "text-sm font-medium truncate text-foreground" }, event.title))),
2481
+ /* @__PURE__ */ import_react16.default.createElement("div", { className: "py-1" }, actions.map((action, index) => /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, { key: action.id }, index > 0 && action.variant === "danger" && /* @__PURE__ */ import_react16.default.createElement("div", { className: "h-px bg-border my-1" }), /* @__PURE__ */ import_react16.default.createElement(
2048
2482
  "button",
2049
2483
  {
2050
2484
  onClick: action.onClick,
@@ -2056,13 +2490,13 @@ var EventContextMenu = ({
2056
2490
  )
2057
2491
  },
2058
2492
  action.icon,
2059
- /* @__PURE__ */ React15__namespace.default.createElement("span", null, action.label)
2493
+ /* @__PURE__ */ import_react16.default.createElement("span", null, action.label)
2060
2494
  ))))
2061
2495
  ));
2062
2496
  };
2063
2497
  var useEventContextMenu = () => {
2064
- const [contextMenu, setContextMenu] = React15.useState({ event: null, position: null });
2065
- const openContextMenu = React15.useCallback((event, e) => {
2498
+ const [contextMenu, setContextMenu] = (0, import_react16.useState)({ event: null, position: null });
2499
+ const openContextMenu = (0, import_react16.useCallback)((event, e) => {
2066
2500
  e.preventDefault();
2067
2501
  e.stopPropagation();
2068
2502
  setContextMenu({
@@ -2070,7 +2504,7 @@ var useEventContextMenu = () => {
2070
2504
  position: { x: e.clientX, y: e.clientY }
2071
2505
  });
2072
2506
  }, []);
2073
- const closeContextMenu = React15.useCallback(() => {
2507
+ const closeContextMenu = (0, import_react16.useCallback)(() => {
2074
2508
  setContextMenu({ event: null, position: null });
2075
2509
  }, []);
2076
2510
  return {
@@ -2081,146 +2515,6 @@ var useEventContextMenu = () => {
2081
2515
  };
2082
2516
  };
2083
2517
 
2084
- // src/locales/index.ts
2085
- var en = {
2086
- today: "Today",
2087
- month: "Month",
2088
- week: "Week",
2089
- day: "Day",
2090
- agenda: "Agenda",
2091
- resource: "Resources",
2092
- createEvent: "Create Event",
2093
- editEvent: "Edit Event",
2094
- delete: "Delete",
2095
- save: "Save",
2096
- cancel: "Cancel",
2097
- title: "Add title",
2098
- start: "Start",
2099
- end: "End",
2100
- allDay: "All Day",
2101
- description: "Description",
2102
- repeat: "Repeat",
2103
- noRepeat: "Does not repeat",
2104
- selectCalendar: "Select Calendar",
2105
- selectType: "Select Type",
2106
- daily: "Daily",
2107
- weekly: "Weekly",
2108
- monthly: "Monthly",
2109
- yearly: "Yearly",
2110
- search: "Search events...",
2111
- allTypes: "All Types",
2112
- timezone: "Time zone",
2113
- localTime: "Local Time",
2114
- create: "Create",
2115
- calendars: "Calendars",
2116
- event: "Event",
2117
- task: "Task",
2118
- appointmentSchedule: "Appointment schedule",
2119
- new: "New",
2120
- dateAndTime: "Date & Time",
2121
- whosJoining: "Who's joining?",
2122
- suggestedTimes: "Suggested times for guests",
2123
- viewSuggestions: "View suggestions",
2124
- whereWillItBe: "Where will it be?",
2125
- location: "Enter address",
2126
- descriptionAndAttachments: "Description",
2127
- dragAndDrop: "Drag & drop files or",
2128
- guests: "Guests",
2129
- addGuests: "Add guests",
2130
- addAttachment: "Upload files",
2131
- moreOptions: "More options",
2132
- doesNotRepeat: "Does not repeat",
2133
- locationHelpText: 'Enter a physical address (e.g. "123 Main St") to generate the map.',
2134
- notes: "Notes...",
2135
- guestCount: "guest",
2136
- guestsCount: "guests",
2137
- repeatFor: "Repeat for",
2138
- times: "times",
2139
- until: "Until",
2140
- endRepeat: "End repeat",
2141
- never: "Never",
2142
- afterOccurrences: "After occurrences",
2143
- onDate: "On date",
2144
- tomorrow: "Tomorrow",
2145
- edit: "Edit",
2146
- duplicate: "Duplicate",
2147
- eventSingular: "event",
2148
- eventPlural: "events",
2149
- allCaughtUp: "All caught up!",
2150
- noEventsScheduled: "No events scheduled",
2151
- noUpcoming: "Your schedule is clear",
2152
- noUpcomingHint: "No upcoming events to show. Create a new event to start planning."
2153
- };
2154
- var fr = {
2155
- today: "Aujourd'hui",
2156
- month: "Mois",
2157
- week: "Semaine",
2158
- day: "Jour",
2159
- agenda: "Agenda",
2160
- resource: "Ressources",
2161
- createEvent: "Cr\xE9er un \xE9v\xE9nement",
2162
- editEvent: "Modifier l'\xE9v\xE9nement",
2163
- delete: "Supprimer",
2164
- save: "Enregistrer",
2165
- cancel: "Annuler",
2166
- title: "Ajouter un titre",
2167
- start: "D\xE9but",
2168
- end: "Fin",
2169
- allDay: "Toute la journ\xE9e",
2170
- description: "Description",
2171
- repeat: "R\xE9p\xE9ter",
2172
- noRepeat: "Ne se r\xE9p\xE8te pas",
2173
- selectCalendar: "S\xE9lectionner un calendrier",
2174
- selectType: "S\xE9lectionner un type",
2175
- daily: "Quotidien",
2176
- weekly: "Hebdomadaire",
2177
- monthly: "Mensuel",
2178
- yearly: "Annuel",
2179
- search: "Rechercher...",
2180
- allTypes: "Tous les types",
2181
- timezone: "Fuseau horaire",
2182
- localTime: "Heure locale",
2183
- create: "Cr\xE9er",
2184
- calendars: "Calendriers",
2185
- event: "\xC9v\xE9nement",
2186
- task: "T\xE2che",
2187
- appointmentSchedule: "Planning de rendez-vous",
2188
- new: "Nouveau",
2189
- dateAndTime: "Date et heure",
2190
- whosJoining: "Qui participe ?",
2191
- suggestedTimes: "Horaires sugg\xE9r\xE9s",
2192
- viewSuggestions: "Voir les suggestions",
2193
- whereWillItBe: "O\xF9 aura lieu ?",
2194
- location: "Entrer une adresse",
2195
- descriptionAndAttachments: "Description",
2196
- dragAndDrop: "Glisser-d\xE9poser des fichiers ou",
2197
- guests: "Invit\xE9s",
2198
- addGuests: "Ajouter des invit\xE9s",
2199
- addAttachment: "T\xE9l\xE9charger des fichiers",
2200
- moreOptions: "Plus d'options",
2201
- doesNotRepeat: "Ne se r\xE9p\xE8te pas",
2202
- locationHelpText: 'Entrez une adresse physique (ex: "123 Rue Principale") pour g\xE9n\xE9rer la carte.',
2203
- notes: "Notes...",
2204
- guestCount: "invit\xE9",
2205
- guestsCount: "invit\xE9s",
2206
- repeatFor: "R\xE9p\xE9ter pendant",
2207
- times: "fois",
2208
- until: "Jusqu'au",
2209
- endRepeat: "Fin de r\xE9p\xE9tition",
2210
- never: "Jamais",
2211
- afterOccurrences: "Apr\xE8s occurrences",
2212
- onDate: "\xC0 la date",
2213
- tomorrow: "Demain",
2214
- edit: "Modifier",
2215
- duplicate: "Dupliquer",
2216
- eventSingular: "\xE9v\xE9nement",
2217
- eventPlural: "\xE9v\xE9nements",
2218
- allCaughtUp: "Tout est \xE0 jour !",
2219
- noEventsScheduled: "Aucun \xE9v\xE9nement pr\xE9vu",
2220
- noUpcoming: "Votre planning est libre",
2221
- noUpcomingHint: "Aucun \xE9v\xE9nement \xE0 venir. Cr\xE9ez un nouvel \xE9v\xE9nement pour commencer \xE0 planifier."
2222
- };
2223
-
2224
2518
  // src/lib/theme.ts
2225
2519
  function colorToHsl(color) {
2226
2520
  let r = 0, g = 0, b = 0;
@@ -2246,7 +2540,7 @@ function colorToHsl(color) {
2246
2540
  const min = Math.min(r, g, b);
2247
2541
  let h = 0;
2248
2542
  let s = 0;
2249
- let l = (max + min) / 2;
2543
+ const l = (max + min) / 2;
2250
2544
  if (max !== min) {
2251
2545
  const d = max - min;
2252
2546
  s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
@@ -2299,6 +2593,151 @@ function getThemeStyles(theme) {
2299
2593
  }
2300
2594
  return styles;
2301
2595
  }
2596
+
2597
+ // src/hooks/useCalendarLogic.ts
2598
+ var import_react18 = require("react");
2599
+ var import_date_fns15 = require("date-fns");
2600
+
2601
+ // src/core/recurrence.ts
2602
+ var import_date_fns14 = require("date-fns");
2603
+ var import_rrule = require("rrule");
2604
+ var WEEKDAYS = [import_rrule.RRule.MO, import_rrule.RRule.TU, import_rrule.RRule.WE, import_rrule.RRule.TH, import_rrule.RRule.FR, import_rrule.RRule.SA, import_rrule.RRule.SU];
2605
+ var toFloating = (instant, tz) => {
2606
+ const w = toDisplay(instant, tz);
2607
+ return new Date(Date.UTC(w.getFullYear(), w.getMonth(), w.getDate(), w.getHours(), w.getMinutes(), w.getSeconds(), w.getMilliseconds()));
2608
+ };
2609
+ var fromFloating = (floating, tz) => fromDisplay(
2610
+ new Date(
2611
+ floating.getUTCFullYear(),
2612
+ floating.getUTCMonth(),
2613
+ floating.getUTCDate(),
2614
+ floating.getUTCHours(),
2615
+ floating.getUTCMinutes(),
2616
+ floating.getUTCSeconds(),
2617
+ floating.getUTCMilliseconds()
2618
+ ),
2619
+ tz
2620
+ );
2621
+ var minuteKey = (date) => Math.floor(date.getTime() / 6e4);
2622
+ var FREQUENCIES = { DAILY: import_rrule.RRule.DAILY, WEEKLY: import_rrule.RRule.WEEKLY, MONTHLY: import_rrule.RRule.MONTHLY, YEARLY: import_rrule.RRule.YEARLY };
2623
+ function buildRule(event, tz) {
2624
+ const r = event.recurrence;
2625
+ const freq = FREQUENCIES[r.freq];
2626
+ if (freq === void 0) throw new Error(`unsupported frequency "${r.freq}"`);
2627
+ return new import_rrule.RRule({
2628
+ freq,
2629
+ interval: r.interval || 1,
2630
+ dtstart: toFloating(event.start, tz),
2631
+ until: r.until ? toFloating(r.until, tz) : void 0,
2632
+ count: r.count,
2633
+ byweekday: r.byweekday?.length ? r.byweekday.map((d) => WEEKDAYS[d]) : void 0
2634
+ });
2635
+ }
2636
+ function occurrencesInMonth(event, monthStart, tz) {
2637
+ const rule = buildRule(event, tz);
2638
+ const excluded = new Set((event.recurrence.exdates ?? []).map(minuteKey));
2639
+ const duration = event.end.getTime() - event.start.getTime();
2640
+ const from = toFloating(monthStart, tz);
2641
+ const to = toFloating((0, import_date_fns14.addMonths)(monthStart, 1), tz);
2642
+ const result = [];
2643
+ for (const floating of rule.between(from, to, true)) {
2644
+ if (floating.getTime() === to.getTime()) continue;
2645
+ const start = fromFloating(floating, tz);
2646
+ if (excluded.has(minuteKey(start))) continue;
2647
+ result.push({
2648
+ ...event,
2649
+ id: `${event.id}-${start.getTime()}`,
2650
+ originalEventId: event.id,
2651
+ occurrenceStart: start,
2652
+ start,
2653
+ end: new Date(start.getTime() + duration)
2654
+ });
2655
+ }
2656
+ return result;
2657
+ }
2658
+ var MAX_MONTHS_PER_EVENT = 12;
2659
+ var occurrenceCache = /* @__PURE__ */ new WeakMap();
2660
+ function cachedMonth(event, monthStart, tz) {
2661
+ let months = occurrenceCache.get(event);
2662
+ if (!months) {
2663
+ months = /* @__PURE__ */ new Map();
2664
+ occurrenceCache.set(event, months);
2665
+ }
2666
+ const key = `${monthStart.getFullYear()}-${monthStart.getMonth()}|${tz ?? ""}`;
2667
+ let occurrences = months.get(key);
2668
+ if (occurrences) {
2669
+ months.delete(key);
2670
+ } else {
2671
+ occurrences = occurrencesInMonth(event, monthStart, tz);
2672
+ if (months.size >= MAX_MONTHS_PER_EVENT) months.delete(months.keys().next().value);
2673
+ }
2674
+ months.set(key, occurrences);
2675
+ return occurrences;
2676
+ }
2677
+ function expandRecurrences(events, range, anchorTz) {
2678
+ const result = [];
2679
+ const firstMonth = (0, import_date_fns14.startOfMonth)(toDisplay(range.start, anchorTz));
2680
+ const lastMonth = (0, import_date_fns14.startOfMonth)(toDisplay(range.end, anchorTz));
2681
+ for (const event of events) {
2682
+ if (!event.recurrence) {
2683
+ result.push(event);
2684
+ continue;
2685
+ }
2686
+ try {
2687
+ for (let month = firstMonth; month <= lastMonth; month = (0, import_date_fns14.addMonths)(month, 1)) {
2688
+ for (const occurrence of cachedMonth(event, fromDisplay(month, anchorTz), anchorTz)) {
2689
+ if (occurrence.end >= range.start && occurrence.start <= range.end) result.push(occurrence);
2690
+ }
2691
+ }
2692
+ } catch (error) {
2693
+ warnOnce(`invalid-recurrence:${event.id}`, `Event "${event.id}" has an invalid recurrence rule: ${String(error)}`);
2694
+ result.push(event);
2695
+ }
2696
+ }
2697
+ return result;
2698
+ }
2699
+ function stripOccurrenceFields(event) {
2700
+ const { originalEventId: _originalEventId, occurrenceStart: _occurrenceStart, ...rest } = event;
2701
+ return rest;
2702
+ }
2703
+ var shiftFloating = (instant, deltaMs, tz) => fromFloating(new Date(toFloating(instant, tz).getTime() + deltaMs), tz);
2704
+ var DAY_MS = 24 * 60 * 60 * 1e3;
2705
+ var floatingDay = (floating) => Math.floor(floating.getTime() / DAY_MS);
2706
+ function shiftSeries(master, occurrence, newStart, newEnd, anchorTz) {
2707
+ const fromFloat = toFloating(occurrence.start, anchorTz);
2708
+ const toFloat = toFloating(newStart, anchorTz);
2709
+ const deltaMs = toFloat.getTime() - fromFloat.getTime();
2710
+ const dayDelta = floatingDay(toFloat) - floatingDay(fromFloat);
2711
+ const start = shiftFloating(master.start, deltaMs, anchorTz);
2712
+ const end = new Date(start.getTime() + (newEnd.getTime() - newStart.getTime()));
2713
+ const recurrence = master.recurrence && {
2714
+ ...master.recurrence,
2715
+ byweekday: master.recurrence.byweekday && dayDelta % 7 !== 0 ? master.recurrence.byweekday.map((d) => ((d + dayDelta) % 7 + 7) % 7) : master.recurrence.byweekday,
2716
+ exdates: master.recurrence.exdates?.map((d) => shiftFloating(d, deltaMs, anchorTz))
2717
+ };
2718
+ return stripOccurrenceFields({ ...master, start, end, recurrence });
2719
+ }
2720
+ function excludeOccurrence(master, occurrenceStart) {
2721
+ const recurrence = master.recurrence ?? { freq: "DAILY" };
2722
+ return { ...master, recurrence: { ...recurrence, exdates: [...recurrence.exdates ?? [], occurrenceStart] } };
2723
+ }
2724
+
2725
+ // src/hooks/useStableCallback.ts
2726
+ var import_react17 = require("react");
2727
+ function useStableCallback(fn) {
2728
+ const ref = (0, import_react17.useRef)(fn);
2729
+ ref.current = fn;
2730
+ return (0, import_react17.useCallback)((...args) => ref.current(...args), []);
2731
+ }
2732
+
2733
+ // src/hooks/useCalendarLogic.ts
2734
+ function expansionRange(monthStart) {
2735
+ return {
2736
+ start: (0, import_date_fns15.startOfWeek)((0, import_date_fns15.startOfMonth)((0, import_date_fns15.subMonths)(monthStart, 1))),
2737
+ end: (0, import_date_fns15.addDays)((0, import_date_fns15.endOfMonth)((0, import_date_fns15.addMonths)(monthStart, 1)), 37)
2738
+ };
2739
+ }
2740
+ var DAY_MS2 = 24 * 60 * 60 * 1e3;
2302
2741
  var useCalendarLogic = ({
2303
2742
  events,
2304
2743
  view: controlledView,
@@ -2309,211 +2748,192 @@ var useCalendarLogic = ({
2309
2748
  onEventUpdate,
2310
2749
  onEventCreate,
2311
2750
  onEventDelete,
2751
+ onEventDrop,
2752
+ onEventResize,
2753
+ onOccurrenceDelete,
2312
2754
  readOnly,
2313
2755
  timezone
2314
2756
  }) => {
2315
- const [internalView, setInternalView] = React15.useState("week");
2316
- const [internalDate, setInternalDate] = React15.useState(/* @__PURE__ */ new Date());
2317
- const [isSidebarOpen, setIsSidebarOpen] = React15.useState(true);
2318
- const [isModalOpen, setIsModalOpen] = React15.useState(false);
2319
- const [selectedEvent, setSelectedEvent] = React15.useState(null);
2320
- const [modalInitialDate, setModalInitialDate] = React15.useState(void 0);
2757
+ const [internalView, setInternalView] = (0, import_react18.useState)("week");
2758
+ const [internalDate, setInternalDate] = (0, import_react18.useState)(() => /* @__PURE__ */ new Date());
2759
+ const [isSidebarOpen, setIsSidebarOpen] = (0, import_react18.useState)(true);
2760
+ const [isModalOpen, setIsModalOpen] = (0, import_react18.useState)(false);
2761
+ const [selectedEvent, setSelectedEvent] = (0, import_react18.useState)(null);
2762
+ const [modalInitialDate, setModalInitialDate] = (0, import_react18.useState)(void 0);
2763
+ const [modalInitialResourceId, setModalInitialResourceId] = (0, import_react18.useState)(void 0);
2321
2764
  const view = controlledView ?? internalView;
2322
2765
  const currentDate = controlledDate ?? internalDate;
2323
- const expandedEvents = React15.useMemo(() => {
2324
- const allEvents = [];
2325
- const rangeStart = dateFns.subDays(currentDate, 365);
2326
- const rangeEnd = dateFns.addDays(currentDate, 365);
2327
- events.forEach((event) => {
2328
- if (event.recurrence) {
2329
- try {
2330
- const rule = new rrule.RRule({
2331
- freq: rrule.RRule[event.recurrence.freq],
2332
- interval: event.recurrence.interval || 1,
2333
- dtstart: new Date(event.start),
2334
- until: event.recurrence.until ? new Date(event.recurrence.until) : void 0,
2335
- count: event.recurrence.count
2336
- });
2337
- const dates = rule.between(rangeStart, rangeEnd);
2338
- dates.forEach((date) => {
2339
- const duration = dateFns.differenceInMilliseconds(new Date(event.end), new Date(event.start));
2340
- allEvents.push({
2341
- ...event,
2342
- id: `${event.id}-${date.getTime()}`,
2343
- // Unique ID for each instance
2344
- originalEventId: event.id,
2345
- // Reference to original
2346
- start: date,
2347
- end: new Date(date.getTime() + duration)
2348
- });
2349
- });
2350
- } catch (e) {
2351
- console.error("Error parsing recurrence rule", e);
2352
- allEvents.push(event);
2353
- }
2354
- } else {
2355
- allEvents.push(event);
2356
- }
2357
- });
2358
- return allEvents;
2359
- }, [events, currentDate]);
2360
- const handleViewChange = (newView) => {
2766
+ const normalizedEvents = (0, import_react18.useMemo)(() => normalizeEvents(events), [events]);
2767
+ const monthKey = (0, import_date_fns15.format)(currentDate, "yyyy-MM");
2768
+ const range = (0, import_react18.useMemo)(() => expansionRange(/* @__PURE__ */ new Date(`${monthKey}-01T00:00:00`)), [monthKey]);
2769
+ const expandedEvents = (0, import_react18.useMemo)(
2770
+ () => expandRecurrences(normalizedEvents, range, timezone),
2771
+ [normalizedEvents, range, timezone]
2772
+ );
2773
+ const masterOf = (occurrence) => normalizedEvents.find((e) => e.id === occurrence.originalEventId);
2774
+ const handleViewChange = useStableCallback((newView) => {
2361
2775
  if (controlledOnViewChange) {
2362
2776
  controlledOnViewChange(newView);
2363
2777
  } else {
2364
2778
  setInternalView(newView);
2365
2779
  }
2366
- };
2367
- const handleDateChange = (newDate) => {
2780
+ });
2781
+ const handleDateChange = useStableCallback((newDate) => {
2368
2782
  if (controlledOnDateChange) {
2369
2783
  controlledOnDateChange(newDate);
2370
2784
  } else {
2371
2785
  setInternalDate(newDate);
2372
2786
  }
2373
- };
2374
- const handlePrev = () => {
2787
+ });
2788
+ const handlePrev = useStableCallback(() => {
2375
2789
  switch (view) {
2376
2790
  case "month":
2377
- handleDateChange(dateFns.subMonths(currentDate, 1));
2791
+ handleDateChange((0, import_date_fns15.subMonths)(currentDate, 1));
2378
2792
  break;
2379
2793
  case "week":
2380
- handleDateChange(dateFns.subWeeks(currentDate, 1));
2794
+ handleDateChange((0, import_date_fns15.subWeeks)(currentDate, 1));
2381
2795
  break;
2382
2796
  case "day":
2383
2797
  case "resource":
2384
- handleDateChange(dateFns.subDays(currentDate, 1));
2798
+ handleDateChange((0, import_date_fns15.subDays)(currentDate, 1));
2385
2799
  break;
2386
2800
  case "agenda":
2387
- handleDateChange(dateFns.subDays(currentDate, 7));
2801
+ handleDateChange((0, import_date_fns15.subDays)(currentDate, 7));
2388
2802
  break;
2389
2803
  }
2390
- };
2391
- const handleNext = () => {
2804
+ });
2805
+ const handleNext = useStableCallback(() => {
2392
2806
  switch (view) {
2393
2807
  case "month":
2394
- handleDateChange(dateFns.addMonths(currentDate, 1));
2808
+ handleDateChange((0, import_date_fns15.addMonths)(currentDate, 1));
2395
2809
  break;
2396
2810
  case "week":
2397
- handleDateChange(dateFns.addWeeks(currentDate, 1));
2811
+ handleDateChange((0, import_date_fns15.addWeeks)(currentDate, 1));
2398
2812
  break;
2399
2813
  case "day":
2400
2814
  case "resource":
2401
- handleDateChange(dateFns.addDays(currentDate, 1));
2815
+ handleDateChange((0, import_date_fns15.addDays)(currentDate, 1));
2402
2816
  break;
2403
2817
  case "agenda":
2404
- handleDateChange(dateFns.addDays(currentDate, 7));
2818
+ handleDateChange((0, import_date_fns15.addDays)(currentDate, 7));
2405
2819
  break;
2406
2820
  }
2407
- };
2408
- const handleToday = () => {
2821
+ });
2822
+ const handleToday = useStableCallback(() => {
2409
2823
  handleDateChange(/* @__PURE__ */ new Date());
2410
- };
2411
- const handleDateClick = (date) => {
2824
+ });
2825
+ const handleDateClick = useStableCallback((date) => {
2412
2826
  handleDateChange(date);
2413
2827
  handleViewChange("day");
2414
- };
2415
- const handleTimeSlotClick = (date) => {
2828
+ });
2829
+ const handleTimeSlotClick = useStableCallback((date, resourceId) => {
2416
2830
  if (readOnly) return;
2417
2831
  setSelectedEvent(null);
2418
2832
  setModalInitialDate(date);
2833
+ setModalInitialResourceId(resourceId);
2419
2834
  setIsModalOpen(true);
2420
- };
2421
- const handleEventClickInternal = (event) => {
2422
- if (onEventClick) {
2423
- onEventClick(event);
2424
- }
2835
+ });
2836
+ const handleEventClickInternal = useStableCallback((event) => {
2837
+ onEventClick?.(event);
2425
2838
  if (!readOnly) {
2426
2839
  setSelectedEvent(event);
2427
2840
  setModalInitialDate(void 0);
2841
+ setModalInitialResourceId(void 0);
2428
2842
  setIsModalOpen(true);
2429
2843
  }
2430
- };
2431
- const handleCreateEvent = () => {
2844
+ });
2845
+ const handleCreateEvent = useStableCallback(() => {
2432
2846
  if (readOnly) return;
2433
2847
  setSelectedEvent(null);
2434
2848
  setModalInitialDate(/* @__PURE__ */ new Date());
2849
+ setModalInitialResourceId(void 0);
2435
2850
  setIsModalOpen(true);
2436
- };
2437
- const handleModalSave = (eventData) => {
2438
- let effectiveEventId = selectedEvent?.id;
2851
+ });
2852
+ const handleModalSave = useStableCallback((eventData) => {
2439
2853
  if (selectedEvent?.originalEventId) {
2440
- effectiveEventId = selectedEvent.originalEventId;
2441
- }
2442
- if (effectiveEventId) {
2443
- if (onEventUpdate) {
2444
- onEventUpdate({
2445
- ...eventData,
2446
- id: effectiveEventId
2447
- });
2448
- }
2854
+ const master = masterOf(selectedEvent);
2855
+ if (!master) return;
2856
+ const edited = {
2857
+ ...master,
2858
+ ...stripOccurrenceFields(eventData),
2859
+ id: master.id,
2860
+ start: master.start,
2861
+ end: master.end
2862
+ };
2863
+ onEventUpdate?.(
2864
+ shiftSeries(edited, selectedEvent, eventData.start ?? selectedEvent.start, eventData.end ?? selectedEvent.end, timezone)
2865
+ );
2866
+ } else if (selectedEvent) {
2867
+ onEventUpdate?.({ ...eventData, id: selectedEvent.id });
2449
2868
  } else {
2450
- if (onEventCreate) {
2451
- onEventCreate(eventData);
2452
- }
2453
- }
2454
- };
2455
- const handleModalDelete = (eventId) => {
2456
- let effectiveEventId = eventId;
2457
- if (selectedEvent?.originalEventId && selectedEvent.id === eventId) {
2458
- effectiveEventId = selectedEvent.originalEventId;
2869
+ onEventCreate?.(
2870
+ modalInitialResourceId && eventData.resourceId === void 0 ? { ...eventData, resourceId: modalInitialResourceId } : eventData
2871
+ );
2459
2872
  }
2460
- if (onEventDelete) {
2461
- onEventDelete(effectiveEventId);
2873
+ });
2874
+ const handleEventDelete = useStableCallback((event) => {
2875
+ if (!event.originalEventId) {
2876
+ onEventDelete?.(event.id);
2877
+ return;
2462
2878
  }
2463
- };
2464
- const handleDragEnd = (event) => {
2465
- const { active, over } = event;
2466
- if (!over) return;
2467
- const activeEvent = active.data.current?.event;
2468
- const overDate = over.data.current?.date;
2469
- if (!activeEvent || !overDate) return;
2470
- const originalStart = new Date(activeEvent.start);
2471
- const originalEnd = new Date(activeEvent.end);
2472
- const duration = dateFns.differenceInMilliseconds(originalEnd, originalStart);
2473
- let newStart;
2474
- if (view === "month") {
2475
- if (timezone) {
2476
- const zonedOriginal = dateFnsTz.toZonedTime(originalStart, timezone);
2477
- const zonedNew = new Date(overDate);
2478
- zonedNew.setHours(zonedOriginal.getHours());
2479
- zonedNew.setMinutes(zonedOriginal.getMinutes());
2480
- zonedNew.setSeconds(zonedOriginal.getSeconds());
2481
- zonedNew.setMilliseconds(zonedOriginal.getMilliseconds());
2482
- newStart = dateFnsTz.fromZonedTime(zonedNew, timezone);
2483
- } else {
2484
- newStart = new Date(overDate);
2485
- newStart.setHours(originalStart.getHours());
2486
- newStart.setMinutes(originalStart.getMinutes());
2487
- newStart.setSeconds(originalStart.getSeconds());
2488
- newStart.setMilliseconds(originalStart.getMilliseconds());
2489
- }
2879
+ const master = masterOf(event);
2880
+ if (onOccurrenceDelete && master) {
2881
+ onOccurrenceDelete(event, excludeOccurrence(master, event.occurrenceStart ?? event.start));
2490
2882
  } else {
2491
- if (timezone) {
2492
- newStart = dateFnsTz.fromZonedTime(overDate, timezone);
2493
- } else {
2494
- newStart = new Date(overDate);
2495
- }
2496
- newStart.setSeconds(0);
2497
- newStart.setMilliseconds(0);
2498
- }
2499
- const newEnd = new Date(newStart.getTime() + duration);
2500
- let newResourceId = activeEvent.resourceId;
2501
- const overResourceId = over.data.current?.resourceId;
2502
- if (overResourceId) {
2503
- newResourceId = overResourceId;
2504
- }
2505
- if (newStart.getTime() === originalStart.getTime() && newEnd.getTime() === originalEnd.getTime() && newResourceId === activeEvent.resourceId) {
2506
- return;
2883
+ onEventDelete?.(event.originalEventId);
2507
2884
  }
2508
- if (onEventUpdate) {
2509
- onEventUpdate({
2510
- ...activeEvent,
2511
- start: newStart,
2512
- end: newEnd,
2513
- resourceId: newResourceId
2514
- });
2885
+ });
2886
+ const handleModalDelete = useStableCallback((eventId) => {
2887
+ if (selectedEvent && selectedEvent.id === eventId) {
2888
+ handleEventDelete(selectedEvent);
2889
+ } else {
2890
+ onEventDelete?.(eventId);
2515
2891
  }
2892
+ });
2893
+ const handleEventDuplicate = useStableCallback((event) => {
2894
+ const { recurrence: _recurrence, ...copy } = stripOccurrenceFields(event);
2895
+ onEventCreate?.({
2896
+ ...copy,
2897
+ id: `${event.originalEventId ?? event.id}-copy-${Date.now()}`,
2898
+ title: `${event.title} (Copy)`,
2899
+ start: new Date(event.start.getTime() + DAY_MS2),
2900
+ end: new Date(event.end.getTime() + DAY_MS2)
2901
+ });
2902
+ });
2903
+ const applyChange = (event, start, end) => {
2904
+ if (!event.originalEventId) return { original: event, updated: { ...event, start, end } };
2905
+ const master = masterOf(event);
2906
+ if (!master) return null;
2907
+ return { original: master, updated: shiftSeries(master, event, start, end, timezone) };
2516
2908
  };
2909
+ const handleDragEnd = useStableCallback((dragEvent) => {
2910
+ const { active, over } = dragEvent;
2911
+ if (!over) return;
2912
+ const dragged = active.data.current?.event;
2913
+ const overDate = over.data.current?.date;
2914
+ if (!dragged || !overDate) return;
2915
+ const drop = computeDrop({
2916
+ event: dragged,
2917
+ overDate,
2918
+ overResourceId: over.data.current?.resourceId,
2919
+ grabOffsetMs: active.data.current?.grabOffsetMs,
2920
+ view,
2921
+ tz: timezone
2922
+ });
2923
+ if (!drop) return;
2924
+ const change = applyChange(dragged, drop.start, drop.end);
2925
+ if (!change) return;
2926
+ const updated = { ...change.updated, resourceId: drop.resourceId };
2927
+ onEventDrop?.(change.original, updated.start, updated.end);
2928
+ onEventUpdate?.(updated);
2929
+ });
2930
+ const handleEventResize = useStableCallback((event, newEnd) => {
2931
+ if (readOnly) return;
2932
+ const change = applyChange(event, event.start, newEnd);
2933
+ if (!change) return;
2934
+ onEventResize?.(change.original, change.updated.start, change.updated.end);
2935
+ onEventUpdate?.(change.updated);
2936
+ });
2517
2937
  return {
2518
2938
  view,
2519
2939
  currentDate,
@@ -2535,9 +2955,18 @@ var useCalendarLogic = ({
2535
2955
  handleCreateEvent,
2536
2956
  handleModalSave,
2537
2957
  handleModalDelete,
2958
+ handleEventDelete,
2959
+ handleEventDuplicate,
2960
+ handleEventResize,
2538
2961
  handleDragEnd
2539
2962
  };
2540
2963
  };
2964
+
2965
+ // src/index.tsx
2966
+ var import_date_fns16 = require("date-fns");
2967
+
2968
+ // src/hooks/useSwipeGesture.ts
2969
+ var import_react19 = require("react");
2541
2970
  var useSwipeGesture = (options) => {
2542
2971
  const {
2543
2972
  onSwipeLeft,
@@ -2549,9 +2978,9 @@ var useSwipeGesture = (options) => {
2549
2978
  allowedTime = 500,
2550
2979
  enabled = true
2551
2980
  } = options;
2552
- const touchInfoRef = React15.useRef(null);
2553
- const elementRef = React15.useRef(null);
2554
- const handleTouchStart = React15.useCallback((e) => {
2981
+ const touchInfoRef = (0, import_react19.useRef)(null);
2982
+ const elementRef = (0, import_react19.useRef)(null);
2983
+ const handleTouchStart = (0, import_react19.useCallback)((e) => {
2555
2984
  if (!enabled) return;
2556
2985
  const touch = e.touches[0];
2557
2986
  touchInfoRef.current = {
@@ -2560,7 +2989,7 @@ var useSwipeGesture = (options) => {
2560
2989
  startTime: Date.now()
2561
2990
  };
2562
2991
  }, [enabled]);
2563
- const handleTouchEnd = React15.useCallback((e) => {
2992
+ const handleTouchEnd = (0, import_react19.useCallback)((e) => {
2564
2993
  if (!enabled || !touchInfoRef.current) return;
2565
2994
  const touch = e.changedTouches[0];
2566
2995
  const { startX, startY, startTime } = touchInfoRef.current;
@@ -2584,7 +3013,7 @@ var useSwipeGesture = (options) => {
2584
3013
  }
2585
3014
  touchInfoRef.current = null;
2586
3015
  }, [enabled, threshold, restraint, allowedTime, onSwipeLeft, onSwipeRight, onSwipeUp, onSwipeDown]);
2587
- React15.useEffect(() => {
3016
+ (0, import_react19.useEffect)(() => {
2588
3017
  const element = elementRef.current;
2589
3018
  if (!element) return;
2590
3019
  element.addEventListener("touchstart", handleTouchStart, { passive: true });
@@ -2618,7 +3047,9 @@ var Scheduler = ({
2618
3047
  onEventCreate,
2619
3048
  onEventUpdate,
2620
3049
  onEventDelete,
3050
+ onEventDrop,
2621
3051
  onEventResize,
3052
+ onOccurrenceDelete,
2622
3053
  timezone,
2623
3054
  onTimezoneChange,
2624
3055
  className,
@@ -2640,7 +3071,7 @@ var Scheduler = ({
2640
3071
  locale
2641
3072
  // Date-fns locale
2642
3073
  }) => {
2643
- const [activeDragEvent, setActiveDragEvent] = React15.useState(null);
3074
+ const [activeDragEvent, setActiveDragEvent] = (0, import_react20.useState)(null);
2644
3075
  const {
2645
3076
  contextMenuEvent,
2646
3077
  contextMenuPosition,
@@ -2666,9 +3097,11 @@ var Scheduler = ({
2666
3097
  handleCreateEvent,
2667
3098
  handleModalSave,
2668
3099
  handleModalDelete,
3100
+ handleEventDelete,
3101
+ handleEventDuplicate,
3102
+ handleEventResize,
2669
3103
  handleDragEnd,
2670
3104
  expandedEvents
2671
- // New export
2672
3105
  } = useCalendarLogic({
2673
3106
  events,
2674
3107
  view: controlledView,
@@ -2679,71 +3112,57 @@ var Scheduler = ({
2679
3112
  onEventUpdate,
2680
3113
  onEventCreate,
2681
3114
  onEventDelete,
3115
+ onEventDrop,
3116
+ onEventResize,
3117
+ onOccurrenceDelete,
2682
3118
  readOnly,
2683
3119
  timezone
2684
3120
  });
2685
- const sensors = core.useSensors(
2686
- core.useSensor(core.PointerSensor, {
3121
+ const sensors = (0, import_core3.useSensors)(
3122
+ (0, import_core3.useSensor)(import_core3.PointerSensor, {
2687
3123
  activationConstraint: {
2688
3124
  distance: 8
2689
3125
  }
2690
3126
  })
2691
3127
  );
2692
3128
  const gridSize = 15;
2693
- const snapToGrid = modifiers.createSnapModifier(gridSize);
2694
- const modifiers$1 = [snapToGrid, modifiers.restrictToWindowEdges];
3129
+ const snapToGrid = (0, import_modifiers.createSnapModifier)(gridSize);
3130
+ const modifiers = [snapToGrid, import_modifiers.restrictToWindowEdges];
2695
3131
  const dndSensors = readOnly ? [] : sensors;
2696
- const handleEventResize = (event, newEnd) => {
2697
- if (readOnly) return;
2698
- if (onEventResize) {
2699
- onEventResize(event, event.start, newEnd);
2700
- }
2701
- if (onEventUpdate) {
2702
- onEventUpdate({
2703
- ...event,
2704
- end: newEnd
2705
- });
2706
- }
2707
- };
2708
- const id = React15.useId();
3132
+ const id = (0, import_react20.useId)();
2709
3133
  const swipeRef = useViewSwipe(handlePrev, handleNext, true);
2710
- const languagePack = language === "fr" ? fr : en;
2711
- const t = {
2712
- ...languagePack,
2713
- ...translations
2714
- };
2715
- const overlayTimeFormat = uses24HourClock(locale) ? "H:mm" : "h:mm a";
2716
- const handleDragStart = (event) => {
2717
- const { active } = event;
2718
- const draggedEvent = expandedEvents.find((e) => e.id === active.id);
3134
+ const t = (0, import_react20.useMemo)(() => resolveTranslations(language, translations), [language, translations]);
3135
+ const overlayTimeFormat = timeFormats(locale).time;
3136
+ const handleDragStart = (0, import_react20.useCallback)((event) => {
3137
+ const draggedEvent = event.active.data.current?.event;
2719
3138
  if (draggedEvent) {
2720
3139
  setActiveDragEvent(draggedEvent);
2721
3140
  }
2722
- };
2723
- const onDragEndWrapper = (event) => {
3141
+ }, []);
3142
+ const onDragEndWrapper = (0, import_react20.useCallback)((event) => {
2724
3143
  setActiveDragEvent(null);
2725
3144
  handleDragEnd(event);
2726
- };
3145
+ }, [handleDragEnd]);
2727
3146
  const getDragHeight = () => {
2728
3147
  if (!activeDragEvent) return void 0;
2729
3148
  if (view === "resource") {
2730
3149
  return 80;
2731
3150
  }
2732
3151
  if (view !== "week" && view !== "day") return void 0;
2733
- const duration = dateFns.differenceInMinutes(activeDragEvent.end, activeDragEvent.start);
3152
+ const duration = (0, import_date_fns16.differenceInMinutes)(activeDragEvent.end, activeDragEvent.start);
2734
3153
  const hourHeight = view === "day" ? 80 : 60;
2735
3154
  return duration / 60 * hourHeight;
2736
3155
  };
2737
3156
  const getDragWidth = () => {
2738
3157
  if (view === "month") return "100%";
2739
3158
  if (view === "resource" && activeDragEvent) {
2740
- const duration = dateFns.differenceInMinutes(activeDragEvent.end, activeDragEvent.start);
3159
+ const duration = (0, import_date_fns16.differenceInMinutes)(activeDragEvent.end, activeDragEvent.start);
2741
3160
  const width = duration / 60 * 100;
2742
3161
  return `${Math.max(width, 4)}px`;
2743
3162
  }
2744
3163
  return "150px";
2745
3164
  };
2746
- const filteredEvents = React15.useMemo(() => {
3165
+ const filteredEvents = (0, import_react20.useMemo)(() => {
2747
3166
  if (!calendars) return expandedEvents;
2748
3167
  const activeCalendarIds = calendars.filter((c) => c.active !== false).map((c) => c.id);
2749
3168
  return expandedEvents.filter((e) => {
@@ -2751,22 +3170,22 @@ var Scheduler = ({
2751
3170
  return activeCalendarIds.includes(e.calendarId);
2752
3171
  });
2753
3172
  }, [expandedEvents, calendars]);
2754
- return /* @__PURE__ */ React15__namespace.default.createElement(
2755
- core.DndContext,
3173
+ return /* @__PURE__ */ import_react20.default.createElement(
3174
+ import_core3.DndContext,
2756
3175
  {
2757
3176
  id,
2758
3177
  sensors: dndSensors,
2759
3178
  onDragStart: handleDragStart,
2760
3179
  onDragEnd: onDragEndWrapper,
2761
- modifiers: modifiers$1
3180
+ modifiers
2762
3181
  },
2763
- /* @__PURE__ */ React15__namespace.default.createElement(
3182
+ /* @__PURE__ */ import_react20.default.createElement(
2764
3183
  "div",
2765
3184
  {
2766
3185
  className: cn("flex flex-col h-full bg-background text-foreground relative", className),
2767
3186
  style: getThemeStyles(theme)
2768
3187
  },
2769
- /* @__PURE__ */ React15__namespace.default.createElement(
3188
+ /* @__PURE__ */ import_react20.default.createElement(
2770
3189
  CalendarHeader,
2771
3190
  {
2772
3191
  currentDate,
@@ -2785,8 +3204,8 @@ var Scheduler = ({
2785
3204
  locale
2786
3205
  }
2787
3206
  ),
2788
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ React15__namespace.default.createElement(
2789
- framerMotion.motion.div,
3207
+ /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ import_react20.default.createElement(
3208
+ import_framer_motion4.motion.div,
2790
3209
  {
2791
3210
  className: cn(
2792
3211
  "hidden md:block overflow-hidden"
@@ -2801,7 +3220,7 @@ var Scheduler = ({
2801
3220
  ease: [0.4, 0, 0.2, 1]
2802
3221
  }
2803
3222
  },
2804
- /* @__PURE__ */ React15__namespace.default.createElement(
3223
+ /* @__PURE__ */ import_react20.default.createElement(
2805
3224
  Sidebar,
2806
3225
  {
2807
3226
  currentDate,
@@ -2818,8 +3237,8 @@ var Scheduler = ({
2818
3237
  locale
2819
3238
  }
2820
3239
  )
2821
- ), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 flex flex-col overflow-hidden relative" }, isLoading ? /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "flex-1 overflow-auto p-0 md:p-4" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "h-full min-w-full" }, view === "month" && /* @__PURE__ */ React15__namespace.default.createElement(MonthViewSkeleton, null), view === "week" && /* @__PURE__ */ React15__namespace.default.createElement(WeekViewSkeleton, null), view === "day" && /* @__PURE__ */ React15__namespace.default.createElement(DayViewSkeleton, null), view === "agenda" && /* @__PURE__ */ React15__namespace.default.createElement(AgendaViewSkeleton, null), view === "resource" && /* @__PURE__ */ React15__namespace.default.createElement(WeekViewSkeleton, null))) : /* @__PURE__ */ React15__namespace.default.createElement("div", { ref: swipeRef, className: "flex-1 overflow-auto p-0 md:p-4 touch-pan-y" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "h-full min-w-full" }, /* @__PURE__ */ React15__namespace.default.createElement(framerMotion.AnimatePresence, { mode: "wait", initial: false }, /* @__PURE__ */ React15__namespace.default.createElement(
2822
- framerMotion.motion.div,
3240
+ ), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex-1 flex flex-col overflow-hidden relative" }, isLoading ? /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex-1 overflow-auto p-0 md:p-4" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-full min-w-full" }, view === "month" && /* @__PURE__ */ import_react20.default.createElement(MonthViewSkeleton, null), view === "week" && /* @__PURE__ */ import_react20.default.createElement(WeekViewSkeleton, null), view === "day" && /* @__PURE__ */ import_react20.default.createElement(DayViewSkeleton, null), view === "agenda" && /* @__PURE__ */ import_react20.default.createElement(AgendaViewSkeleton, null), view === "resource" && /* @__PURE__ */ import_react20.default.createElement(WeekViewSkeleton, null))) : /* @__PURE__ */ import_react20.default.createElement("div", { ref: swipeRef, className: "flex-1 overflow-auto p-0 md:p-4 touch-pan-y" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-full min-w-full" }, /* @__PURE__ */ import_react20.default.createElement(import_framer_motion4.AnimatePresence, { mode: "wait", initial: false }, /* @__PURE__ */ import_react20.default.createElement(
3241
+ import_framer_motion4.motion.div,
2823
3242
  {
2824
3243
  key: `${view}-${currentDate.toISOString()}-${timezone || "local"}`,
2825
3244
  initial: { opacity: 0, scale: 0.98, y: 15 },
@@ -2843,7 +3262,7 @@ var Scheduler = ({
2843
3262
  },
2844
3263
  className: "h-full"
2845
3264
  },
2846
- view === "month" && /* @__PURE__ */ React15__namespace.default.createElement(
3265
+ view === "month" && /* @__PURE__ */ import_react20.default.createElement(
2847
3266
  MonthView,
2848
3267
  {
2849
3268
  currentDate,
@@ -2854,7 +3273,7 @@ var Scheduler = ({
2854
3273
  locale
2855
3274
  }
2856
3275
  ),
2857
- view === "week" && /* @__PURE__ */ React15__namespace.default.createElement(
3276
+ view === "week" && /* @__PURE__ */ import_react20.default.createElement(
2858
3277
  WeekView,
2859
3278
  {
2860
3279
  currentDate,
@@ -2867,7 +3286,7 @@ var Scheduler = ({
2867
3286
  readonly: readOnly
2868
3287
  }
2869
3288
  ),
2870
- view === "day" && /* @__PURE__ */ React15__namespace.default.createElement(
3289
+ view === "day" && /* @__PURE__ */ import_react20.default.createElement(
2871
3290
  DayView,
2872
3291
  {
2873
3292
  currentDate,
@@ -2880,7 +3299,7 @@ var Scheduler = ({
2880
3299
  readonly: readOnly
2881
3300
  }
2882
3301
  ),
2883
- view === "agenda" && /* @__PURE__ */ React15__namespace.default.createElement(
3302
+ view === "agenda" && /* @__PURE__ */ import_react20.default.createElement(
2884
3303
  AgendaView,
2885
3304
  {
2886
3305
  currentDate,
@@ -2888,30 +3307,29 @@ var Scheduler = ({
2888
3307
  onEventClick: handleEventClickInternal,
2889
3308
  onCreateEvent: handleCreateEvent,
2890
3309
  locale,
2891
- translations: t
3310
+ translations: t,
3311
+ timezone
2892
3312
  }
2893
3313
  ),
2894
- view === "resource" && resources && /* @__PURE__ */ React15__namespace.default.createElement(
3314
+ view === "resource" && resources && /* @__PURE__ */ import_react20.default.createElement(
2895
3315
  ResourceView,
2896
3316
  {
2897
3317
  currentDate,
2898
3318
  events: filteredEvents,
2899
3319
  resources,
2900
3320
  onEventClick: handleEventClickInternal,
2901
- onTimeSlotClick: (date, resourceId) => {
2902
- if (readOnly) return;
2903
- handleTimeSlotClick(date);
2904
- },
2905
- locale
3321
+ onTimeSlotClick: handleTimeSlotClick,
3322
+ locale,
3323
+ timezone
2906
3324
  }
2907
3325
  )
2908
- )))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "md:hidden absolute bottom-6 right-6 z-50" }, /* @__PURE__ */ React15__namespace.default.createElement(
3326
+ )))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "md:hidden absolute bottom-6 right-6 z-50" }, /* @__PURE__ */ import_react20.default.createElement(
2909
3327
  "button",
2910
3328
  {
2911
3329
  onClick: handleCreateEvent,
2912
3330
  className: "w-14 h-14 bg-blue-600 rounded-full shadow-lg flex items-center justify-center text-white active:scale-90 transition-transform"
2913
3331
  },
2914
- /* @__PURE__ */ React15__namespace.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React15__namespace.default.createElement("path", { d: "M5 12h14" }), /* @__PURE__ */ React15__namespace.default.createElement("path", { d: "M12 5v14" }))
3332
+ /* @__PURE__ */ import_react20.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react20.default.createElement("path", { d: "M5 12h14" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M12 5v14" }))
2915
3333
  )))),
2916
3334
  renderEventForm ? renderEventForm({
2917
3335
  isOpen: isModalOpen,
@@ -2920,7 +3338,7 @@ var Scheduler = ({
2920
3338
  initialDate: modalInitialDate,
2921
3339
  onSave: handleModalSave,
2922
3340
  onDelete: handleModalDelete
2923
- }) : /* @__PURE__ */ React15__namespace.default.createElement(
3341
+ }) : /* @__PURE__ */ import_react20.default.createElement(
2924
3342
  EventModal,
2925
3343
  {
2926
3344
  isOpen: isModalOpen,
@@ -2934,7 +3352,7 @@ var Scheduler = ({
2934
3352
  translations: t
2935
3353
  }
2936
3354
  ),
2937
- /* @__PURE__ */ React15__namespace.default.createElement(
3355
+ /* @__PURE__ */ import_react20.default.createElement(
2938
3356
  EventContextMenu,
2939
3357
  {
2940
3358
  event: contextMenuEvent,
@@ -2944,20 +3362,12 @@ var Scheduler = ({
2944
3362
  handleEventClickInternal(event);
2945
3363
  closeContextMenu();
2946
3364
  },
2947
- onDelete: (eventId) => {
2948
- onEventDelete?.(eventId);
3365
+ onDelete: () => {
3366
+ if (contextMenuEvent) handleEventDelete(contextMenuEvent);
2949
3367
  closeContextMenu();
2950
3368
  },
2951
3369
  onDuplicate: (event) => {
2952
- const duplicatedEvent = {
2953
- ...event,
2954
- id: `${event.id}-copy-${Date.now()}`,
2955
- title: `${event.title} (Copy)`,
2956
- start: new Date(event.start.getTime() + 24 * 60 * 60 * 1e3),
2957
- // +1 day
2958
- end: new Date(event.end.getTime() + 24 * 60 * 60 * 1e3)
2959
- };
2960
- onEventCreate?.(duplicatedEvent);
3370
+ handleEventDuplicate(event);
2961
3371
  closeContextMenu();
2962
3372
  },
2963
3373
  translations: {
@@ -2967,7 +3377,7 @@ var Scheduler = ({
2967
3377
  }
2968
3378
  }
2969
3379
  ),
2970
- /* @__PURE__ */ React15__namespace.default.createElement(core.DragOverlay, { dropAnimation: null }, activeDragEvent ? /* @__PURE__ */ React15__namespace.default.createElement(
3380
+ /* @__PURE__ */ import_react20.default.createElement(import_core3.DragOverlay, { dropAnimation: null }, activeDragEvent ? /* @__PURE__ */ import_react20.default.createElement(
2971
3381
  "div",
2972
3382
  {
2973
3383
  className: cn(
@@ -2985,19 +3395,19 @@ var Scheduler = ({
2985
3395
  transform: "rotate(-2deg) scale(1.02)"
2986
3396
  }
2987
3397
  },
2988
- /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "p-2.5 h-full flex flex-col" }, /* @__PURE__ */ React15__namespace.default.createElement(
3398
+ /* @__PURE__ */ import_react20.default.createElement("div", { className: "p-2.5 h-full flex flex-col" }, /* @__PURE__ */ import_react20.default.createElement(
2989
3399
  "div",
2990
3400
  {
2991
3401
  className: "absolute left-0 top-0 bottom-0 w-1 rounded-l-lg",
2992
3402
  style: { backgroundColor: activeDragEvent.color || "var(--primary)" }
2993
3403
  }
2994
- ), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "pl-2" }, /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "font-semibold truncate text-sm" }, activeDragEvent.title), (view === "week" || view === "day") && getDragHeight() && getDragHeight() > 40 && /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "text-xs opacity-80 mt-0.5 flex items-center gap-1" }, /* @__PURE__ */ React15__namespace.default.createElement("svg", { className: "w-3 h-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" }, /* @__PURE__ */ React15__namespace.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ React15__namespace.default.createElement("path", { d: "M12 6v6l4 2" })), dateFns.format(activeDragEvent.start, overlayTimeFormat, { locale }), " - ", dateFns.format(activeDragEvent.end, overlayTimeFormat, { locale }))), /* @__PURE__ */ React15__namespace.default.createElement("div", { className: "absolute bottom-1.5 right-1.5 opacity-60" }, /* @__PURE__ */ React15__namespace.default.createElement("svg", { className: "w-4 h-4", viewBox: "0 0 24 24", fill: "currentColor" }, /* @__PURE__ */ React15__namespace.default.createElement("circle", { cx: "9", cy: "5", r: "1.5" }), /* @__PURE__ */ React15__namespace.default.createElement("circle", { cx: "15", cy: "5", r: "1.5" }), /* @__PURE__ */ React15__namespace.default.createElement("circle", { cx: "9", cy: "12", r: "1.5" }), /* @__PURE__ */ React15__namespace.default.createElement("circle", { cx: "15", cy: "12", r: "1.5" }), /* @__PURE__ */ React15__namespace.default.createElement("circle", { cx: "9", cy: "19", r: "1.5" }), /* @__PURE__ */ React15__namespace.default.createElement("circle", { cx: "15", cy: "19", r: "1.5" }))))
3404
+ ), /* @__PURE__ */ import_react20.default.createElement("div", { className: "pl-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "font-semibold truncate text-sm" }, activeDragEvent.title), (view === "week" || view === "day") && getDragHeight() && getDragHeight() > 40 && /* @__PURE__ */ import_react20.default.createElement("div", { className: "text-xs opacity-80 mt-0.5 flex items-center gap-1" }, /* @__PURE__ */ import_react20.default.createElement("svg", { className: "w-3 h-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" }, /* @__PURE__ */ import_react20.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M12 6v6l4 2" })), (0, import_date_fns16.format)(activeDragEvent.start, overlayTimeFormat, { locale }), " - ", (0, import_date_fns16.format)(activeDragEvent.end, overlayTimeFormat, { locale }))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "absolute bottom-1.5 right-1.5 opacity-60" }, /* @__PURE__ */ import_react20.default.createElement("svg", { className: "w-4 h-4", viewBox: "0 0 24 24", fill: "currentColor" }, /* @__PURE__ */ import_react20.default.createElement("circle", { cx: "9", cy: "5", r: "1.5" }), /* @__PURE__ */ import_react20.default.createElement("circle", { cx: "15", cy: "5", r: "1.5" }), /* @__PURE__ */ import_react20.default.createElement("circle", { cx: "9", cy: "12", r: "1.5" }), /* @__PURE__ */ import_react20.default.createElement("circle", { cx: "15", cy: "12", r: "1.5" }), /* @__PURE__ */ import_react20.default.createElement("circle", { cx: "9", cy: "19", r: "1.5" }), /* @__PURE__ */ import_react20.default.createElement("circle", { cx: "15", cy: "19", r: "1.5" }))))
2995
3405
  ) : null)
2996
3406
  )
2997
3407
  );
2998
3408
  };
2999
-
3000
- exports.Scheduler = Scheduler;
3001
- exports.cn = cn;
3002
- //# sourceMappingURL=index.js.map
3003
- //# sourceMappingURL=index.js.map
3409
+ // Annotate the CommonJS export names for ESM import in node:
3410
+ 0 && (module.exports = {
3411
+ Scheduler,
3412
+ cn
3413
+ });