calendarkit-pro 1.3.1 → 1.4.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/README.md +22 -3
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +919 -415
- package/dist/index.mjs +883 -379
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/index.tsx
|
|
4
|
-
import
|
|
4
|
+
import React20, { useCallback as useCallback6, useId, useState as useState8, useMemo as useMemo4 } from "react";
|
|
5
5
|
import { DndContext, useSensor, useSensors, PointerSensor, DragOverlay } from "@dnd-kit/core";
|
|
6
6
|
import { createSnapModifier, restrictToWindowEdges } from "@dnd-kit/modifiers";
|
|
7
7
|
import { AnimatePresence as AnimatePresence3, motion as motion4 } from "framer-motion";
|
|
@@ -386,7 +386,12 @@ var en = {
|
|
|
386
386
|
toggleSidebar: "Toggle sidebar",
|
|
387
387
|
toggleTheme: "Toggle dark mode",
|
|
388
388
|
switchLanguage: "Switch language",
|
|
389
|
-
eventColor: "Event color"
|
|
389
|
+
eventColor: "Event color",
|
|
390
|
+
showLess: "Show less",
|
|
391
|
+
continuesBefore: "Started earlier",
|
|
392
|
+
continuesAfter: "Continues later",
|
|
393
|
+
durationDay: "1 day",
|
|
394
|
+
durationDays: "{n} days"
|
|
390
395
|
};
|
|
391
396
|
var fr = {
|
|
392
397
|
today: "Aujourd'hui",
|
|
@@ -493,7 +498,12 @@ var fr = {
|
|
|
493
498
|
toggleSidebar: "Afficher ou masquer la barre lat\xE9rale",
|
|
494
499
|
toggleTheme: "Basculer le th\xE8me sombre",
|
|
495
500
|
switchLanguage: "Changer de langue",
|
|
496
|
-
eventColor: "Couleur de l'\xE9v\xE9nement"
|
|
501
|
+
eventColor: "Couleur de l'\xE9v\xE9nement",
|
|
502
|
+
showLess: "R\xE9duire",
|
|
503
|
+
continuesBefore: "A commenc\xE9 avant",
|
|
504
|
+
continuesAfter: "Continue apr\xE8s",
|
|
505
|
+
durationDay: "1 jour",
|
|
506
|
+
durationDays: "{n} jours"
|
|
497
507
|
};
|
|
498
508
|
|
|
499
509
|
// src/core/format.ts
|
|
@@ -703,11 +713,14 @@ var Sidebar = ({
|
|
|
703
713
|
};
|
|
704
714
|
|
|
705
715
|
// src/views/MonthView.tsx
|
|
706
|
-
import
|
|
707
|
-
import { format as
|
|
716
|
+
import React8, { useMemo } from "react";
|
|
717
|
+
import { format as format8, isSameDay as isSameDay3, isSameMonth as isSameMonth2 } from "date-fns";
|
|
708
718
|
|
|
709
719
|
// src/core/events.ts
|
|
710
|
-
import { addDays, format as format6, startOfDay as
|
|
720
|
+
import { addDays as addDays2, format as format6, startOfDay as startOfDay3 } from "date-fns";
|
|
721
|
+
|
|
722
|
+
// src/core/allDay.ts
|
|
723
|
+
import { addDays, differenceInCalendarDays, startOfDay as startOfDay2 } from "date-fns";
|
|
711
724
|
|
|
712
725
|
// src/core/timezone.ts
|
|
713
726
|
import { format as format5, isSameDay as isSameDay2, startOfDay } from "date-fns";
|
|
@@ -767,6 +780,91 @@ function displayToday(tz, now = /* @__PURE__ */ new Date()) {
|
|
|
767
780
|
return startOfDay(toDisplay(now, tz));
|
|
768
781
|
}
|
|
769
782
|
|
|
783
|
+
// src/core/allDay.ts
|
|
784
|
+
var DAY_EVENT_MIN_MS = 24 * 60 * 60 * 1e3;
|
|
785
|
+
function isDayEvent(event) {
|
|
786
|
+
return event.allDay === true || event.end.getTime() - event.start.getTime() >= DAY_EVENT_MIN_MS;
|
|
787
|
+
}
|
|
788
|
+
var isMidnight = (date) => date.getHours() === 0 && date.getMinutes() === 0 && date.getSeconds() === 0 && date.getMilliseconds() === 0;
|
|
789
|
+
var isUtcMidnight = (date) => date.getUTCHours() === 0 && date.getUTCMinutes() === 0 && date.getUTCSeconds() === 0 && date.getUTCMilliseconds() === 0;
|
|
790
|
+
function toCalendarMidnight(date) {
|
|
791
|
+
return !isMidnight(date) && isUtcMidnight(date) ? new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()) : date;
|
|
792
|
+
}
|
|
793
|
+
function calendarDay(date) {
|
|
794
|
+
if (isMidnight(date)) return { day: startOfDay2(date), midnight: true };
|
|
795
|
+
if (isUtcMidnight(date)) return { day: new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()), midnight: true };
|
|
796
|
+
return { day: startOfDay2(date), midnight: false };
|
|
797
|
+
}
|
|
798
|
+
function dayEventSpan(event, tz) {
|
|
799
|
+
if (event.allDay) {
|
|
800
|
+
const firstDay2 = calendarDay(event.start).day;
|
|
801
|
+
if (event.end.getTime() <= event.start.getTime()) return { firstDay: firstDay2, lastDay: firstDay2 };
|
|
802
|
+
const end = calendarDay(event.end);
|
|
803
|
+
const lastDay2 = end.midnight ? addDays(end.day, -1) : end.day;
|
|
804
|
+
return { firstDay: firstDay2, lastDay: lastDay2 < firstDay2 ? firstDay2 : lastDay2 };
|
|
805
|
+
}
|
|
806
|
+
const firstDay = startOfDay2(toDisplay(event.start, tz));
|
|
807
|
+
const lastDay = startOfDay2(toDisplay(new Date(event.end.getTime() - 1), tz));
|
|
808
|
+
return { firstDay, lastDay: lastDay < firstDay ? firstDay : lastDay };
|
|
809
|
+
}
|
|
810
|
+
var partitionCache = /* @__PURE__ */ new WeakMap();
|
|
811
|
+
function partitionDayEvents(events, tz) {
|
|
812
|
+
let byZone = partitionCache.get(events);
|
|
813
|
+
if (!byZone) {
|
|
814
|
+
byZone = /* @__PURE__ */ new Map();
|
|
815
|
+
partitionCache.set(events, byZone);
|
|
816
|
+
}
|
|
817
|
+
const key = tz ?? "";
|
|
818
|
+
let result = byZone.get(key);
|
|
819
|
+
if (!result) {
|
|
820
|
+
const dayEvents = [];
|
|
821
|
+
const timedEvents = [];
|
|
822
|
+
for (const event of events) (isDayEvent(event) ? dayEvents : timedEvents).push(event);
|
|
823
|
+
result = { dayEvents, timedEvents };
|
|
824
|
+
byZone.set(key, result);
|
|
825
|
+
}
|
|
826
|
+
return result;
|
|
827
|
+
}
|
|
828
|
+
var rowCache = /* @__PURE__ */ new WeakMap();
|
|
829
|
+
function layoutDayRow(days, dayEvents, tz) {
|
|
830
|
+
if (days.length === 0) return { segments: [], laneCount: 0 };
|
|
831
|
+
const rowStart = startOfDay2(days[0]);
|
|
832
|
+
const columns = days.length;
|
|
833
|
+
const key = `${tz ?? ""}|${rowStart.getTime()}|${columns}`;
|
|
834
|
+
let cache = rowCache.get(dayEvents);
|
|
835
|
+
if (!cache) {
|
|
836
|
+
cache = /* @__PURE__ */ new Map();
|
|
837
|
+
rowCache.set(dayEvents, cache);
|
|
838
|
+
}
|
|
839
|
+
const cached = cache.get(key);
|
|
840
|
+
if (cached) return cached;
|
|
841
|
+
const unplaced = [];
|
|
842
|
+
for (const event of dayEvents) {
|
|
843
|
+
const { firstDay, lastDay } = dayEventSpan(event, tz);
|
|
844
|
+
const first = differenceInCalendarDays(firstDay, rowStart);
|
|
845
|
+
const last = differenceInCalendarDays(lastDay, rowStart);
|
|
846
|
+
if (last < 0 || first >= columns) continue;
|
|
847
|
+
const startCol = Math.max(first, 0);
|
|
848
|
+
const endCol = Math.min(last, columns - 1);
|
|
849
|
+
unplaced.push({ event, startCol, span: endCol - startCol + 1, continuesBefore: first < 0, continuesAfter: last >= columns });
|
|
850
|
+
}
|
|
851
|
+
unplaced.sort((a, b) => a.startCol - b.startCol || b.span - a.span || (a.event.id < b.event.id ? -1 : a.event.id > b.event.id ? 1 : 0));
|
|
852
|
+
const occupied = [];
|
|
853
|
+
const segments = [];
|
|
854
|
+
for (const segment of unplaced) {
|
|
855
|
+
let lane = occupied.findIndex((row) => row.slice(segment.startCol, segment.startCol + segment.span).every((taken) => !taken));
|
|
856
|
+
if (lane === -1) {
|
|
857
|
+
lane = occupied.length;
|
|
858
|
+
occupied.push(new Array(columns).fill(false));
|
|
859
|
+
}
|
|
860
|
+
for (let c = segment.startCol; c < segment.startCol + segment.span; c++) occupied[lane][c] = true;
|
|
861
|
+
segments.push({ ...segment, lane });
|
|
862
|
+
}
|
|
863
|
+
const layout = { segments, laneCount: occupied.length };
|
|
864
|
+
cache.set(key, layout);
|
|
865
|
+
return layout;
|
|
866
|
+
}
|
|
867
|
+
|
|
770
868
|
// src/core/events.ts
|
|
771
869
|
var toDate = (value) => value === void 0 || value === null ? void 0 : value instanceof Date ? value : new Date(value);
|
|
772
870
|
var isValidDate = (date) => !!date && !Number.isNaN(date.getTime());
|
|
@@ -775,29 +873,35 @@ var normalizedList = /* @__PURE__ */ new WeakMap();
|
|
|
775
873
|
function normalizeEvent(event) {
|
|
776
874
|
const cached = normalizedEvent.get(event);
|
|
777
875
|
if (cached !== void 0) return cached;
|
|
778
|
-
const
|
|
779
|
-
const
|
|
876
|
+
const day = (value) => event.allDay && value ? toCalendarMidnight(value) : value;
|
|
877
|
+
const start = day(toDate(event.start));
|
|
878
|
+
const end = day(toDate(event.end));
|
|
780
879
|
let result = null;
|
|
781
880
|
if (!isValidDate(start) || !isValidDate(end)) {
|
|
782
881
|
warnOnce(`invalid-date:${event.id}`, `Event "${event.id}" has an invalid start or end date and was skipped.`);
|
|
783
882
|
} else if (end.getTime() < start.getTime()) {
|
|
784
883
|
warnOnce(`end-before-start:${event.id}`, `Event "${event.id}" ends before it starts and was skipped.`);
|
|
785
884
|
} else {
|
|
786
|
-
const needsCopy = start !== event.start || end !== event.end || needsRecurrenceCopy(event);
|
|
885
|
+
const needsCopy = start !== event.start || end !== event.end || needsRecurrenceCopy(event) || !!event.allDay && dateOnlyRecurrence(event);
|
|
787
886
|
result = needsCopy ? {
|
|
788
887
|
...event,
|
|
789
888
|
start,
|
|
790
889
|
end,
|
|
791
890
|
recurrence: event.recurrence && {
|
|
792
891
|
...event.recurrence,
|
|
793
|
-
until: toDate(event.recurrence.until),
|
|
794
|
-
exdates: event.recurrence.exdates?.map((d) => toDate(d))
|
|
892
|
+
until: day(toDate(event.recurrence.until)),
|
|
893
|
+
exdates: event.recurrence.exdates?.map((d) => day(toDate(d)))
|
|
795
894
|
}
|
|
796
895
|
} : event;
|
|
797
896
|
}
|
|
798
897
|
normalizedEvent.set(event, result);
|
|
799
898
|
return result;
|
|
800
899
|
}
|
|
900
|
+
function dateOnlyRecurrence(event) {
|
|
901
|
+
const r = event.recurrence;
|
|
902
|
+
const changes = (d) => d instanceof Date && toCalendarMidnight(d) !== d;
|
|
903
|
+
return !!r && (changes(r.until) || !!r.exdates?.some(changes));
|
|
904
|
+
}
|
|
801
905
|
function needsRecurrenceCopy(event) {
|
|
802
906
|
const r = event.recurrence;
|
|
803
907
|
if (!r) return false;
|
|
@@ -858,10 +962,10 @@ function segmentsByDisplayDay(events, tz, range) {
|
|
|
858
962
|
const rawEnd = toDisplay(event.end, tz);
|
|
859
963
|
const wallEnd = rawEnd < wallStart ? wallStart : rawEnd;
|
|
860
964
|
if (range && (wallEnd < range.start || wallStart >= range.end)) continue;
|
|
861
|
-
let day =
|
|
965
|
+
let day = startOfDay3(range && wallStart < range.start ? range.start : wallStart);
|
|
862
966
|
const stop = range && wallEnd > range.end ? range.end : wallEnd;
|
|
863
967
|
do {
|
|
864
|
-
const next =
|
|
968
|
+
const next = addDays2(day, 1);
|
|
865
969
|
const start = wallStart > day ? wallStart : day;
|
|
866
970
|
const end = wallEnd < next ? wallEnd : next;
|
|
867
971
|
if (end > start || wallStart.getTime() === wallEnd.getTime()) {
|
|
@@ -878,25 +982,153 @@ function segmentsByDisplayDay(events, tz, range) {
|
|
|
878
982
|
});
|
|
879
983
|
}
|
|
880
984
|
|
|
881
|
-
// src/components/
|
|
882
|
-
import React5 from "react";
|
|
985
|
+
// src/components/AllDayBar.tsx
|
|
986
|
+
import React5, { useRef, useState as useState2 } from "react";
|
|
883
987
|
import { useDraggable } from "@dnd-kit/core";
|
|
884
988
|
import { CSS } from "@dnd-kit/utilities";
|
|
989
|
+
import { addDays as addDays3, differenceInCalendarDays as differenceInCalendarDays2, format as format7 } from "date-fns";
|
|
990
|
+
var AllDayBarImpl = ({
|
|
991
|
+
segment,
|
|
992
|
+
rowDays,
|
|
993
|
+
laneHeight,
|
|
994
|
+
timezone,
|
|
995
|
+
locale,
|
|
996
|
+
translations,
|
|
997
|
+
readonly,
|
|
998
|
+
onEventClick,
|
|
999
|
+
onEventContextMenu,
|
|
1000
|
+
onDayEventResize
|
|
1001
|
+
}) => {
|
|
1002
|
+
const { event, startCol, span, lane, continuesBefore, continuesAfter } = segment;
|
|
1003
|
+
const columns = rowDays.length;
|
|
1004
|
+
const { firstDay, lastDay } = dayEventSpan(event, timezone);
|
|
1005
|
+
const segmentOffset = differenceInCalendarDays2(rowDays[startCol], firstDay);
|
|
1006
|
+
const dragData = useRef({ event, grabDayOffset: segmentOffset });
|
|
1007
|
+
dragData.current.event = event;
|
|
1008
|
+
const dragDisabled = readonly || isEventDragDisabled(event);
|
|
1009
|
+
const { attributes, listeners, setNodeRef, transform, isDragging } = useDraggable({
|
|
1010
|
+
id: `${event.id}@day@${format7(rowDays[0], "yyyy-MM-dd")}`,
|
|
1011
|
+
data: dragData.current,
|
|
1012
|
+
disabled: dragDisabled
|
|
1013
|
+
});
|
|
1014
|
+
const [resizeCols, setResizeCols] = useState2(0);
|
|
1015
|
+
const ignoreClick = useRef(false);
|
|
1016
|
+
const canResize = !readonly && !continuesAfter && !isEventResizeDisabled(event) && !!onDayEventResize;
|
|
1017
|
+
const shownSpan = Math.max(1, Math.min(span + resizeCols, columns - startCol));
|
|
1018
|
+
const handlePointerDownCapture = (e) => {
|
|
1019
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
1020
|
+
const dayWithin = rect.width > 0 ? Math.floor((e.clientX - rect.left) / rect.width * span) : 0;
|
|
1021
|
+
dragData.current.grabDayOffset = segmentOffset + Math.min(Math.max(dayWithin, 0), span - 1);
|
|
1022
|
+
};
|
|
1023
|
+
const handleResizeStart = (e) => {
|
|
1024
|
+
e.stopPropagation();
|
|
1025
|
+
e.preventDefault();
|
|
1026
|
+
const bar = e.currentTarget.parentElement;
|
|
1027
|
+
const columnWidth = bar.getBoundingClientRect().width / span || 1;
|
|
1028
|
+
const startX = e.clientX;
|
|
1029
|
+
let delta = 0;
|
|
1030
|
+
const onMove = (moveEvent) => {
|
|
1031
|
+
delta = Math.round((moveEvent.clientX - startX) / columnWidth);
|
|
1032
|
+
setResizeCols(delta);
|
|
1033
|
+
};
|
|
1034
|
+
const stop = () => {
|
|
1035
|
+
document.removeEventListener("pointermove", onMove);
|
|
1036
|
+
document.removeEventListener("pointerup", onUp);
|
|
1037
|
+
document.removeEventListener("pointercancel", stop);
|
|
1038
|
+
setResizeCols(0);
|
|
1039
|
+
};
|
|
1040
|
+
const onUp = () => {
|
|
1041
|
+
stop();
|
|
1042
|
+
ignoreClick.current = true;
|
|
1043
|
+
setTimeout(() => {
|
|
1044
|
+
ignoreClick.current = false;
|
|
1045
|
+
}, 0);
|
|
1046
|
+
if (delta !== 0) onDayEventResize?.(event, addDays3(rowDays[startCol + span - 1], delta));
|
|
1047
|
+
};
|
|
1048
|
+
document.addEventListener("pointermove", onMove);
|
|
1049
|
+
document.addEventListener("pointerup", onUp);
|
|
1050
|
+
document.addEventListener("pointercancel", stop);
|
|
1051
|
+
};
|
|
1052
|
+
const color = event.color || "hsl(var(--primary))";
|
|
1053
|
+
const dateFormat = "d MMM";
|
|
1054
|
+
const label = `${event.title}, ${format7(firstDay, dateFormat, { locale })}${lastDay > firstDay ? ` \u2013 ${format7(lastDay, dateFormat, { locale })}` : ""}`;
|
|
1055
|
+
return /* @__PURE__ */ React5.createElement(
|
|
1056
|
+
"div",
|
|
1057
|
+
{
|
|
1058
|
+
ref: setNodeRef,
|
|
1059
|
+
...listeners,
|
|
1060
|
+
...attributes,
|
|
1061
|
+
onPointerDownCapture: handlePointerDownCapture,
|
|
1062
|
+
role: "button",
|
|
1063
|
+
"aria-label": label,
|
|
1064
|
+
className: cn(
|
|
1065
|
+
"group absolute px-[2px] select-none",
|
|
1066
|
+
dragDisabled ? "cursor-pointer" : "cursor-grab active:cursor-grabbing touch-none"
|
|
1067
|
+
),
|
|
1068
|
+
style: {
|
|
1069
|
+
left: `${startCol / columns * 100}%`,
|
|
1070
|
+
width: `${shownSpan / columns * 100}%`,
|
|
1071
|
+
top: lane * laneHeight,
|
|
1072
|
+
height: laneHeight,
|
|
1073
|
+
transform: CSS.Translate.toString(transform),
|
|
1074
|
+
opacity: isDragging ? 0 : void 0,
|
|
1075
|
+
zIndex: isDragging ? 100 : 1
|
|
1076
|
+
},
|
|
1077
|
+
onClick: (e) => {
|
|
1078
|
+
e.stopPropagation();
|
|
1079
|
+
if (ignoreClick.current) {
|
|
1080
|
+
ignoreClick.current = false;
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
onEventClick?.(event);
|
|
1084
|
+
},
|
|
1085
|
+
onContextMenu: onEventContextMenu ? (e) => onEventContextMenu(event, e) : void 0
|
|
1086
|
+
},
|
|
1087
|
+
/* @__PURE__ */ React5.createElement(
|
|
1088
|
+
"div",
|
|
1089
|
+
{
|
|
1090
|
+
className: cn(
|
|
1091
|
+
"relative h-[calc(100%-4px)] mt-[2px] flex items-center gap-1 px-1.5 text-[11px] font-semibold text-white overflow-hidden shadow-sm",
|
|
1092
|
+
continuesBefore ? "rounded-l-none" : "rounded-l-md",
|
|
1093
|
+
continuesAfter ? "rounded-r-none" : "rounded-r-md"
|
|
1094
|
+
),
|
|
1095
|
+
style: { backgroundColor: color }
|
|
1096
|
+
},
|
|
1097
|
+
continuesBefore && /* @__PURE__ */ React5.createElement("span", { "aria-label": translations?.continuesBefore }, "\u2039"),
|
|
1098
|
+
/* @__PURE__ */ React5.createElement("span", { className: "truncate" }, event.title),
|
|
1099
|
+
continuesAfter && /* @__PURE__ */ React5.createElement("span", { className: "ml-auto", "aria-label": translations?.continuesAfter }, "\u203A"),
|
|
1100
|
+
canResize && /* @__PURE__ */ React5.createElement(
|
|
1101
|
+
"div",
|
|
1102
|
+
{
|
|
1103
|
+
"data-testid": "all-day-resize",
|
|
1104
|
+
className: "absolute right-0 top-0 bottom-0 w-1.5 cursor-ew-resize opacity-0 group-hover:opacity-100 bg-black/20",
|
|
1105
|
+
onPointerDown: handleResizeStart
|
|
1106
|
+
}
|
|
1107
|
+
)
|
|
1108
|
+
)
|
|
1109
|
+
);
|
|
1110
|
+
};
|
|
1111
|
+
var AllDayBar = React5.memo(AllDayBarImpl);
|
|
1112
|
+
|
|
1113
|
+
// src/components/dnd/DraggableEvent.tsx
|
|
1114
|
+
import React6 from "react";
|
|
1115
|
+
import { useDraggable as useDraggable2 } from "@dnd-kit/core";
|
|
1116
|
+
import { CSS as CSS2 } from "@dnd-kit/utilities";
|
|
885
1117
|
var DraggableEventImpl = ({ event, dragId, grabOffsetMs, children, className, style: propStyle, ...props }) => {
|
|
886
1118
|
const dragDisabled = isEventDragDisabled(event);
|
|
887
|
-
const { attributes, listeners, setNodeRef, transform, isDragging } =
|
|
1119
|
+
const { attributes, listeners, setNodeRef, transform, isDragging } = useDraggable2({
|
|
888
1120
|
id: dragId ?? event.id,
|
|
889
1121
|
data: { event, grabOffsetMs },
|
|
890
1122
|
disabled: dragDisabled
|
|
891
1123
|
});
|
|
892
1124
|
const style = {
|
|
893
1125
|
...propStyle,
|
|
894
|
-
transform:
|
|
1126
|
+
transform: CSS2.Translate.toString(transform),
|
|
895
1127
|
zIndex: isDragging ? 100 : propStyle?.zIndex,
|
|
896
1128
|
// Hide the original while dragging: the DragOverlay ghost is what the user follows.
|
|
897
1129
|
opacity: isDragging ? 0 : propStyle?.opacity
|
|
898
1130
|
};
|
|
899
|
-
return /* @__PURE__ */
|
|
1131
|
+
return /* @__PURE__ */ React6.createElement(
|
|
900
1132
|
"div",
|
|
901
1133
|
{
|
|
902
1134
|
ref: setNodeRef,
|
|
@@ -909,10 +1141,10 @@ var DraggableEventImpl = ({ event, dragId, grabOffsetMs, children, className, st
|
|
|
909
1141
|
children
|
|
910
1142
|
);
|
|
911
1143
|
};
|
|
912
|
-
var DraggableEvent =
|
|
1144
|
+
var DraggableEvent = React6.memo(DraggableEventImpl);
|
|
913
1145
|
|
|
914
1146
|
// src/components/dnd/DroppableCell.tsx
|
|
915
|
-
import
|
|
1147
|
+
import React7 from "react";
|
|
916
1148
|
import { useDroppable } from "@dnd-kit/core";
|
|
917
1149
|
var QUARTER_HOVER = [
|
|
918
1150
|
"hover:bg-blue-50/50 dark:hover:bg-blue-900/10",
|
|
@@ -927,13 +1159,13 @@ var QUARTER_ACTIVE = [
|
|
|
927
1159
|
"bg-blue-100/80 dark:bg-blue-900/40 ring-2 ring-primary ring-inset"
|
|
928
1160
|
];
|
|
929
1161
|
var quarterOf = (date) => Math.min(3, Math.floor(date.getMinutes() / 15));
|
|
930
|
-
var DroppableCellImpl = ({ id, date, resourceId, children, className, style, onClick, onSlotClick }) => {
|
|
1162
|
+
var DroppableCellImpl = ({ id, date, resourceId, allDayRow, children, className, style, onClick, onSlotClick }) => {
|
|
931
1163
|
const { isOver, setNodeRef } = useDroppable({
|
|
932
1164
|
id,
|
|
933
|
-
data: { date, resourceId }
|
|
1165
|
+
data: { date, resourceId, allDayRow }
|
|
934
1166
|
});
|
|
935
1167
|
const quarter = quarterOf(date);
|
|
936
|
-
return /* @__PURE__ */
|
|
1168
|
+
return /* @__PURE__ */ React7.createElement(
|
|
937
1169
|
"div",
|
|
938
1170
|
{
|
|
939
1171
|
ref: setNodeRef,
|
|
@@ -955,13 +1187,13 @@ var shallowEqualStyle = (a, b) => {
|
|
|
955
1187
|
const keys = Object.keys(a);
|
|
956
1188
|
return keys.length === Object.keys(b).length && keys.every((key) => a[key] === b[key]);
|
|
957
1189
|
};
|
|
958
|
-
var DroppableCell =
|
|
1190
|
+
var DroppableCell = React7.memo(
|
|
959
1191
|
DroppableCellImpl,
|
|
960
|
-
(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)
|
|
1192
|
+
(prev, next) => prev.id === next.id && prev.date.getTime() === next.date.getTime() && prev.resourceId === next.resourceId && prev.allDayRow === next.allDayRow && prev.children === next.children && prev.className === next.className && prev.onClick === next.onClick && prev.onSlotClick === next.onSlotClick && shallowEqualStyle(prev.style, next.style)
|
|
961
1193
|
);
|
|
962
1194
|
|
|
963
1195
|
// src/views/MonthView.tsx
|
|
964
|
-
var EventItem =
|
|
1196
|
+
var EventItem = React8.memo(({ event, onEventClick, onEventContextMenu }) => /* @__PURE__ */ React8.createElement(DraggableEvent, { event }, /* @__PURE__ */ React8.createElement(
|
|
965
1197
|
"div",
|
|
966
1198
|
{
|
|
967
1199
|
className: cn(
|
|
@@ -980,9 +1212,23 @@ var EventItem = React7.memo(({ event, onEventClick, onEventContextMenu }) => /*
|
|
|
980
1212
|
},
|
|
981
1213
|
onContextMenu: onEventContextMenu ? (e) => onEventContextMenu(event, e) : void 0
|
|
982
1214
|
},
|
|
983
|
-
/* @__PURE__ */
|
|
1215
|
+
/* @__PURE__ */ React8.createElement("span", { className: "font-medium" }, event.title)
|
|
984
1216
|
)));
|
|
985
1217
|
EventItem.displayName = "EventItem";
|
|
1218
|
+
var ROW_HEIGHT = 130;
|
|
1219
|
+
var LANE_HEIGHT = 20;
|
|
1220
|
+
var MAX_LANES = 3;
|
|
1221
|
+
var MAX_ITEMS = 4;
|
|
1222
|
+
var BARS_TOP = 38;
|
|
1223
|
+
var CELL_CHROME = 16 + 28 + 6;
|
|
1224
|
+
var ITEM_STEP = 29 + 4;
|
|
1225
|
+
var MORE_HEIGHT = 20;
|
|
1226
|
+
function timedSlots(visibleLanes, timedCount, hiddenBars) {
|
|
1227
|
+
if (visibleLanes === 0) return Math.min(timedCount, MAX_ITEMS);
|
|
1228
|
+
const room = ROW_HEIGHT - CELL_CHROME - visibleLanes * LANE_HEIGHT;
|
|
1229
|
+
if (hiddenBars === 0 && timedCount * ITEM_STEP - 4 <= room) return timedCount;
|
|
1230
|
+
return Math.max(0, Math.floor((room - MORE_HEIGHT) / ITEM_STEP));
|
|
1231
|
+
}
|
|
986
1232
|
var MonthView = ({
|
|
987
1233
|
currentDate,
|
|
988
1234
|
events,
|
|
@@ -991,62 +1237,155 @@ var MonthView = ({
|
|
|
991
1237
|
timezone,
|
|
992
1238
|
locale,
|
|
993
1239
|
translations,
|
|
994
|
-
onEventContextMenu
|
|
1240
|
+
onEventContextMenu,
|
|
1241
|
+
onDayEventResize,
|
|
1242
|
+
readonly
|
|
995
1243
|
}) => {
|
|
996
1244
|
const weekStartsOn = resolveWeekStartsOn(locale, 1);
|
|
997
1245
|
const days = useMemo(() => getMonthGrid(currentDate, weekStartsOn), [currentDate, weekStartsOn]);
|
|
998
1246
|
const weekDays = useMemo(() => getWeekDays(currentDate, weekStartsOn), [currentDate, weekStartsOn]);
|
|
999
|
-
const
|
|
1247
|
+
const weeks = useMemo(
|
|
1248
|
+
() => Array.from({ length: Math.ceil(days.length / 7) }, (_, i) => days.slice(i * 7, i * 7 + 7)),
|
|
1249
|
+
[days]
|
|
1250
|
+
);
|
|
1251
|
+
const { dayEvents, timedEvents } = partitionDayEvents(events, timezone);
|
|
1252
|
+
const eventsByDay = eventsByStartDay(timedEvents, timezone);
|
|
1000
1253
|
const today = displayToday(timezone);
|
|
1001
|
-
return /* @__PURE__ */
|
|
1254
|
+
return /* @__PURE__ */ React8.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__ */ React8.createElement("div", { className: "overflow-y-auto flex-1 relative" }, /* @__PURE__ */ React8.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__ */ React8.createElement(
|
|
1002
1255
|
"div",
|
|
1003
1256
|
{
|
|
1004
1257
|
key: day.toISOString(),
|
|
1005
1258
|
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"
|
|
1006
1259
|
},
|
|
1007
|
-
|
|
1008
|
-
))),
|
|
1009
|
-
const
|
|
1010
|
-
const
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
),
|
|
1024
|
-
onClick: () => onDateClick?.(day)
|
|
1025
|
-
},
|
|
1026
|
-
/* @__PURE__ */ React7.createElement("div", { className: "flex justify-between items-start" }, /* @__PURE__ */ React7.createElement("div", { className: cn(
|
|
1027
|
-
"text-sm font-semibold w-7 h-7 flex items-center justify-center rounded-full transition-all duration-200",
|
|
1028
|
-
isSameDay3(day, today) ? "bg-primary text-primary-foreground shadow-md shadow-primary/30" : "group-hover:bg-accent"
|
|
1029
|
-
) }, format7(day, "d", { locale })), dayEvents.length > 0 && /* @__PURE__ */ React7.createElement("div", { className: "text-[10px] font-medium text-muted-foreground/60 bg-muted/50 px-1.5 py-0.5 rounded-full" }, dayEvents.length)),
|
|
1030
|
-
/* @__PURE__ */ React7.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__ */ React7.createElement(EventItem, { key: `${event.id}-${dayKey2}`, event, onEventClick, onEventContextMenu })), dayEvents.length > 4 && // U7: "+N more" opens the day instead of doing nothing.
|
|
1031
|
-
/* @__PURE__ */ React7.createElement(
|
|
1032
|
-
"button",
|
|
1260
|
+
format8(day, "EEE", { locale })
|
|
1261
|
+
))), weeks.map((week) => {
|
|
1262
|
+
const { segments, laneCount } = layoutDayRow(week, dayEvents, timezone);
|
|
1263
|
+
const visibleLanes = Math.min(laneCount, MAX_LANES);
|
|
1264
|
+
return /* @__PURE__ */ React8.createElement("div", { key: week[0].toISOString(), className: "relative grid grid-cols-7", style: { height: ROW_HEIGHT } }, week.map((day, column) => {
|
|
1265
|
+
const dayKey2 = format8(day, "yyyy-MM-dd");
|
|
1266
|
+
const dayTimed = eventsByDay.get(dayKey2) || [];
|
|
1267
|
+
const barsOnDay = segments.filter((s) => column >= s.startCol && column < s.startCol + s.span);
|
|
1268
|
+
const hiddenBars = barsOnDay.filter((s) => s.lane >= MAX_LANES).length;
|
|
1269
|
+
const shown = timedSlots(visibleLanes, dayTimed.length, hiddenBars);
|
|
1270
|
+
const hidden = hiddenBars + dayTimed.length - shown;
|
|
1271
|
+
const total = barsOnDay.length + dayTimed.length;
|
|
1272
|
+
const isCurrentMonth = isSameMonth2(day, currentDate);
|
|
1273
|
+
const cellId = day.toISOString();
|
|
1274
|
+
return /* @__PURE__ */ React8.createElement(
|
|
1275
|
+
DroppableCell,
|
|
1033
1276
|
{
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1277
|
+
key: cellId,
|
|
1278
|
+
id: cellId,
|
|
1279
|
+
date: day,
|
|
1280
|
+
className: cn(
|
|
1281
|
+
"h-full 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",
|
|
1282
|
+
!isCurrentMonth && "bg-muted/5 text-muted-foreground/60",
|
|
1283
|
+
isSameDay3(day, today) && "bg-primary/5 ring-1 ring-inset ring-primary/20"
|
|
1284
|
+
),
|
|
1285
|
+
onClick: () => onDateClick?.(day)
|
|
1040
1286
|
},
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1287
|
+
/* @__PURE__ */ React8.createElement("div", { className: "flex justify-between items-start" }, /* @__PURE__ */ React8.createElement("div", { className: cn(
|
|
1288
|
+
"text-sm font-semibold w-7 h-7 flex items-center justify-center rounded-full transition-all duration-200",
|
|
1289
|
+
isSameDay3(day, today) ? "bg-primary text-primary-foreground shadow-md shadow-primary/30" : "group-hover:bg-accent"
|
|
1290
|
+
) }, format8(day, "d", { locale })), total > 0 && /* @__PURE__ */ React8.createElement("div", { className: "text-[10px] font-medium text-muted-foreground/60 bg-muted/50 px-1.5 py-0.5 rounded-full" }, total)),
|
|
1291
|
+
visibleLanes > 0 && /* @__PURE__ */ React8.createElement("div", { className: "shrink-0", style: { height: visibleLanes * LANE_HEIGHT - 6 } }),
|
|
1292
|
+
/* @__PURE__ */ React8.createElement("div", { className: "flex-1 flex flex-col gap-1 scrollbar-hide overflow-y-auto overflow-x-hidden" }, dayTimed.slice(0, shown).map((event) => /* @__PURE__ */ React8.createElement(EventItem, { key: `${event.id}-${dayKey2}`, event, onEventClick, onEventContextMenu })), hidden > 0 && // "+N more" counts hidden bars and hidden timed events, and opens the day.
|
|
1293
|
+
/* @__PURE__ */ React8.createElement(
|
|
1294
|
+
"button",
|
|
1295
|
+
{
|
|
1296
|
+
type: "button",
|
|
1297
|
+
className: "shrink-0 text-[10px] leading-4 text-primary font-semibold text-center py-0.5 px-2 rounded-md bg-primary/5 hover:bg-primary/10 cursor-pointer transition-colors",
|
|
1298
|
+
onClick: (e) => {
|
|
1299
|
+
e.stopPropagation();
|
|
1300
|
+
onDateClick?.(day);
|
|
1301
|
+
}
|
|
1302
|
+
},
|
|
1303
|
+
interpolate(translations?.moreEvents || "+{n} more", { n: hidden })
|
|
1304
|
+
))
|
|
1305
|
+
);
|
|
1306
|
+
}), /* @__PURE__ */ React8.createElement("div", { className: "absolute inset-x-0 pointer-events-none", style: { top: BARS_TOP, height: visibleLanes * LANE_HEIGHT } }, segments.filter((s) => s.lane < MAX_LANES).map((segment) => /* @__PURE__ */ React8.createElement("div", { key: `${segment.event.id}-${week[0].toISOString()}`, className: "pointer-events-auto" }, /* @__PURE__ */ React8.createElement(
|
|
1307
|
+
AllDayBar,
|
|
1308
|
+
{
|
|
1309
|
+
segment,
|
|
1310
|
+
rowDays: week,
|
|
1311
|
+
laneHeight: LANE_HEIGHT,
|
|
1312
|
+
timezone,
|
|
1313
|
+
locale,
|
|
1314
|
+
translations,
|
|
1315
|
+
readonly,
|
|
1316
|
+
onEventClick,
|
|
1317
|
+
onEventContextMenu,
|
|
1318
|
+
onDayEventResize
|
|
1319
|
+
}
|
|
1320
|
+
)))));
|
|
1321
|
+
})));
|
|
1045
1322
|
};
|
|
1046
1323
|
|
|
1047
1324
|
// src/views/WeekView.tsx
|
|
1048
|
-
import
|
|
1049
|
-
import { addDays as
|
|
1325
|
+
import React11 from "react";
|
|
1326
|
+
import { addDays as addDays5, format as format10, differenceInMinutes, isSameDay as isSameDay4 } from "date-fns";
|
|
1327
|
+
|
|
1328
|
+
// src/components/AllDayRow.tsx
|
|
1329
|
+
import React9, { useCallback, useEffect as useEffect2, useState as useState3 } from "react";
|
|
1330
|
+
import { format as format9 } from "date-fns";
|
|
1331
|
+
var LANE_HEIGHT2 = 22;
|
|
1332
|
+
var AllDayRowImpl = ({
|
|
1333
|
+
days,
|
|
1334
|
+
dayEvents,
|
|
1335
|
+
timezone,
|
|
1336
|
+
locale,
|
|
1337
|
+
translations,
|
|
1338
|
+
readonly,
|
|
1339
|
+
gutterClassName,
|
|
1340
|
+
maxLanes = 2,
|
|
1341
|
+
onEventClick,
|
|
1342
|
+
onEventContextMenu,
|
|
1343
|
+
onDayEventResize,
|
|
1344
|
+
onSlotClick
|
|
1345
|
+
}) => {
|
|
1346
|
+
const [expanded, setExpanded] = useState3(false);
|
|
1347
|
+
const rowKey = days.length ? format9(days[0], "yyyy-MM-dd") : "";
|
|
1348
|
+
useEffect2(() => setExpanded(false), [rowKey]);
|
|
1349
|
+
const handleSlotClick = useCallback((day) => onSlotClick?.(day), [onSlotClick]);
|
|
1350
|
+
const { segments, laneCount } = layoutDayRow(days, dayEvents, timezone);
|
|
1351
|
+
const visibleLanes = expanded ? laneCount : Math.min(laneCount, maxLanes);
|
|
1352
|
+
const hidden = segments.filter((segment) => segment.lane >= visibleLanes).length;
|
|
1353
|
+
const height = Math.max(visibleLanes, 1) * LANE_HEIGHT2 + 4;
|
|
1354
|
+
return /* @__PURE__ */ React9.createElement("div", { className: "flex border-b-[0.5px] border-border/50 bg-background", "data-all-day-row": true }, /* @__PURE__ */ React9.createElement("div", { className: cn("flex-none flex flex-col items-end justify-start gap-0.5 pr-2 pt-1 text-[10px] text-muted-foreground border-r-[0.5px] border-border/30", gutterClassName) }, /* @__PURE__ */ React9.createElement("span", null, translations?.allDay || "All Day"), laneCount > maxLanes && /* @__PURE__ */ React9.createElement(
|
|
1355
|
+
"button",
|
|
1356
|
+
{
|
|
1357
|
+
type: "button",
|
|
1358
|
+
className: "text-primary font-semibold hover:underline",
|
|
1359
|
+
onClick: () => setExpanded(!expanded)
|
|
1360
|
+
},
|
|
1361
|
+
expanded ? translations?.showLess || "Show less" : interpolate(translations?.moreEvents || "+{n} more", { n: hidden })
|
|
1362
|
+
)), /* @__PURE__ */ React9.createElement("div", { className: "flex-1 relative", style: { height } }, /* @__PURE__ */ React9.createElement("div", { className: "absolute inset-0 grid", style: { gridTemplateColumns: `repeat(${days.length}, minmax(0, 1fr))` } }, days.map((day, index) => /* @__PURE__ */ React9.createElement(
|
|
1363
|
+
DroppableCell,
|
|
1364
|
+
{
|
|
1365
|
+
key: day.toISOString(),
|
|
1366
|
+
id: `all-day-${day.toISOString()}`,
|
|
1367
|
+
date: day,
|
|
1368
|
+
allDayRow: true,
|
|
1369
|
+
className: cn("h-full", index > 0 && "border-l-[0.5px] border-border/30"),
|
|
1370
|
+
onSlotClick: readonly || !onSlotClick ? void 0 : handleSlotClick
|
|
1371
|
+
}
|
|
1372
|
+
))), /* @__PURE__ */ React9.createElement("div", { className: "absolute inset-x-0 top-0 pointer-events-none", style: { height } }, segments.filter((segment) => segment.lane < visibleLanes).map((segment) => /* @__PURE__ */ React9.createElement("div", { key: `${segment.event.id}-${rowKey}`, className: "pointer-events-auto" }, /* @__PURE__ */ React9.createElement(
|
|
1373
|
+
AllDayBar,
|
|
1374
|
+
{
|
|
1375
|
+
segment,
|
|
1376
|
+
rowDays: days,
|
|
1377
|
+
laneHeight: LANE_HEIGHT2,
|
|
1378
|
+
timezone,
|
|
1379
|
+
locale,
|
|
1380
|
+
translations,
|
|
1381
|
+
readonly,
|
|
1382
|
+
onEventClick,
|
|
1383
|
+
onEventContextMenu,
|
|
1384
|
+
onDayEventResize
|
|
1385
|
+
}
|
|
1386
|
+
))))));
|
|
1387
|
+
};
|
|
1388
|
+
var AllDayRow = React9.memo(AllDayRowImpl);
|
|
1050
1389
|
|
|
1051
1390
|
// src/core/layout.ts
|
|
1052
1391
|
var layoutCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -1087,9 +1426,10 @@ function layoutDayEvents(segments) {
|
|
|
1087
1426
|
}
|
|
1088
1427
|
|
|
1089
1428
|
// src/components/dnd/ResizableEvent.tsx
|
|
1090
|
-
import
|
|
1429
|
+
import React10, { useState as useState4, useRef as useRef2, useCallback as useCallback2 } from "react";
|
|
1091
1430
|
|
|
1092
1431
|
// src/core/dnd.ts
|
|
1432
|
+
import { addDays as addDays4, differenceInCalendarDays as differenceInCalendarDays3, startOfDay as startOfDay4 } from "date-fns";
|
|
1093
1433
|
function computeDrop({ event, overDate, overResourceId, grabOffsetMs = 0, view, tz }) {
|
|
1094
1434
|
let wallStart;
|
|
1095
1435
|
if (view === "month") {
|
|
@@ -1110,6 +1450,23 @@ function computeResizeEnd(event, deltaMinutes, minDuration = 15) {
|
|
|
1110
1450
|
const minEnd = event.start.getTime() + minDuration * 6e4;
|
|
1111
1451
|
return new Date(Math.max(event.end.getTime() + deltaMinutes * 6e4, minEnd));
|
|
1112
1452
|
}
|
|
1453
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
1454
|
+
var shiftDays = (date, days, event, tz) => event.allDay ? addDays4(date, days) : fromDisplay(addDays4(toDisplay(date, tz), days), tz);
|
|
1455
|
+
function computeDayMove(event, overDay, grabDayOffset, tz) {
|
|
1456
|
+
const { firstDay } = dayEventSpan(event, tz);
|
|
1457
|
+
const days = differenceInCalendarDays3(addDays4(startOfDay4(overDay), -grabDayOffset), firstDay);
|
|
1458
|
+
if (days === 0) return null;
|
|
1459
|
+
return { start: shiftDays(event.start, days, event, tz), end: shiftDays(event.end, days, event, tz) };
|
|
1460
|
+
}
|
|
1461
|
+
function computeDayResize(event, newLastDay, tz) {
|
|
1462
|
+
const { firstDay, lastDay } = dayEventSpan(event, tz);
|
|
1463
|
+
const target = startOfDay4(newLastDay) < firstDay ? firstDay : startOfDay4(newLastDay);
|
|
1464
|
+
const days = differenceInCalendarDays3(target, lastDay);
|
|
1465
|
+
if (days === 0) return null;
|
|
1466
|
+
if (event.allDay) return addDays4(target, 1);
|
|
1467
|
+
const end = new Date(Math.max(shiftDays(event.end, days, event, tz).getTime(), event.start.getTime() + DAY_MS));
|
|
1468
|
+
return end.getTime() === event.end.getTime() ? null : end;
|
|
1469
|
+
}
|
|
1113
1470
|
|
|
1114
1471
|
// src/components/dnd/ResizableEvent.tsx
|
|
1115
1472
|
var ResizableEvent = ({
|
|
@@ -1123,13 +1480,13 @@ var ResizableEvent = ({
|
|
|
1123
1480
|
readonly
|
|
1124
1481
|
}) => {
|
|
1125
1482
|
const resizeLocked = readonly || isEventResizeDisabled(event);
|
|
1126
|
-
const [isResizing, setIsResizing] =
|
|
1127
|
-
const [resizeHeight, setResizeHeight] =
|
|
1128
|
-
const containerRef =
|
|
1129
|
-
const startYRef =
|
|
1130
|
-
const startHeightRef =
|
|
1131
|
-
const resizeHeightRef =
|
|
1132
|
-
const handleResizeStart =
|
|
1483
|
+
const [isResizing, setIsResizing] = useState4(false);
|
|
1484
|
+
const [resizeHeight, setResizeHeight] = useState4(null);
|
|
1485
|
+
const containerRef = useRef2(null);
|
|
1486
|
+
const startYRef = useRef2(0);
|
|
1487
|
+
const startHeightRef = useRef2(0);
|
|
1488
|
+
const resizeHeightRef = useRef2(null);
|
|
1489
|
+
const handleResizeStart = useCallback2((e) => {
|
|
1133
1490
|
e.preventDefault();
|
|
1134
1491
|
e.stopPropagation();
|
|
1135
1492
|
const clientY = "touches" in e ? e.touches[0].clientY : e.clientY;
|
|
@@ -1168,10 +1525,10 @@ var ResizableEvent = ({
|
|
|
1168
1525
|
document.addEventListener("touchmove", handleMove, { passive: false });
|
|
1169
1526
|
document.addEventListener("touchend", handleEnd);
|
|
1170
1527
|
}, [event, hourHeight, minDuration, onResize]);
|
|
1171
|
-
const handlePointerDown =
|
|
1528
|
+
const handlePointerDown = useCallback2((e) => {
|
|
1172
1529
|
e.stopPropagation();
|
|
1173
1530
|
}, []);
|
|
1174
|
-
return /* @__PURE__ */
|
|
1531
|
+
return /* @__PURE__ */ React10.createElement(
|
|
1175
1532
|
"div",
|
|
1176
1533
|
{
|
|
1177
1534
|
ref: containerRef,
|
|
@@ -1182,7 +1539,7 @@ var ResizableEvent = ({
|
|
|
1182
1539
|
}
|
|
1183
1540
|
},
|
|
1184
1541
|
children,
|
|
1185
|
-
/* @__PURE__ */
|
|
1542
|
+
/* @__PURE__ */ React10.createElement(
|
|
1186
1543
|
"div",
|
|
1187
1544
|
{
|
|
1188
1545
|
className: cn(
|
|
@@ -1195,12 +1552,12 @@ var ResizableEvent = ({
|
|
|
1195
1552
|
onMouseDown: resizeLocked ? void 0 : handleResizeStart,
|
|
1196
1553
|
onTouchStart: resizeLocked ? void 0 : handleResizeStart
|
|
1197
1554
|
},
|
|
1198
|
-
/* @__PURE__ */
|
|
1555
|
+
/* @__PURE__ */ React10.createElement("div", { className: cn(
|
|
1199
1556
|
"w-8 h-1 rounded-full transition-all",
|
|
1200
1557
|
isResizing ? "bg-primary" : "bg-muted-foreground/30 group-hover:bg-primary/50"
|
|
1201
1558
|
) })
|
|
1202
1559
|
),
|
|
1203
|
-
isResizing && /* @__PURE__ */
|
|
1560
|
+
isResizing && /* @__PURE__ */ React10.createElement("div", { className: "absolute inset-0 border-2 border-primary border-dashed rounded-md pointer-events-none bg-primary/5" })
|
|
1204
1561
|
);
|
|
1205
1562
|
};
|
|
1206
1563
|
|
|
@@ -1223,29 +1580,33 @@ var WeekViewImpl = ({
|
|
|
1223
1580
|
timezone,
|
|
1224
1581
|
locale,
|
|
1225
1582
|
readonly,
|
|
1226
|
-
onEventContextMenu
|
|
1583
|
+
onEventContextMenu,
|
|
1584
|
+
onDayEventResize,
|
|
1585
|
+
onAllDaySlotClick,
|
|
1586
|
+
translations
|
|
1227
1587
|
}) => {
|
|
1228
|
-
const weekDays =
|
|
1588
|
+
const weekDays = React11.useMemo(
|
|
1229
1589
|
() => getWeekDays(currentDate, resolveWeekStartsOn(locale, 1)),
|
|
1230
1590
|
[currentDate, locale]
|
|
1231
1591
|
);
|
|
1232
|
-
const visibleRange =
|
|
1233
|
-
() => ({ start: weekDays[0], end:
|
|
1592
|
+
const visibleRange = React11.useMemo(
|
|
1593
|
+
() => ({ start: weekDays[0], end: addDays5(weekDays[weekDays.length - 1], 1) }),
|
|
1234
1594
|
[weekDays]
|
|
1235
1595
|
);
|
|
1236
|
-
const scrollContainerRef =
|
|
1237
|
-
const [now, setNow] =
|
|
1238
|
-
|
|
1596
|
+
const scrollContainerRef = React11.useRef(null);
|
|
1597
|
+
const [now, setNow] = React11.useState(() => /* @__PURE__ */ new Date());
|
|
1598
|
+
React11.useEffect(() => {
|
|
1239
1599
|
const interval = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
|
|
1240
1600
|
return () => clearInterval(interval);
|
|
1241
1601
|
}, []);
|
|
1242
|
-
|
|
1602
|
+
React11.useEffect(() => {
|
|
1243
1603
|
if (scrollContainerRef.current) {
|
|
1244
1604
|
const offsetHour = 4;
|
|
1245
1605
|
scrollContainerRef.current.scrollTop = (toDisplay(/* @__PURE__ */ new Date(), timezone).getHours() - offsetHour) * HOUR_HEIGHT;
|
|
1246
1606
|
}
|
|
1247
1607
|
}, [timezone]);
|
|
1248
|
-
const
|
|
1608
|
+
const { dayEvents, timedEvents } = partitionDayEvents(events, timezone);
|
|
1609
|
+
const segmentsByDay = segmentsByDisplayDay(timedEvents, timezone, visibleRange);
|
|
1249
1610
|
const today = displayToday(timezone, now);
|
|
1250
1611
|
const zonedNow = toDisplay(now, timezone);
|
|
1251
1612
|
const nowTop = minutesSinceDisplayMidnight(now, timezone) / 60 * HOUR_HEIGHT;
|
|
@@ -1253,42 +1614,57 @@ var WeekViewImpl = ({
|
|
|
1253
1614
|
const zone = resolveTimeZone(timezone);
|
|
1254
1615
|
const zoneLabel = timeZoneAbbreviation(now, zone) || zone || "LOC";
|
|
1255
1616
|
const formats = timeFormats(locale);
|
|
1256
|
-
return /* @__PURE__ */
|
|
1617
|
+
return /* @__PURE__ */ React11.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__ */ React11.createElement(
|
|
1257
1618
|
"div",
|
|
1258
1619
|
{
|
|
1259
1620
|
ref: scrollContainerRef,
|
|
1260
1621
|
className: "flex-1 overflow-y-auto scrollbar-hide relative bg-background scroll-smooth"
|
|
1261
1622
|
},
|
|
1262
|
-
/* @__PURE__ */
|
|
1623
|
+
/* @__PURE__ */ React11.createElement("div", { className: "sticky top-0 z-20" }, /* @__PURE__ */ React11.createElement("div", { className: "flex border-b-[0.5px] border-border/50 bg-gradient-to-r from-muted/20 via-background to-muted/20 backdrop-blur-sm" }, /* @__PURE__ */ React11.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__ */ React11.createElement("div", { className: "flex flex-col items-center justify-center leading-tight" }, /* @__PURE__ */ React11.createElement("span", null, format10(zonedNow, "HH:mm")), /* @__PURE__ */ React11.createElement("span", { className: "text-[10px] opacity-75" }, "(", zoneLabel, ")"))), /* @__PURE__ */ React11.createElement("div", { className: "flex-1 grid grid-cols-7" }, weekDays.map((day, index) => /* @__PURE__ */ React11.createElement("div", { key: day.toISOString(), className: cn("py-3 px-2 text-center", index > 0 && "border-l-[0.5px] border-border/30") }, /* @__PURE__ */ React11.createElement("div", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider mb-1.5" }, format10(day, "EEE", { locale })), /* @__PURE__ */ React11.createElement("div", { className: cn(
|
|
1263
1624
|
"w-9 h-9 flex items-center justify-center rounded-xl mx-auto text-sm font-semibold transition-all duration-200",
|
|
1264
1625
|
isSameDay4(day, today) ? "bg-primary text-primary-foreground shadow-lg shadow-primary/30 scale-110" : "text-foreground hover:bg-accent/80"
|
|
1265
|
-
) },
|
|
1266
|
-
|
|
1626
|
+
) }, format10(day, "d", { locale })))))), /* @__PURE__ */ React11.createElement(
|
|
1627
|
+
AllDayRow,
|
|
1628
|
+
{
|
|
1629
|
+
days: weekDays,
|
|
1630
|
+
dayEvents,
|
|
1631
|
+
timezone,
|
|
1632
|
+
locale,
|
|
1633
|
+
translations,
|
|
1634
|
+
readonly,
|
|
1635
|
+
gutterClassName: "w-16",
|
|
1636
|
+
onEventClick,
|
|
1637
|
+
onEventContextMenu,
|
|
1638
|
+
onDayEventResize,
|
|
1639
|
+
onSlotClick: onAllDaySlotClick
|
|
1640
|
+
}
|
|
1641
|
+
)),
|
|
1642
|
+
/* @__PURE__ */ React11.createElement(
|
|
1267
1643
|
"div",
|
|
1268
1644
|
{
|
|
1269
1645
|
className: "flex min-w-full relative",
|
|
1270
1646
|
style: { height: HOURS.length * HOUR_HEIGHT }
|
|
1271
1647
|
},
|
|
1272
|
-
/* @__PURE__ */
|
|
1648
|
+
/* @__PURE__ */ React11.createElement("div", { className: "flex-none w-16 border-r-[0.5px] border-border/30 relative bg-muted/5" }, HOURS.map((hour) => /* @__PURE__ */ React11.createElement(
|
|
1273
1649
|
"div",
|
|
1274
1650
|
{
|
|
1275
1651
|
key: hour,
|
|
1276
1652
|
className: "relative w-full text-[11px] text-muted-foreground/80 text-right pr-3 font-medium tabular-nums box-border",
|
|
1277
1653
|
style: { height: HOUR_HEIGHT }
|
|
1278
1654
|
},
|
|
1279
|
-
/* @__PURE__ */
|
|
1280
|
-
)), showsToday && /* @__PURE__ */
|
|
1655
|
+
/* @__PURE__ */ React11.createElement("span", { className: "block -translate-y-1/2" }, hour !== 0 && format10(slotDate(currentDate, hour, 0), formats.hour, { locale }))
|
|
1656
|
+
)), showsToday && /* @__PURE__ */ React11.createElement(
|
|
1281
1657
|
"div",
|
|
1282
1658
|
{
|
|
1283
1659
|
className: "absolute left-0 w-full pointer-events-none z-30 flex justify-end pr-2",
|
|
1284
1660
|
style: { top: `${nowTop}px` }
|
|
1285
1661
|
},
|
|
1286
|
-
/* @__PURE__ */
|
|
1662
|
+
/* @__PURE__ */ React11.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" }, format10(zonedNow, formats.compact, { locale }))
|
|
1287
1663
|
)),
|
|
1288
|
-
/* @__PURE__ */
|
|
1289
|
-
const dayKey2 =
|
|
1664
|
+
/* @__PURE__ */ React11.createElement("div", { className: "flex-1 grid grid-cols-7 relative" }, weekDays.map((day, dayIndex) => {
|
|
1665
|
+
const dayKey2 = format10(day, "yyyy-MM-dd");
|
|
1290
1666
|
const positioned = layoutDayEvents(segmentsByDay.get(dayKey2) ?? NO_SEGMENTS);
|
|
1291
|
-
return /* @__PURE__ */
|
|
1667
|
+
return /* @__PURE__ */ React11.createElement("div", { key: dayKey2, className: cn("relative h-full", dayIndex > 0 && "border-l-[0.5px] border-border/30") }, HOURS.map((hour) => /* @__PURE__ */ React11.createElement(
|
|
1292
1668
|
"div",
|
|
1293
1669
|
{
|
|
1294
1670
|
key: hour,
|
|
@@ -1297,7 +1673,7 @@ var WeekViewImpl = ({
|
|
|
1297
1673
|
},
|
|
1298
1674
|
QUARTERS.map((minute) => {
|
|
1299
1675
|
const cellDate = slotDate(day, hour, minute);
|
|
1300
|
-
return /* @__PURE__ */
|
|
1676
|
+
return /* @__PURE__ */ React11.createElement(
|
|
1301
1677
|
DroppableCell,
|
|
1302
1678
|
{
|
|
1303
1679
|
key: minute,
|
|
@@ -1323,7 +1699,7 @@ var WeekViewImpl = ({
|
|
|
1323
1699
|
const height = durationMinutes / 60 * HOUR_HEIGHT;
|
|
1324
1700
|
const isShortEvent = durationMinutes < 60;
|
|
1325
1701
|
const isLastSegment = end.getTime() === zonedEventEnd.getTime();
|
|
1326
|
-
return /* @__PURE__ */
|
|
1702
|
+
return /* @__PURE__ */ React11.createElement(
|
|
1327
1703
|
DraggableEvent,
|
|
1328
1704
|
{
|
|
1329
1705
|
key: `${event.id}-${dayKey2}`,
|
|
@@ -1340,7 +1716,7 @@ var WeekViewImpl = ({
|
|
|
1340
1716
|
paddingRight: columns > 1 ? "2px" : "0"
|
|
1341
1717
|
}
|
|
1342
1718
|
},
|
|
1343
|
-
/* @__PURE__ */
|
|
1719
|
+
/* @__PURE__ */ React11.createElement(
|
|
1344
1720
|
ResizableEvent,
|
|
1345
1721
|
{
|
|
1346
1722
|
readonly: readonly || !isLastSegment,
|
|
@@ -1350,7 +1726,7 @@ var WeekViewImpl = ({
|
|
|
1350
1726
|
className: "h-full",
|
|
1351
1727
|
style: { height: "100%" }
|
|
1352
1728
|
},
|
|
1353
|
-
/* @__PURE__ */
|
|
1729
|
+
/* @__PURE__ */ React11.createElement(
|
|
1354
1730
|
"div",
|
|
1355
1731
|
{
|
|
1356
1732
|
className: cn(
|
|
@@ -1376,31 +1752,31 @@ var WeekViewImpl = ({
|
|
|
1376
1752
|
onContextMenu: onEventContextMenu ? (e) => onEventContextMenu(event, e) : void 0,
|
|
1377
1753
|
title: columns > 1 ? `${event.title} (${column + 1}/${columns})` : void 0
|
|
1378
1754
|
},
|
|
1379
|
-
/* @__PURE__ */
|
|
1755
|
+
/* @__PURE__ */ React11.createElement("div", { className: "flex flex-col h-full overflow-hidden w-full" }, /* @__PURE__ */ React11.createElement("div", { className: cn(
|
|
1380
1756
|
"font-semibold truncate text-foreground/90 leading-tight",
|
|
1381
1757
|
isShortEvent ? "text-xs text-center" : "text-xs"
|
|
1382
|
-
) }, event.title), !isShortEvent && /* @__PURE__ */
|
|
1758
|
+
) }, event.title), !isShortEvent && /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement("div", { className: "text-[10px] text-muted-foreground truncate mt-0.5 font-medium leading-tight" }, format10(zonedEventStart, formats.time, { locale }), " - ", format10(zonedEventEnd, formats.time, { locale })), event.description && height > 50 && /* @__PURE__ */ React11.createElement("div", { className: "text-[10px] text-muted-foreground/80 truncate mt-1 leading-tight opacity-80" }, event.description)), columns > 1 && !isShortEvent && /* @__PURE__ */ React11.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))
|
|
1383
1759
|
)
|
|
1384
1760
|
)
|
|
1385
1761
|
);
|
|
1386
|
-
}), isSameDay4(day, today) && /* @__PURE__ */
|
|
1762
|
+
}), isSameDay4(day, today) && /* @__PURE__ */ React11.createElement(
|
|
1387
1763
|
"div",
|
|
1388
1764
|
{
|
|
1389
1765
|
className: "absolute left-0 right-0 z-20 pointer-events-none flex items-center",
|
|
1390
1766
|
style: { top: `${nowTop}px` }
|
|
1391
1767
|
},
|
|
1392
|
-
/* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1768
|
+
/* @__PURE__ */ React11.createElement("div", { className: "h-[2px] w-full bg-gradient-to-r from-primary via-primary to-primary/50" }),
|
|
1769
|
+
/* @__PURE__ */ React11.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" })
|
|
1394
1770
|
));
|
|
1395
1771
|
}))
|
|
1396
1772
|
)
|
|
1397
1773
|
));
|
|
1398
1774
|
};
|
|
1399
|
-
var WeekView =
|
|
1775
|
+
var WeekView = React11.memo(WeekViewImpl);
|
|
1400
1776
|
|
|
1401
1777
|
// src/views/DayView.tsx
|
|
1402
|
-
import
|
|
1403
|
-
import { addDays as
|
|
1778
|
+
import React12 from "react";
|
|
1779
|
+
import { addDays as addDays6, format as format11, differenceInMinutes as differenceInMinutes2, isSameDay as isSameDay5, startOfDay as startOfDay5 } from "date-fns";
|
|
1404
1780
|
var HOUR_HEIGHT2 = 80;
|
|
1405
1781
|
var HOURS2 = Array.from({ length: 24 }, (_, i) => i);
|
|
1406
1782
|
var QUARTERS2 = [0, 15, 30, 45];
|
|
@@ -1420,46 +1796,65 @@ var DayViewImpl = ({
|
|
|
1420
1796
|
locale,
|
|
1421
1797
|
readonly,
|
|
1422
1798
|
onEventContextMenu,
|
|
1423
|
-
translations
|
|
1799
|
+
translations,
|
|
1800
|
+
onDayEventResize,
|
|
1801
|
+
onAllDaySlotClick
|
|
1424
1802
|
}) => {
|
|
1425
|
-
const visibleRange =
|
|
1426
|
-
const start =
|
|
1427
|
-
return { start, end:
|
|
1803
|
+
const visibleRange = React12.useMemo(() => {
|
|
1804
|
+
const start = startOfDay5(currentDate);
|
|
1805
|
+
return { start, end: addDays6(start, 1) };
|
|
1428
1806
|
}, [currentDate]);
|
|
1429
|
-
const scrollContainerRef =
|
|
1430
|
-
const [now, setNow] =
|
|
1431
|
-
|
|
1807
|
+
const scrollContainerRef = React12.useRef(null);
|
|
1808
|
+
const [now, setNow] = React12.useState(() => /* @__PURE__ */ new Date());
|
|
1809
|
+
React12.useEffect(() => {
|
|
1432
1810
|
const interval = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
|
|
1433
1811
|
return () => clearInterval(interval);
|
|
1434
1812
|
}, []);
|
|
1435
|
-
|
|
1813
|
+
React12.useEffect(() => {
|
|
1436
1814
|
if (scrollContainerRef.current) {
|
|
1437
1815
|
const offsetHour = 3;
|
|
1438
1816
|
scrollContainerRef.current.scrollTop = (toDisplay(/* @__PURE__ */ new Date(), timezone).getHours() - offsetHour) * HOUR_HEIGHT2;
|
|
1439
1817
|
}
|
|
1440
1818
|
}, [timezone]);
|
|
1441
|
-
const dayKey2 =
|
|
1442
|
-
const
|
|
1819
|
+
const dayKey2 = format11(currentDate, "yyyy-MM-dd");
|
|
1820
|
+
const { dayEvents, timedEvents } = partitionDayEvents(events, timezone);
|
|
1821
|
+
const rowDays = React12.useMemo(() => [visibleRange.start], [visibleRange]);
|
|
1822
|
+
const positioned = layoutDayEvents(segmentsByDisplayDay(timedEvents, timezone, visibleRange).get(dayKey2) ?? NO_SEGMENTS2);
|
|
1443
1823
|
const isToday2 = isSameDay5(currentDate, displayToday(timezone, now));
|
|
1444
1824
|
const zonedNow = toDisplay(now, timezone);
|
|
1445
1825
|
const nowTop = minutesSinceDisplayMidnight(now, timezone) / 60 * HOUR_HEIGHT2;
|
|
1446
1826
|
const formats = timeFormats(locale);
|
|
1447
|
-
return /* @__PURE__ */
|
|
1827
|
+
return /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col h-full bg-background border-[0.5px] border-border/50 rounded-2xl overflow-hidden shadow-sm" }, /* @__PURE__ */ React12.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__ */ React12.createElement("div", { className: "flex items-center justify-center gap-3" }, /* @__PURE__ */ React12.createElement("h2", { className: "text-xl font-semibold capitalize text-foreground" }, format11(currentDate, "EEEE, MMMM d, yyyy", { locale })), isToday2 && /* @__PURE__ */ React12.createElement("span", { className: "text-xs font-semibold bg-primary text-primary-foreground px-3 py-1 rounded-full shadow-md shadow-primary/20" }, translations?.today || "Today"))), /* @__PURE__ */ React12.createElement(
|
|
1828
|
+
AllDayRow,
|
|
1829
|
+
{
|
|
1830
|
+
days: rowDays,
|
|
1831
|
+
dayEvents,
|
|
1832
|
+
timezone,
|
|
1833
|
+
locale,
|
|
1834
|
+
translations,
|
|
1835
|
+
readonly,
|
|
1836
|
+
gutterClassName: "w-20",
|
|
1837
|
+
onEventClick,
|
|
1838
|
+
onEventContextMenu,
|
|
1839
|
+
onDayEventResize,
|
|
1840
|
+
onSlotClick: onAllDaySlotClick
|
|
1841
|
+
}
|
|
1842
|
+
), /* @__PURE__ */ React12.createElement("div", { ref: scrollContainerRef, className: "flex-1 overflow-y-auto relative" }, /* @__PURE__ */ React12.createElement("div", { className: "flex relative", style: { height: HOURS2.length * HOUR_HEIGHT2 } }, /* @__PURE__ */ React12.createElement("div", { className: "w-20 bg-muted/5 border-r-[0.5px] border-border/30 relative" }, HOURS2.map((hour) => /* @__PURE__ */ React12.createElement(
|
|
1448
1843
|
"div",
|
|
1449
1844
|
{
|
|
1450
1845
|
key: hour,
|
|
1451
1846
|
className: "relative w-full",
|
|
1452
1847
|
style: { height: HOUR_HEIGHT2 }
|
|
1453
1848
|
},
|
|
1454
|
-
hour !== 0 && /* @__PURE__ */
|
|
1455
|
-
)), isToday2 && /* @__PURE__ */
|
|
1849
|
+
hour !== 0 && /* @__PURE__ */ React12.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" }, format11(slotDate2(currentDate, hour, 0), formats.hour, { locale }))
|
|
1850
|
+
)), isToday2 && /* @__PURE__ */ React12.createElement(
|
|
1456
1851
|
"div",
|
|
1457
1852
|
{
|
|
1458
1853
|
className: "absolute left-0 w-full pointer-events-none z-30 flex justify-end pr-2",
|
|
1459
1854
|
style: { top: `${nowTop}px` }
|
|
1460
1855
|
},
|
|
1461
|
-
/* @__PURE__ */
|
|
1462
|
-
)), /* @__PURE__ */
|
|
1856
|
+
/* @__PURE__ */ React12.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" }, format11(zonedNow, formats.time, { locale }))
|
|
1857
|
+
)), /* @__PURE__ */ React12.createElement("div", { className: "flex-1 relative" }, HOURS2.map((hour) => /* @__PURE__ */ React12.createElement(
|
|
1463
1858
|
"div",
|
|
1464
1859
|
{
|
|
1465
1860
|
key: hour,
|
|
@@ -1468,7 +1863,7 @@ var DayViewImpl = ({
|
|
|
1468
1863
|
},
|
|
1469
1864
|
QUARTERS2.map((minute) => {
|
|
1470
1865
|
const cellDate = slotDate2(currentDate, hour, minute);
|
|
1471
|
-
return /* @__PURE__ */
|
|
1866
|
+
return /* @__PURE__ */ React12.createElement(
|
|
1472
1867
|
DroppableCell,
|
|
1473
1868
|
{
|
|
1474
1869
|
key: minute,
|
|
@@ -1494,7 +1889,7 @@ var DayViewImpl = ({
|
|
|
1494
1889
|
const height = durationMinutes / 60 * HOUR_HEIGHT2;
|
|
1495
1890
|
const isShortEvent = durationMinutes < 45;
|
|
1496
1891
|
const isLastSegment = end.getTime() === zonedEnd.getTime();
|
|
1497
|
-
return /* @__PURE__ */
|
|
1892
|
+
return /* @__PURE__ */ React12.createElement(
|
|
1498
1893
|
DraggableEvent,
|
|
1499
1894
|
{
|
|
1500
1895
|
key: `${event.id}-${dayKey2}`,
|
|
@@ -1510,7 +1905,7 @@ var DayViewImpl = ({
|
|
|
1510
1905
|
paddingRight: columns > 1 ? "2px" : "0"
|
|
1511
1906
|
}
|
|
1512
1907
|
},
|
|
1513
|
-
/* @__PURE__ */
|
|
1908
|
+
/* @__PURE__ */ React12.createElement(
|
|
1514
1909
|
ResizableEvent,
|
|
1515
1910
|
{
|
|
1516
1911
|
readonly: readonly || !isLastSegment,
|
|
@@ -1520,7 +1915,7 @@ var DayViewImpl = ({
|
|
|
1520
1915
|
className: "h-full",
|
|
1521
1916
|
style: { height: "100%" }
|
|
1522
1917
|
},
|
|
1523
|
-
/* @__PURE__ */
|
|
1918
|
+
/* @__PURE__ */ React12.createElement(
|
|
1524
1919
|
"div",
|
|
1525
1920
|
{
|
|
1526
1921
|
className: cn(
|
|
@@ -1544,40 +1939,40 @@ var DayViewImpl = ({
|
|
|
1544
1939
|
onContextMenu: onEventContextMenu ? (e) => onEventContextMenu(event, e) : void 0,
|
|
1545
1940
|
title: columns > 1 ? `${event.title} (${column + 1}/${columns})` : void 0
|
|
1546
1941
|
},
|
|
1547
|
-
/* @__PURE__ */
|
|
1942
|
+
/* @__PURE__ */ React12.createElement("div", { className: "flex flex-col h-full overflow-hidden w-full" }, /* @__PURE__ */ React12.createElement("div", { className: cn(
|
|
1548
1943
|
"font-semibold truncate leading-tight",
|
|
1549
1944
|
isShortEvent ? "text-xs" : "text-sm",
|
|
1550
1945
|
event.color ? "text-foreground" : "text-foreground/90"
|
|
1551
|
-
) }, event.title), !isShortEvent && /* @__PURE__ */
|
|
1946
|
+
) }, event.title), !isShortEvent && /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement("div", { className: "text-xs text-muted-foreground mt-0.5 font-medium" }, format11(zonedStart, formats.time, { locale }), " - ", format11(zonedEnd, formats.time, { locale })), event.description && height > 60 && /* @__PURE__ */ React12.createElement("div", { className: "text-xs text-muted-foreground/80 mt-1 line-clamp-2" }, event.description)), columns > 1 && !isShortEvent && /* @__PURE__ */ React12.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))
|
|
1552
1947
|
)
|
|
1553
1948
|
)
|
|
1554
1949
|
);
|
|
1555
|
-
}), isToday2 && /* @__PURE__ */
|
|
1950
|
+
}), isToday2 && /* @__PURE__ */ React12.createElement(
|
|
1556
1951
|
"div",
|
|
1557
1952
|
{
|
|
1558
1953
|
className: "absolute left-0 right-0 z-20 pointer-events-none flex items-center",
|
|
1559
1954
|
style: { top: `${nowTop}px` }
|
|
1560
1955
|
},
|
|
1561
|
-
/* @__PURE__ */
|
|
1562
|
-
/* @__PURE__ */
|
|
1956
|
+
/* @__PURE__ */ React12.createElement("div", { className: "h-[2px] w-full bg-gradient-to-r from-primary via-primary to-primary/50" }),
|
|
1957
|
+
/* @__PURE__ */ React12.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" })
|
|
1563
1958
|
)))));
|
|
1564
1959
|
};
|
|
1565
|
-
var DayView =
|
|
1960
|
+
var DayView = React12.memo(DayViewImpl);
|
|
1566
1961
|
|
|
1567
1962
|
// src/views/AgendaView.tsx
|
|
1568
|
-
import
|
|
1569
|
-
import { format as
|
|
1963
|
+
import React14, { useMemo as useMemo2 } from "react";
|
|
1964
|
+
import { format as format12, isSameDay as isSameDay6, addDays as addDays7, startOfDay as startOfDay6, differenceInMinutes as differenceInMinutes3 } from "date-fns";
|
|
1570
1965
|
|
|
1571
1966
|
// src/components/EmptyState.tsx
|
|
1572
|
-
import
|
|
1967
|
+
import React13 from "react";
|
|
1573
1968
|
import { Plus as Plus2 } from "lucide-react";
|
|
1574
|
-
var AgendaEmptyState = ({ onCreateEvent, translations }) => /* @__PURE__ */
|
|
1969
|
+
var AgendaEmptyState = ({ onCreateEvent, translations }) => /* @__PURE__ */ React13.createElement("div", { className: "flex flex-col items-center justify-center h-full min-h-[400px] py-12" }, /* @__PURE__ */ React13.createElement("div", { className: "relative mb-8" }, /* @__PURE__ */ React13.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__ */ React13.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React13.createElement("div", { className: "w-12 h-12 rounded-2xl bg-green-100 dark:bg-green-900/30 flex items-center justify-center" }, /* @__PURE__ */ React13.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__ */ React13.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }))), /* @__PURE__ */ React13.createElement("div", { className: "text-left" }, /* @__PURE__ */ React13.createElement("div", { className: "font-medium text-foreground" }, translations?.allCaughtUp || "All caught up!"), /* @__PURE__ */ React13.createElement("div", { className: "text-sm text-muted-foreground" }, translations?.noEventsScheduled || "No events scheduled"))))), /* @__PURE__ */ React13.createElement("div", { className: "text-center max-w-sm" }, /* @__PURE__ */ React13.createElement("h3", { className: "text-lg font-semibold text-foreground mb-2" }, translations?.noUpcoming || "Your schedule is clear"), /* @__PURE__ */ React13.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__ */ React13.createElement(
|
|
1575
1970
|
"button",
|
|
1576
1971
|
{
|
|
1577
1972
|
onClick: onCreateEvent,
|
|
1578
1973
|
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"
|
|
1579
1974
|
},
|
|
1580
|
-
/* @__PURE__ */
|
|
1975
|
+
/* @__PURE__ */ React13.createElement(Plus2, { className: "w-4 h-4" }),
|
|
1581
1976
|
translations?.createEvent || "Create Event"
|
|
1582
1977
|
)));
|
|
1583
1978
|
|
|
@@ -1594,8 +1989,8 @@ var formatDuration = (start, end) => {
|
|
|
1594
1989
|
};
|
|
1595
1990
|
var getDateLabel = (date, today, locale, translations) => {
|
|
1596
1991
|
if (isSameDay6(date, today)) return translations?.today || "Today";
|
|
1597
|
-
if (isSameDay6(date,
|
|
1598
|
-
return
|
|
1992
|
+
if (isSameDay6(date, addDays7(today, 1))) return translations?.tomorrow || "Tomorrow";
|
|
1993
|
+
return format12(date, "EEEE", { locale });
|
|
1599
1994
|
};
|
|
1600
1995
|
var AgendaView = ({
|
|
1601
1996
|
currentDate,
|
|
@@ -1614,8 +2009,8 @@ var AgendaView = ({
|
|
|
1614
2009
|
const byDay = eventsByStartDay(events, timezone);
|
|
1615
2010
|
const groups = [];
|
|
1616
2011
|
for (let i = 0; i < 30; i++) {
|
|
1617
|
-
const day =
|
|
1618
|
-
const dayEvents = byDay.get(
|
|
2012
|
+
const day = addDays7(startOfDay6(currentDate), i);
|
|
2013
|
+
const dayEvents = byDay.get(format12(day, "yyyy-MM-dd"));
|
|
1619
2014
|
if (dayEvents?.length) {
|
|
1620
2015
|
groups.push({ date: day, events: [...dayEvents].sort((a, b) => a.start.getTime() - b.start.getTime()) });
|
|
1621
2016
|
}
|
|
@@ -1635,7 +2030,7 @@ var AgendaView = ({
|
|
|
1635
2030
|
hidden: { opacity: 0, x: -20 },
|
|
1636
2031
|
show: { opacity: 1, x: 0 }
|
|
1637
2032
|
};
|
|
1638
|
-
return /* @__PURE__ */
|
|
2033
|
+
return /* @__PURE__ */ React14.createElement("div", { className: "flex flex-col h-full bg-background overflow-y-auto" }, groupedEvents.length === 0 ? /* @__PURE__ */ React14.createElement(AgendaEmptyState, { onCreateEvent, translations }) : /* @__PURE__ */ React14.createElement(
|
|
1639
2034
|
motion.div,
|
|
1640
2035
|
{
|
|
1641
2036
|
className: "max-w-3xl mx-auto w-full pb-10 px-4 md:px-6",
|
|
@@ -1643,21 +2038,21 @@ var AgendaView = ({
|
|
|
1643
2038
|
initial: "hidden",
|
|
1644
2039
|
animate: "show"
|
|
1645
2040
|
},
|
|
1646
|
-
groupedEvents.map((group) => /* @__PURE__ */
|
|
2041
|
+
groupedEvents.map((group) => /* @__PURE__ */ React14.createElement(
|
|
1647
2042
|
motion.div,
|
|
1648
2043
|
{
|
|
1649
2044
|
key: group.date.toISOString(),
|
|
1650
2045
|
className: "relative",
|
|
1651
2046
|
variants: item
|
|
1652
2047
|
},
|
|
1653
|
-
/* @__PURE__ */
|
|
2048
|
+
/* @__PURE__ */ React14.createElement("div", { className: "sticky top-0 bg-background/95 backdrop-blur-md py-4 z-10 border-b border-border/50" }, /* @__PURE__ */ React14.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React14.createElement("div", { className: cn(
|
|
1654
2049
|
"flex flex-col items-center justify-center w-16 h-16 rounded-2xl transition-all",
|
|
1655
2050
|
isSameDay6(group.date, today) ? "bg-primary text-primary-foreground shadow-lg shadow-primary/30" : "bg-muted/50 text-foreground"
|
|
1656
|
-
) }, /* @__PURE__ */
|
|
2051
|
+
) }, /* @__PURE__ */ React14.createElement("span", { className: "text-2xl font-bold leading-none" }, format12(group.date, "d")), /* @__PURE__ */ React14.createElement("span", { className: "text-xs font-medium uppercase tracking-wide opacity-80" }, format12(group.date, "MMM", { locale }))), /* @__PURE__ */ React14.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React14.createElement("span", { className: cn(
|
|
1657
2052
|
"text-lg font-semibold",
|
|
1658
2053
|
isSameDay6(group.date, today) && "text-primary"
|
|
1659
|
-
) }, getDateLabel(group.date, today, locale, translations)), /* @__PURE__ */
|
|
1660
|
-
/* @__PURE__ */
|
|
2054
|
+
) }, getDateLabel(group.date, today, locale, translations)), /* @__PURE__ */ React14.createElement("span", { className: "text-sm text-muted-foreground" }, group.events.length, " ", group.events.length !== 1 ? translations?.eventPlural || "events" : translations?.eventSingular || "event")))),
|
|
2055
|
+
/* @__PURE__ */ React14.createElement("div", { className: "py-4 space-y-3" }, group.events.map((event) => /* @__PURE__ */ React14.createElement(
|
|
1661
2056
|
motion.div,
|
|
1662
2057
|
{
|
|
1663
2058
|
key: event.id,
|
|
@@ -1672,30 +2067,30 @@ var AgendaView = ({
|
|
|
1672
2067
|
whileHover: { scale: 1.01, y: -2 },
|
|
1673
2068
|
transition: { duration: 0.2 }
|
|
1674
2069
|
},
|
|
1675
|
-
/* @__PURE__ */
|
|
2070
|
+
/* @__PURE__ */ React14.createElement(
|
|
1676
2071
|
"div",
|
|
1677
2072
|
{
|
|
1678
2073
|
className: "absolute left-0 top-3 bottom-3 w-1 rounded-full",
|
|
1679
2074
|
style: { backgroundColor: event.color || "var(--primary)" }
|
|
1680
2075
|
}
|
|
1681
2076
|
),
|
|
1682
|
-
/* @__PURE__ */
|
|
1683
|
-
/* @__PURE__ */
|
|
2077
|
+
/* @__PURE__ */ React14.createElement("div", { className: "flex flex-col items-center min-w-[70px] pl-2" }, event.allDay ? /* @__PURE__ */ React14.createElement("div", { className: "flex flex-col items-center" }, /* @__PURE__ */ React14.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__ */ React14.createElement("div", { className: "flex flex-col items-center" }, /* @__PURE__ */ React14.createElement("span", { className: "text-base font-semibold text-foreground" }, format12(toDisplay(event.start, timezone), compactTimePattern, { locale })), !is24h && /* @__PURE__ */ React14.createElement("span", { className: "text-xs text-muted-foreground uppercase" }, format12(toDisplay(event.start, timezone), "a")), /* @__PURE__ */ React14.createElement("div", { className: "w-px h-3 bg-border my-1" }), /* @__PURE__ */ React14.createElement("span", { className: "text-xs text-muted-foreground/70 font-medium" }, formatDuration(event.start, event.end)))),
|
|
2078
|
+
/* @__PURE__ */ React14.createElement("div", { className: "flex-1 min-w-0 space-y-2" }, /* @__PURE__ */ React14.createElement("div", { className: "flex items-start justify-between gap-2" }, /* @__PURE__ */ React14.createElement("h4", { className: "text-base font-semibold text-foreground group-hover:text-primary transition-colors line-clamp-1" }, event.title), /* @__PURE__ */ React14.createElement(
|
|
1684
2079
|
"div",
|
|
1685
2080
|
{
|
|
1686
2081
|
className: "w-3 h-3 rounded-full shrink-0 mt-1.5",
|
|
1687
2082
|
style: { backgroundColor: event.color || "var(--primary)" }
|
|
1688
2083
|
}
|
|
1689
|
-
)), event.description && /* @__PURE__ */
|
|
1690
|
-
/* @__PURE__ */
|
|
2084
|
+
)), event.description && /* @__PURE__ */ React14.createElement("p", { className: "text-sm text-muted-foreground line-clamp-2 leading-relaxed" }, event.description), /* @__PURE__ */ React14.createElement("div", { className: "flex flex-wrap items-center gap-3 pt-1" }, !event.allDay && /* @__PURE__ */ React14.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ React14.createElement(Clock, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ React14.createElement("span", null, format12(toDisplay(event.start, timezone), timePattern, { locale }), " - ", format12(toDisplay(event.end, timezone), timePattern, { locale }))), event.guests && event.guests.length > 0 && /* @__PURE__ */ React14.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ React14.createElement(Users, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ React14.createElement("span", null, event.guests.length, " ", event.guests.length !== 1 ? translations?.guestsCount || "guests" : translations?.guestCount || "guest")), event.attachments && event.attachments.length > 0 && /* @__PURE__ */ React14.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ React14.createElement(Paperclip, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ React14.createElement("span", null, event.attachments.length)), event.reminders && event.reminders.length > 0 && /* @__PURE__ */ React14.createElement("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground" }, /* @__PURE__ */ React14.createElement(Bell, { className: "w-3.5 h-3.5" }), /* @__PURE__ */ React14.createElement("span", null, event.reminders.length)))),
|
|
2085
|
+
/* @__PURE__ */ React14.createElement("div", { className: "absolute right-4 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-opacity" }, /* @__PURE__ */ React14.createElement("svg", { className: "w-5 h-5 text-muted-foreground", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" }, /* @__PURE__ */ React14.createElement("path", { d: "M9 18l6-6-6-6" })))
|
|
1691
2086
|
)))
|
|
1692
2087
|
))
|
|
1693
2088
|
));
|
|
1694
2089
|
};
|
|
1695
2090
|
|
|
1696
2091
|
// src/views/ResourceView.tsx
|
|
1697
|
-
import
|
|
1698
|
-
import { format as
|
|
2092
|
+
import React15, { useRef as useRef3 } from "react";
|
|
2093
|
+
import { format as format13, startOfDay as startOfDay7, differenceInMinutes as differenceInMinutes4 } from "date-fns";
|
|
1699
2094
|
var ResourceView = ({
|
|
1700
2095
|
currentDate,
|
|
1701
2096
|
events,
|
|
@@ -1707,14 +2102,14 @@ var ResourceView = ({
|
|
|
1707
2102
|
translations,
|
|
1708
2103
|
onEventContextMenu
|
|
1709
2104
|
}) => {
|
|
1710
|
-
const containerRef =
|
|
2105
|
+
const containerRef = useRef3(null);
|
|
1711
2106
|
const hours = Array.from({ length: 24 }, (_, i) => i);
|
|
1712
2107
|
const hourWidth = 100;
|
|
1713
2108
|
const timeFormat = timeFormats(locale).hour;
|
|
1714
2109
|
const getEventStyle = (event) => {
|
|
1715
2110
|
const start = toDisplay(event.start, timezone);
|
|
1716
2111
|
const end = toDisplay(event.end, timezone);
|
|
1717
|
-
const dayStart =
|
|
2112
|
+
const dayStart = startOfDay7(currentDate);
|
|
1718
2113
|
const startMinutes = differenceInMinutes4(start, dayStart);
|
|
1719
2114
|
const durationMinutes = differenceInMinutes4(end, start);
|
|
1720
2115
|
const left = startMinutes / 60 * hourWidth;
|
|
@@ -1725,19 +2120,19 @@ var ResourceView = ({
|
|
|
1725
2120
|
// Min width for visibility
|
|
1726
2121
|
};
|
|
1727
2122
|
};
|
|
1728
|
-
return /* @__PURE__ */
|
|
2123
|
+
return /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col h-full bg-background overflow-hidden" }, /* @__PURE__ */ React15.createElement("div", { className: "flex border-b border-border bg-muted/20" }, /* @__PURE__ */ React15.createElement("div", { className: "w-48 shrink-0 border-r border-border p-4 font-semibold text-sm bg-background sticky left-0 z-20" }, translations?.resource || "Resources"), /* @__PURE__ */ React15.createElement("div", { className: "flex overflow-hidden" }, /* @__PURE__ */ React15.createElement("div", { className: "flex relative", style: { width: hours.length * hourWidth } }, hours.map((hour) => /* @__PURE__ */ React15.createElement(
|
|
1729
2124
|
"div",
|
|
1730
2125
|
{
|
|
1731
2126
|
key: hour,
|
|
1732
2127
|
className: "border-r border-border/50 text-xs text-muted-foreground p-2 font-medium shrink-0",
|
|
1733
2128
|
style: { width: hourWidth }
|
|
1734
2129
|
},
|
|
1735
|
-
|
|
1736
|
-
))))), /* @__PURE__ */
|
|
2130
|
+
format13((/* @__PURE__ */ new Date()).setHours(hour, 0, 0, 0), timeFormat, { locale })
|
|
2131
|
+
))))), /* @__PURE__ */ React15.createElement("div", { className: "flex-1 overflow-auto relative", ref: containerRef }, /* @__PURE__ */ React15.createElement("div", { className: "min-w-fit" }, resources.map((resource) => {
|
|
1737
2132
|
const resourceEvents = events.filter(
|
|
1738
2133
|
(e) => e.resourceId === resource.id && isSameDisplayDay(e.start, currentDate, timezone)
|
|
1739
2134
|
);
|
|
1740
|
-
return /* @__PURE__ */
|
|
2135
|
+
return /* @__PURE__ */ React15.createElement("div", { key: resource.id, className: "flex border-b border-border min-h-[100px]" }, /* @__PURE__ */ React15.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.createElement("img", { src: resource.avatar, alt: resource.label, className: "w-8 h-8 rounded-full object-cover" }) : /* @__PURE__ */ React15.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.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React15.createElement("span", { className: "text-sm font-medium" }, resource.label), /* @__PURE__ */ React15.createElement("span", { className: "text-xs text-muted-foreground" }, interpolate(translations?.idLabel || "ID: {id}", { id: resource.id })))), /* @__PURE__ */ React15.createElement("div", { className: "relative flex", style: { width: hours.length * hourWidth } }, hours.map((hour) => /* @__PURE__ */ React15.createElement(
|
|
1741
2136
|
"div",
|
|
1742
2137
|
{
|
|
1743
2138
|
key: hour,
|
|
@@ -1748,7 +2143,7 @@ var ResourceView = ({
|
|
|
1748
2143
|
const slotDate3 = new Date(currentDate);
|
|
1749
2144
|
slotDate3.setHours(hour, minute, 0, 0);
|
|
1750
2145
|
const slotId = `${resource.id}-${slotDate3.toISOString()}`;
|
|
1751
|
-
return /* @__PURE__ */
|
|
2146
|
+
return /* @__PURE__ */ React15.createElement(
|
|
1752
2147
|
DroppableCell,
|
|
1753
2148
|
{
|
|
1754
2149
|
key: minute,
|
|
@@ -1760,7 +2155,7 @@ var ResourceView = ({
|
|
|
1760
2155
|
}
|
|
1761
2156
|
);
|
|
1762
2157
|
})
|
|
1763
|
-
)), resourceEvents.map((event) => /* @__PURE__ */
|
|
2158
|
+
)), resourceEvents.map((event) => /* @__PURE__ */ React15.createElement(
|
|
1764
2159
|
DraggableEvent,
|
|
1765
2160
|
{
|
|
1766
2161
|
key: event.id,
|
|
@@ -1778,16 +2173,16 @@ var ResourceView = ({
|
|
|
1778
2173
|
color: "#fff"
|
|
1779
2174
|
}
|
|
1780
2175
|
},
|
|
1781
|
-
/* @__PURE__ */
|
|
2176
|
+
/* @__PURE__ */ React15.createElement("div", { className: "truncate" }, event.title)
|
|
1782
2177
|
))));
|
|
1783
2178
|
}))));
|
|
1784
2179
|
};
|
|
1785
2180
|
|
|
1786
2181
|
// src/components/EventModal.tsx
|
|
1787
|
-
import
|
|
2182
|
+
import React17, { useState as useState5, useEffect as useEffect4, useInsertionEffect, useRef as useRef5 } from "react";
|
|
1788
2183
|
|
|
1789
2184
|
// src/components/ui/Modal.tsx
|
|
1790
|
-
import
|
|
2185
|
+
import React16, { useEffect as useEffect3, useRef as useRef4 } from "react";
|
|
1791
2186
|
import { X } from "lucide-react";
|
|
1792
2187
|
var Modal = ({
|
|
1793
2188
|
isOpen,
|
|
@@ -1798,8 +2193,8 @@ var Modal = ({
|
|
|
1798
2193
|
hideHeader = false,
|
|
1799
2194
|
closeLabel = "Close"
|
|
1800
2195
|
}) => {
|
|
1801
|
-
const overlayRef =
|
|
1802
|
-
|
|
2196
|
+
const overlayRef = useRef4(null);
|
|
2197
|
+
useEffect3(() => {
|
|
1803
2198
|
const handleEscape = (e) => {
|
|
1804
2199
|
if (e.key === "Escape") {
|
|
1805
2200
|
onClose();
|
|
@@ -1813,14 +2208,14 @@ var Modal = ({
|
|
|
1813
2208
|
};
|
|
1814
2209
|
}, [isOpen, onClose]);
|
|
1815
2210
|
if (!isOpen) return null;
|
|
1816
|
-
return /* @__PURE__ */
|
|
2211
|
+
return /* @__PURE__ */ React16.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__ */ React16.createElement(
|
|
1817
2212
|
"div",
|
|
1818
2213
|
{
|
|
1819
2214
|
ref: overlayRef,
|
|
1820
2215
|
className: "absolute inset-0",
|
|
1821
2216
|
onClick: onClose
|
|
1822
2217
|
}
|
|
1823
|
-
), /* @__PURE__ */
|
|
2218
|
+
), /* @__PURE__ */ React16.createElement(
|
|
1824
2219
|
"div",
|
|
1825
2220
|
{
|
|
1826
2221
|
className: cn(
|
|
@@ -1828,7 +2223,7 @@ var Modal = ({
|
|
|
1828
2223
|
className
|
|
1829
2224
|
)
|
|
1830
2225
|
},
|
|
1831
|
-
!hideHeader && /* @__PURE__ */
|
|
2226
|
+
!hideHeader && /* @__PURE__ */ React16.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__ */ React16.createElement("h3", { className: "text-lg font-semibold text-foreground" }, title), /* @__PURE__ */ React16.createElement(
|
|
1832
2227
|
Button,
|
|
1833
2228
|
{
|
|
1834
2229
|
variant: "ghost",
|
|
@@ -1836,15 +2231,15 @@ var Modal = ({
|
|
|
1836
2231
|
onClick: onClose,
|
|
1837
2232
|
className: "h-9 w-9 p-0 rounded-xl hover:bg-accent/80 transition-all duration-200"
|
|
1838
2233
|
},
|
|
1839
|
-
/* @__PURE__ */
|
|
1840
|
-
/* @__PURE__ */
|
|
2234
|
+
/* @__PURE__ */ React16.createElement(X, { className: "h-4 w-4" }),
|
|
2235
|
+
/* @__PURE__ */ React16.createElement("span", { className: "sr-only" }, closeLabel)
|
|
1841
2236
|
)),
|
|
1842
|
-
/* @__PURE__ */
|
|
2237
|
+
/* @__PURE__ */ React16.createElement("div", { className: cn("overflow-y-auto flex-1", !hideHeader && "p-6") }, children)
|
|
1843
2238
|
));
|
|
1844
2239
|
};
|
|
1845
2240
|
|
|
1846
2241
|
// src/components/EventModal.tsx
|
|
1847
|
-
import { format as
|
|
2242
|
+
import { addDays as addDays8, differenceInCalendarDays as differenceInCalendarDays4, format as format14, differenceInMinutes as differenceInMinutes5, startOfDay as startOfDay8 } from "date-fns";
|
|
1848
2243
|
import { motion as motion2, AnimatePresence } from "framer-motion";
|
|
1849
2244
|
import {
|
|
1850
2245
|
Clock as Clock2,
|
|
@@ -1923,14 +2318,15 @@ var EventModal = ({
|
|
|
1923
2318
|
onDelete,
|
|
1924
2319
|
calendars,
|
|
1925
2320
|
translations: t,
|
|
1926
|
-
locale
|
|
2321
|
+
locale,
|
|
2322
|
+
initialAllDay
|
|
1927
2323
|
}) => {
|
|
1928
|
-
const [mode, setMode] =
|
|
1929
|
-
const translationsRef =
|
|
2324
|
+
const [mode, setMode] = useState5("create");
|
|
2325
|
+
const translationsRef = useRef5(t);
|
|
1930
2326
|
useInsertionEffect(() => {
|
|
1931
2327
|
translationsRef.current = t;
|
|
1932
2328
|
});
|
|
1933
|
-
const [formData, setFormData] =
|
|
2329
|
+
const [formData, setFormData] = useState5({
|
|
1934
2330
|
title: "",
|
|
1935
2331
|
description: "",
|
|
1936
2332
|
location: "",
|
|
@@ -1944,12 +2340,12 @@ var EventModal = ({
|
|
|
1944
2340
|
attachments: [],
|
|
1945
2341
|
reminders: []
|
|
1946
2342
|
});
|
|
1947
|
-
const [isCalendarDropdownOpen, setIsCalendarDropdownOpen] =
|
|
1948
|
-
const [isColorPickerOpen, setIsColorPickerOpen] =
|
|
1949
|
-
const [isReminderDropdownOpen, setIsReminderDropdownOpen] =
|
|
1950
|
-
const [guestInput, setGuestInput] =
|
|
1951
|
-
const [guestError, setGuestError] =
|
|
1952
|
-
|
|
2343
|
+
const [isCalendarDropdownOpen, setIsCalendarDropdownOpen] = useState5(false);
|
|
2344
|
+
const [isColorPickerOpen, setIsColorPickerOpen] = useState5(false);
|
|
2345
|
+
const [isReminderDropdownOpen, setIsReminderDropdownOpen] = useState5(false);
|
|
2346
|
+
const [guestInput, setGuestInput] = useState5("");
|
|
2347
|
+
const [guestError, setGuestError] = useState5(false);
|
|
2348
|
+
useEffect4(() => {
|
|
1953
2349
|
const defaultReminders = () => [{ id: "1", type: "notification", time: 30, label: reminderLabel(30, translationsRef.current) }];
|
|
1954
2350
|
if (isOpen) {
|
|
1955
2351
|
setGuestInput("");
|
|
@@ -1966,16 +2362,16 @@ var EventModal = ({
|
|
|
1966
2362
|
});
|
|
1967
2363
|
} else {
|
|
1968
2364
|
setMode("create");
|
|
1969
|
-
const
|
|
1970
|
-
const
|
|
1971
|
-
end
|
|
2365
|
+
const base = initialDate || /* @__PURE__ */ new Date();
|
|
2366
|
+
const start = initialAllDay ? startOfDay8(base) : base;
|
|
2367
|
+
const end = initialAllDay ? addDays8(start, 1) : new Date(base.getTime() + 60 * 60 * 1e3);
|
|
1972
2368
|
setFormData({
|
|
1973
2369
|
title: "",
|
|
1974
2370
|
description: "",
|
|
1975
2371
|
location: "",
|
|
1976
2372
|
start,
|
|
1977
2373
|
end,
|
|
1978
|
-
allDay:
|
|
2374
|
+
allDay: !!initialAllDay,
|
|
1979
2375
|
color: "#3b82f6",
|
|
1980
2376
|
calendarId: calendars?.[0]?.id,
|
|
1981
2377
|
attachments: [],
|
|
@@ -1984,7 +2380,7 @@ var EventModal = ({
|
|
|
1984
2380
|
});
|
|
1985
2381
|
}
|
|
1986
2382
|
}
|
|
1987
|
-
}, [isOpen, event, initialDate, calendars]);
|
|
2383
|
+
}, [isOpen, event, initialDate, calendars, initialAllDay]);
|
|
1988
2384
|
const guests = formData.guests || [];
|
|
1989
2385
|
const addGuests = (raw) => {
|
|
1990
2386
|
const entries = raw.split(/[\s,;]+/).filter(Boolean);
|
|
@@ -2031,9 +2427,38 @@ var EventModal = ({
|
|
|
2031
2427
|
};
|
|
2032
2428
|
const formatDateForInput = (date) => {
|
|
2033
2429
|
if (!date) return "";
|
|
2034
|
-
return
|
|
2430
|
+
return format14(date, "yyyy-MM-dd'T'HH:mm");
|
|
2431
|
+
};
|
|
2432
|
+
const allDaySpan = formData.allDay && formData.start && formData.end ? dayEventSpan({ ...formData, allDay: true }) : null;
|
|
2433
|
+
const handleAllDayToggle = () => {
|
|
2434
|
+
if (!formData.start || !formData.end) return;
|
|
2435
|
+
if (!formData.allDay) {
|
|
2436
|
+
const firstDay = startOfDay8(formData.start);
|
|
2437
|
+
const lastDay = startOfDay8(new Date(Math.max(formData.end.getTime() - 1, formData.start.getTime())));
|
|
2438
|
+
setFormData((prev) => ({ ...prev, allDay: true, start: firstDay, end: addDays8(lastDay, 1) }));
|
|
2439
|
+
} else {
|
|
2440
|
+
const start = new Date(formData.start);
|
|
2441
|
+
start.setHours(9, 0, 0, 0);
|
|
2442
|
+
setFormData((prev) => ({ ...prev, allDay: false, start, end: new Date(start.getTime() + 60 * 60 * 1e3) }));
|
|
2443
|
+
}
|
|
2444
|
+
};
|
|
2445
|
+
const handleAllDayDateChange = (field, value) => {
|
|
2446
|
+
const [y, m, d] = value.split("-").map(Number);
|
|
2447
|
+
if (!y || !m || !d || !allDaySpan) return;
|
|
2448
|
+
const day = new Date(y, m - 1, d);
|
|
2449
|
+
if (field === "start") {
|
|
2450
|
+
const days = differenceInCalendarDays4(allDaySpan.lastDay, allDaySpan.firstDay);
|
|
2451
|
+
setFormData((prev) => ({ ...prev, start: day, end: addDays8(day, days + 1) }));
|
|
2452
|
+
} else {
|
|
2453
|
+
const firstDay = day < allDaySpan.firstDay ? day : allDaySpan.firstDay;
|
|
2454
|
+
setFormData((prev) => ({ ...prev, start: firstDay, end: addDays8(day, 1) }));
|
|
2455
|
+
}
|
|
2035
2456
|
};
|
|
2036
2457
|
const handleDateChange = (field, value) => {
|
|
2458
|
+
if (formData.allDay) {
|
|
2459
|
+
handleAllDayDateChange(field, value);
|
|
2460
|
+
return;
|
|
2461
|
+
}
|
|
2037
2462
|
const date = new Date(value);
|
|
2038
2463
|
if (isNaN(date.getTime())) return;
|
|
2039
2464
|
if (field === "start") {
|
|
@@ -2072,6 +2497,10 @@ var EventModal = ({
|
|
|
2072
2497
|
};
|
|
2073
2498
|
const getDurationText = () => {
|
|
2074
2499
|
if (!formData.start || !formData.end) return "";
|
|
2500
|
+
if (allDaySpan) {
|
|
2501
|
+
const days = differenceInCalendarDays4(allDaySpan.lastDay, allDaySpan.firstDay) + 1;
|
|
2502
|
+
return days === 1 ? t.durationDay : interpolate(t.durationDays, { n: days });
|
|
2503
|
+
}
|
|
2075
2504
|
const mins = differenceInMinutes5(formData.end, formData.start);
|
|
2076
2505
|
if (mins < 60) return interpolate(t.durationMinutes, { n: mins });
|
|
2077
2506
|
const hours = Math.floor(mins / 60);
|
|
@@ -2080,12 +2509,14 @@ var EventModal = ({
|
|
|
2080
2509
|
return interpolate(t.durationHoursMinutes, { h: hours, m: remainingMins });
|
|
2081
2510
|
};
|
|
2082
2511
|
const { time: timeFormat } = timeFormats(locale);
|
|
2512
|
+
const viewEvent = event && { ...event, start: new Date(event.start), end: new Date(event.end) };
|
|
2513
|
+
const viewSpan = viewEvent && isDayEvent(viewEvent) ? dayEventSpan(viewEvent) : null;
|
|
2083
2514
|
const renderAttachment = (att) => {
|
|
2084
|
-
const content = /* @__PURE__ */
|
|
2515
|
+
const content = /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("div", { className: "p-2 bg-primary/10 rounded-lg" }, /* @__PURE__ */ React17.createElement(File, { className: "w-4 h-4 text-primary" })), /* @__PURE__ */ React17.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React17.createElement("p", { className: "text-sm font-medium text-foreground truncate" }, att.name), /* @__PURE__ */ React17.createElement("p", { className: "text-xs text-muted-foreground" }, att.size)), att.url && /* @__PURE__ */ React17.createElement(Download, { className: "w-4 h-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" }));
|
|
2085
2516
|
const className = "flex items-center gap-3 p-3 rounded-xl border border-border/30 bg-muted/20 transition-all group";
|
|
2086
|
-
return att.url && isSafeUrl(att.url) ? /* @__PURE__ */
|
|
2517
|
+
return att.url && isSafeUrl(att.url) ? /* @__PURE__ */ React17.createElement("a", { key: att.id, href: att.url, target: "_blank", rel: "noopener noreferrer", download: att.name, className: cn(className, "hover:bg-muted/40 cursor-pointer") }, content) : /* @__PURE__ */ React17.createElement("div", { key: att.id, className }, content);
|
|
2087
2518
|
};
|
|
2088
|
-
const renderViewMode = () => /* @__PURE__ */
|
|
2519
|
+
const renderViewMode = () => /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col bg-background overflow-hidden w-full max-h-[90vh]" }, /* @__PURE__ */ React17.createElement(
|
|
2089
2520
|
"div",
|
|
2090
2521
|
{
|
|
2091
2522
|
className: "relative px-6 pt-6 pb-8",
|
|
@@ -2093,13 +2524,13 @@ var EventModal = ({
|
|
|
2093
2524
|
background: `linear-gradient(135deg, ${event?.color || "#3b82f6"}15 0%, transparent 100%)`
|
|
2094
2525
|
}
|
|
2095
2526
|
},
|
|
2096
|
-
/* @__PURE__ */
|
|
2527
|
+
/* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between mb-6" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React17.createElement(
|
|
2097
2528
|
"div",
|
|
2098
2529
|
{
|
|
2099
2530
|
className: "w-3 h-3 rounded-full",
|
|
2100
2531
|
style: { backgroundColor: event?.color || "#3b82f6" }
|
|
2101
2532
|
}
|
|
2102
|
-
), /* @__PURE__ */
|
|
2533
|
+
), /* @__PURE__ */ React17.createElement("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider" }, calendars?.find((c) => c.id === event?.calendarId)?.label || t.event)), /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React17.createElement(
|
|
2103
2534
|
"button",
|
|
2104
2535
|
{
|
|
2105
2536
|
onClick: () => setMode("edit"),
|
|
@@ -2107,8 +2538,8 @@ var EventModal = ({
|
|
|
2107
2538
|
title: t.edit,
|
|
2108
2539
|
"aria-label": t.edit
|
|
2109
2540
|
},
|
|
2110
|
-
/* @__PURE__ */
|
|
2111
|
-
), /* @__PURE__ */
|
|
2541
|
+
/* @__PURE__ */ React17.createElement(Edit2, { className: "w-4 h-4" })
|
|
2542
|
+
), /* @__PURE__ */ React17.createElement(
|
|
2112
2543
|
"button",
|
|
2113
2544
|
{
|
|
2114
2545
|
onClick: handleDelete,
|
|
@@ -2116,8 +2547,8 @@ var EventModal = ({
|
|
|
2116
2547
|
title: t.delete,
|
|
2117
2548
|
"aria-label": t.delete
|
|
2118
2549
|
},
|
|
2119
|
-
/* @__PURE__ */
|
|
2120
|
-
), /* @__PURE__ */
|
|
2550
|
+
/* @__PURE__ */ React17.createElement(Trash2, { className: "w-4 h-4" })
|
|
2551
|
+
), /* @__PURE__ */ React17.createElement(
|
|
2121
2552
|
"button",
|
|
2122
2553
|
{
|
|
2123
2554
|
onClick: onClose,
|
|
@@ -2125,11 +2556,11 @@ var EventModal = ({
|
|
|
2125
2556
|
title: t.close,
|
|
2126
2557
|
"aria-label": t.close
|
|
2127
2558
|
},
|
|
2128
|
-
/* @__PURE__ */
|
|
2559
|
+
/* @__PURE__ */ React17.createElement(X2, { className: "w-4 h-4" })
|
|
2129
2560
|
))),
|
|
2130
|
-
/* @__PURE__ */
|
|
2131
|
-
/* @__PURE__ */
|
|
2132
|
-
), /* @__PURE__ */
|
|
2561
|
+
/* @__PURE__ */ React17.createElement("h1", { className: "text-2xl font-bold text-foreground mb-3 leading-tight" }, event?.title || t.noTitle),
|
|
2562
|
+
/* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-3 text-sm" }, /* @__PURE__ */ React17.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__ */ React17.createElement(Calendar2, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React17.createElement("span", { className: "font-medium" }, viewSpan && viewSpan.lastDay > viewSpan.firstDay ? `${format14(viewSpan.firstDay, "EEE d MMM", { locale })} \u2013 ${format14(viewSpan.lastDay, "EEE d MMM", { locale })}` : event?.start && format14(new Date(event.start), "EEE, MMM d", { locale }))), event?.allDay ? /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2 px-3 py-1.5 bg-primary/10 rounded-lg border border-primary/20" }, /* @__PURE__ */ React17.createElement("span", { className: "font-medium text-primary" }, t.allDay)) : /* @__PURE__ */ React17.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__ */ React17.createElement(Clock2, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React17.createElement("span", { className: "font-medium" }, event?.start && format14(new Date(event.start), timeFormat, { locale }), " \u2013 ", event?.end && format14(new Date(event.end), timeFormat, { locale }))))
|
|
2563
|
+
), /* @__PURE__ */ React17.createElement("div", { className: "px-6 pb-6 space-y-4 overflow-y-auto flex-1" }, event?.location && /* @__PURE__ */ React17.createElement(
|
|
2133
2564
|
motion2.a,
|
|
2134
2565
|
{
|
|
2135
2566
|
href: mapsUrl(event.location),
|
|
@@ -2139,10 +2570,10 @@ var EventModal = ({
|
|
|
2139
2570
|
animate: { opacity: 1, y: 0 },
|
|
2140
2571
|
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"
|
|
2141
2572
|
},
|
|
2142
|
-
/* @__PURE__ */
|
|
2143
|
-
/* @__PURE__ */
|
|
2144
|
-
/* @__PURE__ */
|
|
2145
|
-
), event?.guests && event.guests.length > 0 && /* @__PURE__ */
|
|
2573
|
+
/* @__PURE__ */ React17.createElement("div", { className: "p-2 bg-primary/10 rounded-xl" }, /* @__PURE__ */ React17.createElement(MapPin, { className: "w-5 h-5 text-primary" })),
|
|
2574
|
+
/* @__PURE__ */ React17.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React17.createElement("p", { className: "text-sm font-medium text-foreground" }, event.location), /* @__PURE__ */ React17.createElement("p", { className: "text-xs text-muted-foreground mt-0.5" }, t.openInMaps)),
|
|
2575
|
+
/* @__PURE__ */ React17.createElement(ExternalLink, { className: "w-4 h-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" })
|
|
2576
|
+
), event?.guests && event.guests.length > 0 && /* @__PURE__ */ React17.createElement(
|
|
2146
2577
|
motion2.div,
|
|
2147
2578
|
{
|
|
2148
2579
|
initial: { opacity: 0, y: 10 },
|
|
@@ -2150,14 +2581,14 @@ var EventModal = ({
|
|
|
2150
2581
|
transition: { delay: 0.05 },
|
|
2151
2582
|
className: "space-y-3"
|
|
2152
2583
|
},
|
|
2153
|
-
/* @__PURE__ */
|
|
2154
|
-
/* @__PURE__ */
|
|
2584
|
+
/* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React17.createElement(Users2, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React17.createElement("span", { className: "text-sm font-medium text-foreground" }, event.guests.length, " ", event.guests.length > 1 ? t.guests : t.guestSingular))),
|
|
2585
|
+
/* @__PURE__ */ React17.createElement("div", { className: "flex flex-wrap gap-2" }, event.guests.map((email) => /* @__PURE__ */ React17.createElement(
|
|
2155
2586
|
"div",
|
|
2156
2587
|
{
|
|
2157
2588
|
key: email,
|
|
2158
2589
|
className: "flex items-center gap-2 px-3 py-2 rounded-xl bg-muted/30 border border-border/30"
|
|
2159
2590
|
},
|
|
2160
|
-
/* @__PURE__ */
|
|
2591
|
+
/* @__PURE__ */ React17.createElement(
|
|
2161
2592
|
"div",
|
|
2162
2593
|
{
|
|
2163
2594
|
className: "w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold text-white",
|
|
@@ -2165,9 +2596,9 @@ var EventModal = ({
|
|
|
2165
2596
|
},
|
|
2166
2597
|
email[0].toUpperCase()
|
|
2167
2598
|
),
|
|
2168
|
-
/* @__PURE__ */
|
|
2599
|
+
/* @__PURE__ */ React17.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React17.createElement("p", { className: "text-sm font-medium text-foreground" }, email.split("@")[0]), /* @__PURE__ */ React17.createElement("p", { className: "text-xs text-muted-foreground truncate" }, email))
|
|
2169
2600
|
)))
|
|
2170
|
-
), event?.reminders && event.reminders.length > 0 && /* @__PURE__ */
|
|
2601
|
+
), event?.reminders && event.reminders.length > 0 && /* @__PURE__ */ React17.createElement(
|
|
2171
2602
|
motion2.div,
|
|
2172
2603
|
{
|
|
2173
2604
|
initial: { opacity: 0, y: 10 },
|
|
@@ -2175,8 +2606,8 @@ var EventModal = ({
|
|
|
2175
2606
|
transition: { delay: 0.1 },
|
|
2176
2607
|
className: "flex items-center gap-3"
|
|
2177
2608
|
},
|
|
2178
|
-
/* @__PURE__ */
|
|
2179
|
-
/* @__PURE__ */
|
|
2609
|
+
/* @__PURE__ */ React17.createElement("div", { className: "p-2 bg-amber-500/10 rounded-xl" }, /* @__PURE__ */ React17.createElement(Bell2, { className: "w-4 h-4 text-amber-500" })),
|
|
2610
|
+
/* @__PURE__ */ React17.createElement("div", { className: "flex flex-wrap gap-2" }, event.reminders.map((reminder) => /* @__PURE__ */ React17.createElement(
|
|
2180
2611
|
"span",
|
|
2181
2612
|
{
|
|
2182
2613
|
key: reminder.id,
|
|
@@ -2184,7 +2615,7 @@ var EventModal = ({
|
|
|
2184
2615
|
},
|
|
2185
2616
|
reminder.label || reminderLabel(reminder.time, t)
|
|
2186
2617
|
)))
|
|
2187
|
-
), event?.description && /* @__PURE__ */
|
|
2618
|
+
), event?.description && /* @__PURE__ */ React17.createElement(
|
|
2188
2619
|
motion2.div,
|
|
2189
2620
|
{
|
|
2190
2621
|
initial: { opacity: 0, y: 10 },
|
|
@@ -2192,9 +2623,9 @@ var EventModal = ({
|
|
|
2192
2623
|
transition: { delay: 0.15 },
|
|
2193
2624
|
className: "space-y-2"
|
|
2194
2625
|
},
|
|
2195
|
-
/* @__PURE__ */
|
|
2196
|
-
/* @__PURE__ */
|
|
2197
|
-
), event?.attachments && event.attachments.length > 0 && /* @__PURE__ */
|
|
2626
|
+
/* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React17.createElement(AlignLeft, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React17.createElement("span", { className: "text-sm font-medium text-foreground" }, t.notesLabel)),
|
|
2627
|
+
/* @__PURE__ */ React17.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)
|
|
2628
|
+
), event?.attachments && event.attachments.length > 0 && /* @__PURE__ */ React17.createElement(
|
|
2198
2629
|
motion2.div,
|
|
2199
2630
|
{
|
|
2200
2631
|
initial: { opacity: 0, y: 10 },
|
|
@@ -2202,10 +2633,10 @@ var EventModal = ({
|
|
|
2202
2633
|
transition: { delay: 0.2 },
|
|
2203
2634
|
className: "space-y-2"
|
|
2204
2635
|
},
|
|
2205
|
-
/* @__PURE__ */
|
|
2206
|
-
/* @__PURE__ */
|
|
2636
|
+
/* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React17.createElement(Paperclip2, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React17.createElement("span", { className: "text-sm font-medium text-foreground" }, t.attachments)),
|
|
2637
|
+
/* @__PURE__ */ React17.createElement("div", { className: "grid gap-2" }, event.attachments.map(renderAttachment))
|
|
2207
2638
|
)));
|
|
2208
|
-
const renderEditMode = () => /* @__PURE__ */
|
|
2639
|
+
const renderEditMode = () => /* @__PURE__ */ React17.createElement("form", { onSubmit: handleSubmit, className: "flex flex-col bg-background overflow-hidden w-full max-h-[85vh]" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between px-5 py-4 border-b border-border/50 shrink-0" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React17.createElement(
|
|
2209
2640
|
"button",
|
|
2210
2641
|
{
|
|
2211
2642
|
type: "button",
|
|
@@ -2213,7 +2644,7 @@ var EventModal = ({
|
|
|
2213
2644
|
className: "relative p-1",
|
|
2214
2645
|
"aria-label": t.eventColor
|
|
2215
2646
|
},
|
|
2216
|
-
/* @__PURE__ */
|
|
2647
|
+
/* @__PURE__ */ React17.createElement(
|
|
2217
2648
|
"div",
|
|
2218
2649
|
{
|
|
2219
2650
|
className: "w-5 h-5 rounded-full cursor-pointer hover:scale-110 transition-transform",
|
|
@@ -2223,7 +2654,7 @@ var EventModal = ({
|
|
|
2223
2654
|
}
|
|
2224
2655
|
}
|
|
2225
2656
|
),
|
|
2226
|
-
isColorPickerOpen && /* @__PURE__ */
|
|
2657
|
+
isColorPickerOpen && /* @__PURE__ */ React17.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__ */ React17.createElement(
|
|
2227
2658
|
"button",
|
|
2228
2659
|
{
|
|
2229
2660
|
key: color,
|
|
@@ -2240,7 +2671,7 @@ var EventModal = ({
|
|
|
2240
2671
|
style: { backgroundColor: color, color }
|
|
2241
2672
|
}
|
|
2242
2673
|
)))
|
|
2243
|
-
), /* @__PURE__ */
|
|
2674
|
+
), /* @__PURE__ */ React17.createElement("h2", { className: "text-lg font-semibold text-foreground" }, mode === "edit" ? t.editEvent : t.newEvent)), /* @__PURE__ */ React17.createElement(
|
|
2244
2675
|
"button",
|
|
2245
2676
|
{
|
|
2246
2677
|
type: "button",
|
|
@@ -2248,8 +2679,8 @@ var EventModal = ({
|
|
|
2248
2679
|
className: "p-2 hover:bg-accent rounded-xl transition-all text-muted-foreground hover:text-foreground",
|
|
2249
2680
|
"aria-label": t.close
|
|
2250
2681
|
},
|
|
2251
|
-
/* @__PURE__ */
|
|
2252
|
-
)), /* @__PURE__ */
|
|
2682
|
+
/* @__PURE__ */ React17.createElement(X2, { className: "w-4 h-4" })
|
|
2683
|
+
)), /* @__PURE__ */ React17.createElement("div", { className: "flex-1 overflow-y-auto" }, /* @__PURE__ */ React17.createElement("div", { className: "px-5 py-4 space-y-5" }, /* @__PURE__ */ React17.createElement("div", null, /* @__PURE__ */ React17.createElement(
|
|
2253
2684
|
"input",
|
|
2254
2685
|
{
|
|
2255
2686
|
type: "text",
|
|
@@ -2261,34 +2692,56 @@ var EventModal = ({
|
|
|
2261
2692
|
placeholder: t.title,
|
|
2262
2693
|
"aria-label": t.title
|
|
2263
2694
|
}
|
|
2264
|
-
)), /* @__PURE__ */
|
|
2695
|
+
)), /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between px-1" }, /* @__PURE__ */ React17.createElement("span", { id: "calendarkit-all-day-label", className: "text-sm font-medium text-foreground" }, t.allDay), /* @__PURE__ */ React17.createElement(
|
|
2696
|
+
"button",
|
|
2697
|
+
{
|
|
2698
|
+
type: "button",
|
|
2699
|
+
role: "switch",
|
|
2700
|
+
"aria-checked": !!formData.allDay,
|
|
2701
|
+
"aria-labelledby": "calendarkit-all-day-label",
|
|
2702
|
+
onClick: handleAllDayToggle,
|
|
2703
|
+
className: cn(
|
|
2704
|
+
"relative inline-flex h-6 w-11 shrink-0 rounded-full border-2 border-transparent transition-colors cursor-pointer",
|
|
2705
|
+
formData.allDay ? "bg-primary" : "bg-muted"
|
|
2706
|
+
)
|
|
2707
|
+
},
|
|
2708
|
+
/* @__PURE__ */ React17.createElement(
|
|
2709
|
+
"span",
|
|
2710
|
+
{
|
|
2711
|
+
className: cn(
|
|
2712
|
+
"pointer-events-none inline-block h-5 w-5 rounded-full bg-background shadow transition-transform",
|
|
2713
|
+
formData.allDay ? "translate-x-5" : "translate-x-0"
|
|
2714
|
+
)
|
|
2715
|
+
}
|
|
2716
|
+
)
|
|
2717
|
+
)), /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-3 p-4 rounded-2xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ React17.createElement("div", { className: "p-2 bg-primary/10 rounded-xl shrink-0" }, /* @__PURE__ */ React17.createElement(Clock2, { className: "w-5 h-5 text-primary" })), /* @__PURE__ */ React17.createElement("div", { className: "flex-1 grid grid-cols-2 gap-3" }, /* @__PURE__ */ React17.createElement("div", null, /* @__PURE__ */ React17.createElement("label", { htmlFor: "calendarkit-event-start", className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider mb-1 block" }, t.start), /* @__PURE__ */ React17.createElement(
|
|
2265
2718
|
"input",
|
|
2266
2719
|
{
|
|
2267
2720
|
id: "calendarkit-event-start",
|
|
2268
|
-
type: "datetime-local",
|
|
2721
|
+
type: allDaySpan ? "date" : "datetime-local",
|
|
2269
2722
|
className: "w-full bg-background border border-border/50 rounded-xl px-3 py-2 text-sm font-medium text-foreground focus:border-primary focus:ring-2 focus:ring-primary/20 transition-all",
|
|
2270
|
-
value: formatDateForInput(formData.start),
|
|
2723
|
+
value: allDaySpan ? format14(allDaySpan.firstDay, "yyyy-MM-dd") : formatDateForInput(formData.start),
|
|
2271
2724
|
onChange: (e) => handleDateChange("start", e.target.value)
|
|
2272
2725
|
}
|
|
2273
|
-
)), /* @__PURE__ */
|
|
2726
|
+
)), /* @__PURE__ */ React17.createElement("div", null, /* @__PURE__ */ React17.createElement("label", { htmlFor: "calendarkit-event-end", className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider mb-1 block" }, t.end), /* @__PURE__ */ React17.createElement(
|
|
2274
2727
|
"input",
|
|
2275
2728
|
{
|
|
2276
2729
|
id: "calendarkit-event-end",
|
|
2277
|
-
type: "datetime-local",
|
|
2730
|
+
type: allDaySpan ? "date" : "datetime-local",
|
|
2278
2731
|
className: "w-full bg-background border border-border/50 rounded-xl px-3 py-2 text-sm font-medium text-foreground focus:border-primary focus:ring-2 focus:ring-primary/20 transition-all",
|
|
2279
|
-
value: formatDateForInput(formData.end),
|
|
2732
|
+
value: allDaySpan ? format14(allDaySpan.lastDay, "yyyy-MM-dd") : formatDateForInput(formData.end),
|
|
2280
2733
|
onChange: (e) => handleDateChange("end", e.target.value)
|
|
2281
2734
|
}
|
|
2282
|
-
)))), getDurationText() && /* @__PURE__ */
|
|
2735
|
+
)))), getDurationText() && /* @__PURE__ */ React17.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React17.createElement("span", { className: "text-xs font-medium px-3 py-1 rounded-full bg-primary/10 text-primary" }, getDurationText())), /* @__PURE__ */ React17.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React17.createElement(Bell2, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React17.createElement("span", { className: "text-sm font-medium text-foreground" }, t.reminders)), /* @__PURE__ */ React17.createElement("div", { className: "relative" }, /* @__PURE__ */ React17.createElement(
|
|
2283
2736
|
"button",
|
|
2284
2737
|
{
|
|
2285
2738
|
type: "button",
|
|
2286
2739
|
onClick: () => setIsReminderDropdownOpen(!isReminderDropdownOpen),
|
|
2287
2740
|
className: "flex items-center gap-1 text-xs font-medium text-primary hover:text-primary/80 transition-colors"
|
|
2288
2741
|
},
|
|
2289
|
-
/* @__PURE__ */
|
|
2742
|
+
/* @__PURE__ */ React17.createElement(Plus3, { className: "w-3.5 h-3.5" }),
|
|
2290
2743
|
t.add
|
|
2291
|
-
), isReminderDropdownOpen && /* @__PURE__ */
|
|
2744
|
+
), isReminderDropdownOpen && /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsReminderDropdownOpen(false) }), /* @__PURE__ */ React17.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((minutes) => /* @__PURE__ */ React17.createElement(
|
|
2292
2745
|
"button",
|
|
2293
2746
|
{
|
|
2294
2747
|
key: minutes,
|
|
@@ -2297,15 +2750,15 @@ var EventModal = ({
|
|
|
2297
2750
|
className: "w-full px-3 py-2 text-left text-sm hover:bg-accent transition-colors"
|
|
2298
2751
|
},
|
|
2299
2752
|
reminderLabel(minutes, t)
|
|
2300
|
-
)))))), formData.reminders && formData.reminders.length > 0 && /* @__PURE__ */
|
|
2753
|
+
)))))), formData.reminders && formData.reminders.length > 0 && /* @__PURE__ */ React17.createElement("div", { className: "flex flex-wrap gap-2" }, formData.reminders.map((reminder) => /* @__PURE__ */ React17.createElement(
|
|
2301
2754
|
"div",
|
|
2302
2755
|
{
|
|
2303
2756
|
key: reminder.id,
|
|
2304
2757
|
className: "flex items-center gap-2 px-3 py-1.5 rounded-full bg-amber-500/10 border border-amber-500/20"
|
|
2305
2758
|
},
|
|
2306
|
-
/* @__PURE__ */
|
|
2307
|
-
/* @__PURE__ */
|
|
2308
|
-
/* @__PURE__ */
|
|
2759
|
+
/* @__PURE__ */ React17.createElement(BellRing, { className: "w-3.5 h-3.5 text-amber-500" }),
|
|
2760
|
+
/* @__PURE__ */ React17.createElement("span", { className: "text-xs font-medium text-amber-600 dark:text-amber-400" }, reminder.label || reminderLabel(reminder.time, t)),
|
|
2761
|
+
/* @__PURE__ */ React17.createElement(
|
|
2309
2762
|
"button",
|
|
2310
2763
|
{
|
|
2311
2764
|
type: "button",
|
|
@@ -2313,9 +2766,9 @@ var EventModal = ({
|
|
|
2313
2766
|
className: "p-0.5 hover:bg-amber-500/20 rounded-full transition-colors",
|
|
2314
2767
|
"aria-label": t.removeReminder
|
|
2315
2768
|
},
|
|
2316
|
-
/* @__PURE__ */
|
|
2769
|
+
/* @__PURE__ */ React17.createElement(X2, { className: "w-3 h-3 text-amber-500" })
|
|
2317
2770
|
)
|
|
2318
|
-
)))), /* @__PURE__ */
|
|
2771
|
+
)))), /* @__PURE__ */ React17.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React17.createElement(Users2, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React17.createElement("label", { htmlFor: "calendarkit-event-guest", className: "text-sm font-medium text-foreground" }, t.guests)), /* @__PURE__ */ React17.createElement(
|
|
2319
2772
|
"input",
|
|
2320
2773
|
{
|
|
2321
2774
|
id: "calendarkit-event-guest",
|
|
@@ -2341,13 +2794,13 @@ var EventModal = ({
|
|
|
2341
2794
|
guestError ? "border-destructive" : "border-border/30"
|
|
2342
2795
|
)
|
|
2343
2796
|
}
|
|
2344
|
-
), guestError && /* @__PURE__ */
|
|
2797
|
+
), guestError && /* @__PURE__ */ React17.createElement("p", { role: "alert", className: "text-xs text-destructive" }, t.invalidEmail), guests.length > 0 && /* @__PURE__ */ React17.createElement("div", { className: "flex flex-wrap gap-2 mt-2" }, guests.map((email) => /* @__PURE__ */ React17.createElement(
|
|
2345
2798
|
"div",
|
|
2346
2799
|
{
|
|
2347
2800
|
key: email,
|
|
2348
2801
|
className: "flex items-center gap-2 pl-1 pr-2 py-1 bg-muted/30 border border-border/30 rounded-full"
|
|
2349
2802
|
},
|
|
2350
|
-
/* @__PURE__ */
|
|
2803
|
+
/* @__PURE__ */ React17.createElement(
|
|
2351
2804
|
"div",
|
|
2352
2805
|
{
|
|
2353
2806
|
className: "w-6 h-6 rounded-full flex items-center justify-center text-xs font-semibold text-white",
|
|
@@ -2355,8 +2808,8 @@ var EventModal = ({
|
|
|
2355
2808
|
},
|
|
2356
2809
|
email[0].toUpperCase()
|
|
2357
2810
|
),
|
|
2358
|
-
/* @__PURE__ */
|
|
2359
|
-
/* @__PURE__ */
|
|
2811
|
+
/* @__PURE__ */ React17.createElement("span", { className: "text-xs font-medium text-foreground" }, email),
|
|
2812
|
+
/* @__PURE__ */ React17.createElement(
|
|
2360
2813
|
"button",
|
|
2361
2814
|
{
|
|
2362
2815
|
type: "button",
|
|
@@ -2364,9 +2817,9 @@ var EventModal = ({
|
|
|
2364
2817
|
className: "p-0.5 hover:bg-destructive/10 rounded-full transition-colors",
|
|
2365
2818
|
"aria-label": interpolate(t.removeGuest, { email })
|
|
2366
2819
|
},
|
|
2367
|
-
/* @__PURE__ */
|
|
2820
|
+
/* @__PURE__ */ React17.createElement(X2, { className: "w-3 h-3 text-muted-foreground" })
|
|
2368
2821
|
)
|
|
2369
|
-
)))), /* @__PURE__ */
|
|
2822
|
+
)))), /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-3 p-3 rounded-xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ React17.createElement(MapPin, { className: "w-5 h-5 text-muted-foreground shrink-0" }), /* @__PURE__ */ React17.createElement(
|
|
2370
2823
|
"input",
|
|
2371
2824
|
{
|
|
2372
2825
|
type: "text",
|
|
@@ -2376,7 +2829,7 @@ var EventModal = ({
|
|
|
2376
2829
|
value: formData.location || "",
|
|
2377
2830
|
onChange: (e) => setFormData({ ...formData, location: e.target.value })
|
|
2378
2831
|
}
|
|
2379
|
-
)), /* @__PURE__ */
|
|
2832
|
+
)), /* @__PURE__ */ React17.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React17.createElement(AlignLeft, { className: "w-4 h-4 text-muted-foreground" }), /* @__PURE__ */ React17.createElement("span", { className: "text-sm font-medium text-foreground" }, t.notesLabel)), /* @__PURE__ */ React17.createElement(
|
|
2380
2833
|
"textarea",
|
|
2381
2834
|
{
|
|
2382
2835
|
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",
|
|
@@ -2385,7 +2838,7 @@ var EventModal = ({
|
|
|
2385
2838
|
value: formData.description || "",
|
|
2386
2839
|
onChange: (e) => setFormData({ ...formData, description: e.target.value })
|
|
2387
2840
|
}
|
|
2388
|
-
)), /* @__PURE__ */
|
|
2841
|
+
)), /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-3 p-3 rounded-xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ React17.createElement(Repeat, { className: "w-5 h-5 text-muted-foreground shrink-0" }), /* @__PURE__ */ React17.createElement(
|
|
2389
2842
|
"select",
|
|
2390
2843
|
{
|
|
2391
2844
|
className: "flex-1 bg-transparent text-sm text-foreground focus:outline-none cursor-pointer",
|
|
@@ -2405,28 +2858,28 @@ var EventModal = ({
|
|
|
2405
2858
|
}
|
|
2406
2859
|
}
|
|
2407
2860
|
},
|
|
2408
|
-
/* @__PURE__ */
|
|
2409
|
-
/* @__PURE__ */
|
|
2410
|
-
/* @__PURE__ */
|
|
2411
|
-
/* @__PURE__ */
|
|
2412
|
-
/* @__PURE__ */
|
|
2413
|
-
)), calendars && calendars.length > 0 && /* @__PURE__ */
|
|
2861
|
+
/* @__PURE__ */ React17.createElement("option", { value: "" }, t.doesNotRepeat),
|
|
2862
|
+
/* @__PURE__ */ React17.createElement("option", { value: "DAILY" }, t.daily),
|
|
2863
|
+
/* @__PURE__ */ React17.createElement("option", { value: "WEEKLY" }, t.weekly),
|
|
2864
|
+
/* @__PURE__ */ React17.createElement("option", { value: "MONTHLY" }, t.monthly),
|
|
2865
|
+
/* @__PURE__ */ React17.createElement("option", { value: "YEARLY" }, t.yearly)
|
|
2866
|
+
)), calendars && calendars.length > 0 && /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between p-3 rounded-xl bg-muted/20 border border-border/30" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React17.createElement(Tag, { className: "w-5 h-5 text-muted-foreground" }), /* @__PURE__ */ React17.createElement("span", { className: "text-sm text-foreground" }, t.calendar)), /* @__PURE__ */ React17.createElement("div", { className: "relative" }, /* @__PURE__ */ React17.createElement(
|
|
2414
2867
|
"button",
|
|
2415
2868
|
{
|
|
2416
2869
|
type: "button",
|
|
2417
2870
|
onClick: () => setIsCalendarDropdownOpen(!isCalendarDropdownOpen),
|
|
2418
2871
|
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"
|
|
2419
2872
|
},
|
|
2420
|
-
/* @__PURE__ */
|
|
2873
|
+
/* @__PURE__ */ React17.createElement(
|
|
2421
2874
|
"div",
|
|
2422
2875
|
{
|
|
2423
2876
|
className: "w-3 h-3 rounded-full",
|
|
2424
2877
|
style: { backgroundColor: calendars.find((c) => c.id === formData.calendarId)?.color || "#3b82f6" }
|
|
2425
2878
|
}
|
|
2426
2879
|
),
|
|
2427
|
-
/* @__PURE__ */
|
|
2428
|
-
/* @__PURE__ */
|
|
2429
|
-
), isCalendarDropdownOpen && /* @__PURE__ */
|
|
2880
|
+
/* @__PURE__ */ React17.createElement("span", { className: "font-medium" }, calendars.find((c) => c.id === formData.calendarId)?.label || t.select),
|
|
2881
|
+
/* @__PURE__ */ React17.createElement(ChevronDown2, { className: "w-3.5 h-3.5 text-muted-foreground" })
|
|
2882
|
+
), isCalendarDropdownOpen && /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsCalendarDropdownOpen(false) }), /* @__PURE__ */ React17.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__ */ React17.createElement(
|
|
2430
2883
|
"button",
|
|
2431
2884
|
{
|
|
2432
2885
|
key: cal.id,
|
|
@@ -2441,19 +2894,19 @@ var EventModal = ({
|
|
|
2441
2894
|
setIsCalendarDropdownOpen(false);
|
|
2442
2895
|
}
|
|
2443
2896
|
},
|
|
2444
|
-
/* @__PURE__ */
|
|
2445
|
-
/* @__PURE__ */
|
|
2446
|
-
formData.calendarId === cal.id && /* @__PURE__ */
|
|
2447
|
-
)))))))), /* @__PURE__ */
|
|
2897
|
+
/* @__PURE__ */ React17.createElement("div", { className: "w-3 h-3 rounded-full", style: { backgroundColor: cal.color } }),
|
|
2898
|
+
/* @__PURE__ */ React17.createElement("span", { className: "flex-1 text-sm" }, cal.label),
|
|
2899
|
+
formData.calendarId === cal.id && /* @__PURE__ */ React17.createElement(Check, { className: "w-4 h-4 text-primary" })
|
|
2900
|
+
)))))))), /* @__PURE__ */ React17.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__ */ React17.createElement(
|
|
2448
2901
|
"button",
|
|
2449
2902
|
{
|
|
2450
2903
|
type: "button",
|
|
2451
2904
|
onClick: handleDelete,
|
|
2452
2905
|
className: "flex items-center gap-2 px-4 py-2 text-destructive hover:bg-destructive/10 rounded-xl transition-all text-sm font-medium"
|
|
2453
2906
|
},
|
|
2454
|
-
/* @__PURE__ */
|
|
2907
|
+
/* @__PURE__ */ React17.createElement(Trash2, { className: "w-4 h-4" }),
|
|
2455
2908
|
t.delete
|
|
2456
|
-
), mode === "create" && /* @__PURE__ */
|
|
2909
|
+
), mode === "create" && /* @__PURE__ */ React17.createElement("div", null), /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React17.createElement(
|
|
2457
2910
|
"button",
|
|
2458
2911
|
{
|
|
2459
2912
|
type: "button",
|
|
@@ -2461,7 +2914,7 @@ var EventModal = ({
|
|
|
2461
2914
|
className: "px-4 py-2.5 text-muted-foreground hover:text-foreground font-medium text-sm rounded-xl transition-all hover:bg-accent"
|
|
2462
2915
|
},
|
|
2463
2916
|
t.cancel
|
|
2464
|
-
), /* @__PURE__ */
|
|
2917
|
+
), /* @__PURE__ */ React17.createElement(
|
|
2465
2918
|
"button",
|
|
2466
2919
|
{
|
|
2467
2920
|
type: "submit",
|
|
@@ -2469,7 +2922,7 @@ var EventModal = ({
|
|
|
2469
2922
|
},
|
|
2470
2923
|
mode === "edit" ? t.saveChanges : t.createEvent
|
|
2471
2924
|
))));
|
|
2472
|
-
return /* @__PURE__ */
|
|
2925
|
+
return /* @__PURE__ */ React17.createElement(Modal, { isOpen, onClose, hideHeader: true, className: "p-0 overflow-hidden max-w-lg rounded-2xl shadow-2xl" }, /* @__PURE__ */ React17.createElement(AnimatePresence, { mode: "wait" }, mode === "view" && event ? /* @__PURE__ */ React17.createElement(
|
|
2473
2926
|
motion2.div,
|
|
2474
2927
|
{
|
|
2475
2928
|
key: "view",
|
|
@@ -2479,7 +2932,7 @@ var EventModal = ({
|
|
|
2479
2932
|
transition: { duration: 0.15 }
|
|
2480
2933
|
},
|
|
2481
2934
|
renderViewMode()
|
|
2482
|
-
) : /* @__PURE__ */
|
|
2935
|
+
) : /* @__PURE__ */ React17.createElement(
|
|
2483
2936
|
motion2.div,
|
|
2484
2937
|
{
|
|
2485
2938
|
key: "edit",
|
|
@@ -2493,10 +2946,10 @@ var EventModal = ({
|
|
|
2493
2946
|
};
|
|
2494
2947
|
|
|
2495
2948
|
// src/components/Skeleton.tsx
|
|
2496
|
-
import
|
|
2497
|
-
var Skeleton = ({ className, style }) => /* @__PURE__ */
|
|
2498
|
-
var MonthViewSkeleton = () => /* @__PURE__ */
|
|
2499
|
-
var WeekViewSkeleton = () => /* @__PURE__ */
|
|
2949
|
+
import React18 from "react";
|
|
2950
|
+
var Skeleton = ({ className, style }) => /* @__PURE__ */ React18.createElement("div", { className: cn("animate-pulse bg-muted/40 rounded", className), style });
|
|
2951
|
+
var MonthViewSkeleton = () => /* @__PURE__ */ React18.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden" }, /* @__PURE__ */ React18.createElement("div", { className: "grid grid-cols-7 border-b border-border/50 bg-muted/10" }, Array.from({ length: 7 }).map((_, i) => /* @__PURE__ */ React18.createElement("div", { key: i, className: "py-3 px-2 text-center border-r border-border/30 last:border-r-0" }, /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-4 w-8 mx-auto" })))), /* @__PURE__ */ React18.createElement("div", { className: "grid grid-cols-7 flex-1" }, Array.from({ length: 35 }).map((_, i) => /* @__PURE__ */ React18.createElement("div", { key: i, className: "min-h-[120px] border-r border-b border-border/30 p-2" }, /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-4 w-6 mb-2" }), /* @__PURE__ */ React18.createElement("div", { className: "space-y-1" }, i * 7 % 10 > 4 && /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-5 w-full rounded-md" }), i * 3 % 10 > 6 && /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-5 w-3/4 rounded-md" }))))));
|
|
2952
|
+
var WeekViewSkeleton = () => /* @__PURE__ */ React18.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden" }, /* @__PURE__ */ React18.createElement("div", { className: "flex border-b border-border/50 bg-muted/10" }, /* @__PURE__ */ React18.createElement("div", { className: "w-16 p-3 border-r border-border/30" }, /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-8 w-10 mx-auto" })), /* @__PURE__ */ React18.createElement("div", { className: "flex-1 grid grid-cols-7" }, Array.from({ length: 7 }).map((_, i) => /* @__PURE__ */ React18.createElement("div", { key: i, className: "py-3 px-2 text-center border-r border-border/30 last:border-r-0" }, /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-3 w-8 mx-auto mb-1" }), /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-8 w-8 mx-auto rounded-xl" }))))), /* @__PURE__ */ React18.createElement("div", { className: "flex flex-1", style: { height: "600px" } }, /* @__PURE__ */ React18.createElement("div", { className: "w-16 border-r border-border/30" }, Array.from({ length: 10 }).map((_, i) => /* @__PURE__ */ React18.createElement("div", { key: i, className: "h-[60px] relative" }, /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-4 w-10 absolute right-2 -translate-y-1/2" })))), /* @__PURE__ */ React18.createElement("div", { className: "flex-1 grid grid-cols-7 relative" }, Array.from({ length: 7 }).map((_, colIdx) => /* @__PURE__ */ React18.createElement("div", { key: colIdx, className: "relative border-r border-border/30 last:border-r-0" }, Array.from({ length: 10 }).map((_2, rowIdx) => /* @__PURE__ */ React18.createElement("div", { key: rowIdx, className: "h-[60px] border-b border-dashed border-border/20" })), Math.random() > 0.3 && /* @__PURE__ */ React18.createElement(
|
|
2500
2953
|
Skeleton,
|
|
2501
2954
|
{
|
|
2502
2955
|
className: "absolute rounded-md",
|
|
@@ -2508,23 +2961,23 @@ var WeekViewSkeleton = () => /* @__PURE__ */ React16.createElement("div", { clas
|
|
|
2508
2961
|
}
|
|
2509
2962
|
}
|
|
2510
2963
|
))))));
|
|
2511
|
-
var DayViewSkeleton = () => /* @__PURE__ */
|
|
2964
|
+
var DayViewSkeleton = () => /* @__PURE__ */ React18.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden" }, /* @__PURE__ */ React18.createElement("div", { className: "px-6 py-4 border-b border-border/50 bg-muted/10 text-center" }, /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-7 w-64 mx-auto" })), /* @__PURE__ */ React18.createElement("div", { className: "flex flex-1", style: { height: "600px" } }, /* @__PURE__ */ React18.createElement("div", { className: "w-20 border-r border-border/30 bg-muted/5" }, Array.from({ length: 10 }).map((_, i) => /* @__PURE__ */ React18.createElement("div", { key: i, className: "h-[80px] relative" }, /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-4 w-12 absolute left-1/2 -translate-x-1/2 -translate-y-1/2" })))), /* @__PURE__ */ React18.createElement("div", { className: "flex-1 relative" }, Array.from({ length: 10 }).map((_, i) => /* @__PURE__ */ React18.createElement("div", { key: i, className: "h-[80px] border-b border-dashed border-border/20" })), /* @__PURE__ */ React18.createElement(
|
|
2512
2965
|
Skeleton,
|
|
2513
2966
|
{
|
|
2514
2967
|
className: "absolute rounded-lg left-4 right-4",
|
|
2515
2968
|
style: { top: "160px", height: "120px" }
|
|
2516
2969
|
}
|
|
2517
|
-
), /* @__PURE__ */
|
|
2970
|
+
), /* @__PURE__ */ React18.createElement(
|
|
2518
2971
|
Skeleton,
|
|
2519
2972
|
{
|
|
2520
2973
|
className: "absolute rounded-lg left-4 right-4",
|
|
2521
2974
|
style: { top: "400px", height: "80px" }
|
|
2522
2975
|
}
|
|
2523
2976
|
))));
|
|
2524
|
-
var AgendaViewSkeleton = () => /* @__PURE__ */
|
|
2977
|
+
var AgendaViewSkeleton = () => /* @__PURE__ */ React18.createElement("div", { className: "h-full bg-background border border-border/50 rounded-2xl overflow-hidden p-6" }, /* @__PURE__ */ React18.createElement("div", { className: "space-y-6" }, Array.from({ length: 4 }).map((_, dayIdx) => /* @__PURE__ */ React18.createElement("div", { key: dayIdx }, /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-5 w-40 mb-4" }), /* @__PURE__ */ React18.createElement("div", { className: "space-y-3" }, Array.from({ length: 2 + Math.floor(Math.random() * 3) }).map((_2, eventIdx) => /* @__PURE__ */ React18.createElement("div", { key: eventIdx, className: "flex items-center gap-4 p-3 rounded-xl bg-muted/10" }, /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-10 w-10 rounded-lg" }), /* @__PURE__ */ React18.createElement("div", { className: "flex-1 space-y-2" }, /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-4 w-3/4" }), /* @__PURE__ */ React18.createElement(Skeleton, { className: "h-3 w-1/2" })))))))));
|
|
2525
2978
|
|
|
2526
2979
|
// src/components/ContextMenu.tsx
|
|
2527
|
-
import
|
|
2980
|
+
import React19, { useState as useState6, useCallback as useCallback3, useEffect as useEffect5, useRef as useRef6 } from "react";
|
|
2528
2981
|
import { Edit3, Trash2 as Trash22, Copy } from "lucide-react";
|
|
2529
2982
|
import { AnimatePresence as AnimatePresence2, motion as motion3 } from "framer-motion";
|
|
2530
2983
|
var EventContextMenu = ({
|
|
@@ -2537,8 +2990,8 @@ var EventContextMenu = ({
|
|
|
2537
2990
|
customActions = [],
|
|
2538
2991
|
translations
|
|
2539
2992
|
}) => {
|
|
2540
|
-
const menuRef =
|
|
2541
|
-
|
|
2993
|
+
const menuRef = useRef6(null);
|
|
2994
|
+
useEffect5(() => {
|
|
2542
2995
|
const handleKeyDown = (e) => {
|
|
2543
2996
|
if (e.key === "Escape") {
|
|
2544
2997
|
onClose();
|
|
@@ -2549,7 +3002,7 @@ var EventContextMenu = ({
|
|
|
2549
3002
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
2550
3003
|
}
|
|
2551
3004
|
}, [position, onClose]);
|
|
2552
|
-
|
|
3005
|
+
useEffect5(() => {
|
|
2553
3006
|
const handleClickOutside = (e) => {
|
|
2554
3007
|
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
2555
3008
|
onClose();
|
|
@@ -2567,7 +3020,7 @@ var EventContextMenu = ({
|
|
|
2567
3020
|
...onEdit ? [{
|
|
2568
3021
|
id: "edit",
|
|
2569
3022
|
label: translations?.edit || "Edit",
|
|
2570
|
-
icon: /* @__PURE__ */
|
|
3023
|
+
icon: /* @__PURE__ */ React19.createElement(Edit3, { className: "w-4 h-4" }),
|
|
2571
3024
|
onClick: () => {
|
|
2572
3025
|
onEdit(event);
|
|
2573
3026
|
onClose();
|
|
@@ -2576,7 +3029,7 @@ var EventContextMenu = ({
|
|
|
2576
3029
|
...onDuplicate ? [{
|
|
2577
3030
|
id: "duplicate",
|
|
2578
3031
|
label: translations?.duplicate || "Duplicate",
|
|
2579
|
-
icon: /* @__PURE__ */
|
|
3032
|
+
icon: /* @__PURE__ */ React19.createElement(Copy, { className: "w-4 h-4" }),
|
|
2580
3033
|
onClick: () => {
|
|
2581
3034
|
onDuplicate(event);
|
|
2582
3035
|
onClose();
|
|
@@ -2586,7 +3039,7 @@ var EventContextMenu = ({
|
|
|
2586
3039
|
...onDelete ? [{
|
|
2587
3040
|
id: "delete",
|
|
2588
3041
|
label: translations?.delete || "Delete",
|
|
2589
|
-
icon: /* @__PURE__ */
|
|
3042
|
+
icon: /* @__PURE__ */ React19.createElement(Trash22, { className: "w-4 h-4" }),
|
|
2590
3043
|
onClick: () => {
|
|
2591
3044
|
onDelete(event.id);
|
|
2592
3045
|
onClose();
|
|
@@ -2598,7 +3051,7 @@ var EventContextMenu = ({
|
|
|
2598
3051
|
x: Math.min(position.x, window.innerWidth - 200),
|
|
2599
3052
|
y: Math.min(position.y, window.innerHeight - (actions.length * 44 + 80))
|
|
2600
3053
|
};
|
|
2601
|
-
return /* @__PURE__ */
|
|
3054
|
+
return /* @__PURE__ */ React19.createElement(AnimatePresence2, null, /* @__PURE__ */ React19.createElement(
|
|
2602
3055
|
motion3.div,
|
|
2603
3056
|
{
|
|
2604
3057
|
ref: menuRef,
|
|
@@ -2612,14 +3065,14 @@ var EventContextMenu = ({
|
|
|
2612
3065
|
top: adjustedPosition.y
|
|
2613
3066
|
}
|
|
2614
3067
|
},
|
|
2615
|
-
/* @__PURE__ */
|
|
3068
|
+
/* @__PURE__ */ React19.createElement("div", { className: "px-3 py-2 border-b-[0.5px] border-border bg-muted/30" }, /* @__PURE__ */ React19.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React19.createElement(
|
|
2616
3069
|
"div",
|
|
2617
3070
|
{
|
|
2618
3071
|
className: "w-2.5 h-2.5 rounded-full shrink-0",
|
|
2619
3072
|
style: { backgroundColor: event.color || "var(--primary)" }
|
|
2620
3073
|
}
|
|
2621
|
-
), /* @__PURE__ */
|
|
2622
|
-
/* @__PURE__ */
|
|
3074
|
+
), /* @__PURE__ */ React19.createElement("span", { className: "text-sm font-medium truncate text-foreground" }, event.title))),
|
|
3075
|
+
/* @__PURE__ */ React19.createElement("div", { className: "py-1" }, actions.map((action, index) => /* @__PURE__ */ React19.createElement(React19.Fragment, { key: action.id }, index > 0 && action.variant === "danger" && /* @__PURE__ */ React19.createElement("div", { className: "h-px bg-border my-1" }), /* @__PURE__ */ React19.createElement(
|
|
2623
3076
|
"button",
|
|
2624
3077
|
{
|
|
2625
3078
|
onClick: action.onClick,
|
|
@@ -2631,13 +3084,13 @@ var EventContextMenu = ({
|
|
|
2631
3084
|
)
|
|
2632
3085
|
},
|
|
2633
3086
|
action.icon,
|
|
2634
|
-
/* @__PURE__ */
|
|
3087
|
+
/* @__PURE__ */ React19.createElement("span", null, action.label)
|
|
2635
3088
|
))))
|
|
2636
3089
|
));
|
|
2637
3090
|
};
|
|
2638
3091
|
var useEventContextMenu = () => {
|
|
2639
|
-
const [contextMenu, setContextMenu] =
|
|
2640
|
-
const openContextMenu =
|
|
3092
|
+
const [contextMenu, setContextMenu] = useState6({ event: null, position: null });
|
|
3093
|
+
const openContextMenu = useCallback3((event, e) => {
|
|
2641
3094
|
e.preventDefault();
|
|
2642
3095
|
e.stopPropagation();
|
|
2643
3096
|
setContextMenu({
|
|
@@ -2645,7 +3098,7 @@ var useEventContextMenu = () => {
|
|
|
2645
3098
|
position: { x: e.clientX, y: e.clientY }
|
|
2646
3099
|
});
|
|
2647
3100
|
}, []);
|
|
2648
|
-
const closeContextMenu =
|
|
3101
|
+
const closeContextMenu = useCallback3(() => {
|
|
2649
3102
|
setContextMenu({ event: null, position: null });
|
|
2650
3103
|
}, []);
|
|
2651
3104
|
return {
|
|
@@ -2736,13 +3189,13 @@ function getThemeStyles(theme) {
|
|
|
2736
3189
|
}
|
|
2737
3190
|
|
|
2738
3191
|
// src/hooks/useCalendarLogic.ts
|
|
2739
|
-
import { useMemo as useMemo3, useState as
|
|
3192
|
+
import { useMemo as useMemo3, useState as useState7 } from "react";
|
|
2740
3193
|
import {
|
|
2741
|
-
addDays as
|
|
3194
|
+
addDays as addDays9,
|
|
2742
3195
|
addMonths as addMonths3,
|
|
2743
3196
|
addWeeks,
|
|
2744
3197
|
endOfMonth as endOfMonth2,
|
|
2745
|
-
format as
|
|
3198
|
+
format as format15,
|
|
2746
3199
|
startOfMonth as startOfMonth3,
|
|
2747
3200
|
startOfWeek as startOfWeek2,
|
|
2748
3201
|
subDays,
|
|
@@ -2828,17 +3281,18 @@ function cachedMonth(event, monthStart, tz) {
|
|
|
2828
3281
|
}
|
|
2829
3282
|
function expandRecurrences(events, range, anchorTz) {
|
|
2830
3283
|
const result = [];
|
|
2831
|
-
const lastMonth = startOfMonth2(toDisplay(range.end, anchorTz));
|
|
2832
3284
|
for (const event of events) {
|
|
2833
3285
|
if (!event.recurrence) {
|
|
2834
3286
|
result.push(event);
|
|
2835
3287
|
continue;
|
|
2836
3288
|
}
|
|
3289
|
+
const tz = event.allDay ? void 0 : anchorTz;
|
|
3290
|
+
const lastMonth = startOfMonth2(toDisplay(range.end, tz));
|
|
2837
3291
|
const duration = event.end.getTime() - event.start.getTime();
|
|
2838
|
-
const firstMonth = startOfMonth2(toDisplay(new Date(range.start.getTime() - duration),
|
|
3292
|
+
const firstMonth = startOfMonth2(toDisplay(new Date(range.start.getTime() - duration), tz));
|
|
2839
3293
|
try {
|
|
2840
3294
|
for (let month = firstMonth; month <= lastMonth; month = addMonths2(month, 1)) {
|
|
2841
|
-
for (const occurrence of cachedMonth(event, fromDisplay(month,
|
|
3295
|
+
for (const occurrence of cachedMonth(event, fromDisplay(month, tz), tz)) {
|
|
2842
3296
|
if (occurrence.end >= range.start && occurrence.start <= range.end) result.push(occurrence);
|
|
2843
3297
|
}
|
|
2844
3298
|
}
|
|
@@ -2854,8 +3308,8 @@ function stripOccurrenceFields(event) {
|
|
|
2854
3308
|
return rest;
|
|
2855
3309
|
}
|
|
2856
3310
|
var shiftFloating = (instant, deltaMs, tz) => fromFloating(new Date(toFloating(instant, tz).getTime() + deltaMs), tz);
|
|
2857
|
-
var
|
|
2858
|
-
var floatingDay = (floating) => Math.floor(floating.getTime() /
|
|
3311
|
+
var DAY_MS2 = 24 * 60 * 60 * 1e3;
|
|
3312
|
+
var floatingDay = (floating) => Math.floor(floating.getTime() / DAY_MS2);
|
|
2859
3313
|
function shiftSeries(master, occurrence, newStart, newEnd, anchorTz) {
|
|
2860
3314
|
const fromFloat = toFloating(occurrence.start, anchorTz);
|
|
2861
3315
|
const toFloat = toFloating(newStart, anchorTz);
|
|
@@ -2877,23 +3331,23 @@ function excludeOccurrence(master, occurrenceStart) {
|
|
|
2877
3331
|
}
|
|
2878
3332
|
|
|
2879
3333
|
// src/hooks/useStableCallback.ts
|
|
2880
|
-
import { useCallback as
|
|
3334
|
+
import { useCallback as useCallback4, useInsertionEffect as useInsertionEffect2, useRef as useRef7 } from "react";
|
|
2881
3335
|
function useStableCallback(fn) {
|
|
2882
|
-
const ref =
|
|
3336
|
+
const ref = useRef7(fn);
|
|
2883
3337
|
useInsertionEffect2(() => {
|
|
2884
3338
|
ref.current = fn;
|
|
2885
3339
|
});
|
|
2886
|
-
return
|
|
3340
|
+
return useCallback4((...args) => ref.current(...args), []);
|
|
2887
3341
|
}
|
|
2888
3342
|
|
|
2889
3343
|
// src/hooks/useCalendarLogic.ts
|
|
2890
3344
|
function expansionRange(monthStart) {
|
|
2891
3345
|
return {
|
|
2892
3346
|
start: startOfWeek2(startOfMonth3(subMonths2(monthStart, 1))),
|
|
2893
|
-
end:
|
|
3347
|
+
end: addDays9(endOfMonth2(addMonths3(monthStart, 1)), 37)
|
|
2894
3348
|
};
|
|
2895
3349
|
}
|
|
2896
|
-
var
|
|
3350
|
+
var DAY_MS3 = 24 * 60 * 60 * 1e3;
|
|
2897
3351
|
var useCalendarLogic = ({
|
|
2898
3352
|
events,
|
|
2899
3353
|
view: controlledView,
|
|
@@ -2910,17 +3364,18 @@ var useCalendarLogic = ({
|
|
|
2910
3364
|
readOnly,
|
|
2911
3365
|
timezone
|
|
2912
3366
|
}) => {
|
|
2913
|
-
const [internalView, setInternalView] =
|
|
2914
|
-
const [internalDate, setInternalDate] =
|
|
2915
|
-
const [isSidebarOpen, setIsSidebarOpen] =
|
|
2916
|
-
const [isModalOpen, setIsModalOpen] =
|
|
2917
|
-
const [selectedEvent, setSelectedEvent] =
|
|
2918
|
-
const [modalInitialDate, setModalInitialDate] =
|
|
2919
|
-
const [modalInitialResourceId, setModalInitialResourceId] =
|
|
3367
|
+
const [internalView, setInternalView] = useState7("week");
|
|
3368
|
+
const [internalDate, setInternalDate] = useState7(() => /* @__PURE__ */ new Date());
|
|
3369
|
+
const [isSidebarOpen, setIsSidebarOpen] = useState7(true);
|
|
3370
|
+
const [isModalOpen, setIsModalOpen] = useState7(false);
|
|
3371
|
+
const [selectedEvent, setSelectedEvent] = useState7(null);
|
|
3372
|
+
const [modalInitialDate, setModalInitialDate] = useState7(void 0);
|
|
3373
|
+
const [modalInitialResourceId, setModalInitialResourceId] = useState7(void 0);
|
|
3374
|
+
const [modalInitialAllDay, setModalInitialAllDay] = useState7(false);
|
|
2920
3375
|
const view = controlledView ?? internalView;
|
|
2921
3376
|
const currentDate = controlledDate ?? internalDate;
|
|
2922
3377
|
const normalizedEvents = useMemo3(() => normalizeEvents(events), [events]);
|
|
2923
|
-
const monthKey =
|
|
3378
|
+
const monthKey = format15(currentDate, "yyyy-MM");
|
|
2924
3379
|
const range = useMemo3(() => expansionRange(/* @__PURE__ */ new Date(`${monthKey}-01T00:00:00`)), [monthKey]);
|
|
2925
3380
|
const expandedEvents = useMemo3(
|
|
2926
3381
|
() => expandRecurrences(normalizedEvents, range, timezone),
|
|
@@ -2968,10 +3423,10 @@ var useCalendarLogic = ({
|
|
|
2968
3423
|
break;
|
|
2969
3424
|
case "day":
|
|
2970
3425
|
case "resource":
|
|
2971
|
-
handleDateChange(
|
|
3426
|
+
handleDateChange(addDays9(currentDate, 1));
|
|
2972
3427
|
break;
|
|
2973
3428
|
case "agenda":
|
|
2974
|
-
handleDateChange(
|
|
3429
|
+
handleDateChange(addDays9(currentDate, 7));
|
|
2975
3430
|
break;
|
|
2976
3431
|
}
|
|
2977
3432
|
});
|
|
@@ -2987,6 +3442,15 @@ var useCalendarLogic = ({
|
|
|
2987
3442
|
setSelectedEvent(null);
|
|
2988
3443
|
setModalInitialDate(date);
|
|
2989
3444
|
setModalInitialResourceId(resourceId);
|
|
3445
|
+
setModalInitialAllDay(false);
|
|
3446
|
+
setIsModalOpen(true);
|
|
3447
|
+
});
|
|
3448
|
+
const handleAllDaySlotClick = useStableCallback((day) => {
|
|
3449
|
+
if (readOnly) return;
|
|
3450
|
+
setSelectedEvent(null);
|
|
3451
|
+
setModalInitialDate(day);
|
|
3452
|
+
setModalInitialResourceId(void 0);
|
|
3453
|
+
setModalInitialAllDay(true);
|
|
2990
3454
|
setIsModalOpen(true);
|
|
2991
3455
|
});
|
|
2992
3456
|
const handleEventClickInternal = useStableCallback((event) => {
|
|
@@ -2995,6 +3459,7 @@ var useCalendarLogic = ({
|
|
|
2995
3459
|
setSelectedEvent(event);
|
|
2996
3460
|
setModalInitialDate(void 0);
|
|
2997
3461
|
setModalInitialResourceId(void 0);
|
|
3462
|
+
setModalInitialAllDay(false);
|
|
2998
3463
|
setIsModalOpen(true);
|
|
2999
3464
|
}
|
|
3000
3465
|
});
|
|
@@ -3003,6 +3468,7 @@ var useCalendarLogic = ({
|
|
|
3003
3468
|
setSelectedEvent(null);
|
|
3004
3469
|
setModalInitialDate(/* @__PURE__ */ new Date());
|
|
3005
3470
|
setModalInitialResourceId(void 0);
|
|
3471
|
+
setModalInitialAllDay(false);
|
|
3006
3472
|
setIsModalOpen(true);
|
|
3007
3473
|
});
|
|
3008
3474
|
const handleModalSave = useStableCallback((eventData) => {
|
|
@@ -3017,7 +3483,7 @@ var useCalendarLogic = ({
|
|
|
3017
3483
|
end: master.end
|
|
3018
3484
|
};
|
|
3019
3485
|
onEventUpdate?.(
|
|
3020
|
-
shiftSeries(edited, selectedEvent, eventData.start ?? selectedEvent.start, eventData.end ?? selectedEvent.end, timezone)
|
|
3486
|
+
shiftSeries(edited, selectedEvent, eventData.start ?? selectedEvent.start, eventData.end ?? selectedEvent.end, edited.allDay ? void 0 : timezone)
|
|
3021
3487
|
);
|
|
3022
3488
|
} else if (selectedEvent) {
|
|
3023
3489
|
onEventUpdate?.({ ...eventData, id: selectedEvent.id });
|
|
@@ -3052,15 +3518,15 @@ var useCalendarLogic = ({
|
|
|
3052
3518
|
...copy,
|
|
3053
3519
|
id: `${event.originalEventId ?? event.id}-copy-${Date.now()}`,
|
|
3054
3520
|
title: `${event.title} (Copy)`,
|
|
3055
|
-
start: new Date(event.start.getTime() +
|
|
3056
|
-
end: new Date(event.end.getTime() +
|
|
3521
|
+
start: new Date(event.start.getTime() + DAY_MS3),
|
|
3522
|
+
end: new Date(event.end.getTime() + DAY_MS3)
|
|
3057
3523
|
});
|
|
3058
3524
|
});
|
|
3059
3525
|
const applyChange = (event, start, end) => {
|
|
3060
3526
|
if (!event.originalEventId) return { original: event, updated: { ...event, start, end } };
|
|
3061
3527
|
const master = masterOf(event);
|
|
3062
3528
|
if (!master) return null;
|
|
3063
|
-
return { original: master, updated: shiftSeries(master, event, start, end, timezone) };
|
|
3529
|
+
return { original: master, updated: shiftSeries(master, event, start, end, event.allDay ? void 0 : timezone) };
|
|
3064
3530
|
};
|
|
3065
3531
|
const handleDragEnd = useStableCallback((dragEvent) => {
|
|
3066
3532
|
if (readOnly) return;
|
|
@@ -3069,12 +3535,22 @@ var useCalendarLogic = ({
|
|
|
3069
3535
|
const dragged = active.data.current?.event;
|
|
3070
3536
|
const overDate = over.data.current?.date;
|
|
3071
3537
|
if (!dragged || !overDate) return;
|
|
3538
|
+
const grabDayOffset = active.data.current?.grabDayOffset;
|
|
3539
|
+
if (grabDayOffset !== void 0) {
|
|
3540
|
+
const move = computeDayMove(dragged, overDate, grabDayOffset, timezone);
|
|
3541
|
+
const dayChange = move && applyChange(dragged, move.start, move.end);
|
|
3542
|
+
if (!dayChange) return;
|
|
3543
|
+
onEventDrop?.(dayChange.original, dayChange.updated.start, dayChange.updated.end);
|
|
3544
|
+
onEventUpdate?.(dayChange.updated);
|
|
3545
|
+
return;
|
|
3546
|
+
}
|
|
3072
3547
|
const drop = computeDrop({
|
|
3073
3548
|
event: dragged,
|
|
3074
3549
|
overDate,
|
|
3075
3550
|
overResourceId: over.data.current?.resourceId,
|
|
3076
3551
|
grabOffsetMs: active.data.current?.grabOffsetMs,
|
|
3077
|
-
view
|
|
3552
|
+
// A timed event dropped in the all-day row only changes day (keeps its time), like in month view.
|
|
3553
|
+
view: over.data.current?.allDayRow ? "month" : view,
|
|
3078
3554
|
tz: timezone
|
|
3079
3555
|
});
|
|
3080
3556
|
if (!drop) return;
|
|
@@ -3084,6 +3560,14 @@ var useCalendarLogic = ({
|
|
|
3084
3560
|
onEventDrop?.(change.original, updated.start, updated.end);
|
|
3085
3561
|
onEventUpdate?.(updated);
|
|
3086
3562
|
});
|
|
3563
|
+
const handleDayEventResize = useStableCallback((event, newLastDay) => {
|
|
3564
|
+
if (readOnly) return;
|
|
3565
|
+
const end = computeDayResize(event, newLastDay, timezone);
|
|
3566
|
+
const change = end && applyChange(event, event.start, end);
|
|
3567
|
+
if (!change) return;
|
|
3568
|
+
onEventResize?.(change.original, change.updated.start, change.updated.end);
|
|
3569
|
+
onEventUpdate?.(change.updated);
|
|
3570
|
+
});
|
|
3087
3571
|
const handleEventResize = useStableCallback((event, newEnd) => {
|
|
3088
3572
|
if (readOnly) return;
|
|
3089
3573
|
const change = applyChange(event, event.start, newEnd);
|
|
@@ -3100,6 +3584,7 @@ var useCalendarLogic = ({
|
|
|
3100
3584
|
setIsModalOpen,
|
|
3101
3585
|
selectedEvent,
|
|
3102
3586
|
modalInitialDate,
|
|
3587
|
+
modalInitialAllDay,
|
|
3103
3588
|
expandedEvents,
|
|
3104
3589
|
handleViewChange,
|
|
3105
3590
|
handleDateChange,
|
|
@@ -3108,6 +3593,7 @@ var useCalendarLogic = ({
|
|
|
3108
3593
|
handleToday,
|
|
3109
3594
|
handleDateClick,
|
|
3110
3595
|
handleTimeSlotClick,
|
|
3596
|
+
handleAllDaySlotClick,
|
|
3111
3597
|
handleEventClickInternal,
|
|
3112
3598
|
handleCreateEvent,
|
|
3113
3599
|
handleModalSave,
|
|
@@ -3115,15 +3601,16 @@ var useCalendarLogic = ({
|
|
|
3115
3601
|
handleEventDelete,
|
|
3116
3602
|
handleEventDuplicate,
|
|
3117
3603
|
handleEventResize,
|
|
3604
|
+
handleDayEventResize,
|
|
3118
3605
|
handleDragEnd
|
|
3119
3606
|
};
|
|
3120
3607
|
};
|
|
3121
3608
|
|
|
3122
3609
|
// src/index.tsx
|
|
3123
|
-
import {
|
|
3610
|
+
import { format as format16, startOfWeek as startOfWeek3 } from "date-fns";
|
|
3124
3611
|
|
|
3125
3612
|
// src/hooks/useSwipeGesture.ts
|
|
3126
|
-
import { useRef as
|
|
3613
|
+
import { useRef as useRef8, useCallback as useCallback5, useEffect as useEffect6 } from "react";
|
|
3127
3614
|
var useSwipeGesture = (options) => {
|
|
3128
3615
|
const {
|
|
3129
3616
|
onSwipeLeft,
|
|
@@ -3135,9 +3622,9 @@ var useSwipeGesture = (options) => {
|
|
|
3135
3622
|
allowedTime = 500,
|
|
3136
3623
|
enabled = true
|
|
3137
3624
|
} = options;
|
|
3138
|
-
const touchInfoRef =
|
|
3139
|
-
const elementRef =
|
|
3140
|
-
const handleTouchStart =
|
|
3625
|
+
const touchInfoRef = useRef8(null);
|
|
3626
|
+
const elementRef = useRef8(null);
|
|
3627
|
+
const handleTouchStart = useCallback5((e) => {
|
|
3141
3628
|
if (!enabled) return;
|
|
3142
3629
|
const touch = e.touches[0];
|
|
3143
3630
|
touchInfoRef.current = {
|
|
@@ -3146,7 +3633,7 @@ var useSwipeGesture = (options) => {
|
|
|
3146
3633
|
startTime: Date.now()
|
|
3147
3634
|
};
|
|
3148
3635
|
}, [enabled]);
|
|
3149
|
-
const handleTouchEnd =
|
|
3636
|
+
const handleTouchEnd = useCallback5((e) => {
|
|
3150
3637
|
if (!enabled || !touchInfoRef.current) return;
|
|
3151
3638
|
const touch = e.changedTouches[0];
|
|
3152
3639
|
const { startX, startY, startTime } = touchInfoRef.current;
|
|
@@ -3170,7 +3657,7 @@ var useSwipeGesture = (options) => {
|
|
|
3170
3657
|
}
|
|
3171
3658
|
touchInfoRef.current = null;
|
|
3172
3659
|
}, [enabled, threshold, restraint, allowedTime, onSwipeLeft, onSwipeRight, onSwipeUp, onSwipeDown]);
|
|
3173
|
-
|
|
3660
|
+
useEffect6(() => {
|
|
3174
3661
|
const element = elementRef.current;
|
|
3175
3662
|
if (!element) return;
|
|
3176
3663
|
element.addEventListener("touchstart", handleTouchStart, { passive: true });
|
|
@@ -3193,6 +3680,25 @@ var useViewSwipe = (onPrev, onNext, enabled = true) => {
|
|
|
3193
3680
|
});
|
|
3194
3681
|
};
|
|
3195
3682
|
|
|
3683
|
+
// src/components/dnd/dragOverlay.ts
|
|
3684
|
+
import { pointerWithin, rectIntersection } from "@dnd-kit/core";
|
|
3685
|
+
import { differenceInMinutes as differenceInMinutes6 } from "date-fns";
|
|
3686
|
+
var dayAwareCollision = (args) => {
|
|
3687
|
+
if (args.active.data.current?.grabDayOffset !== void 0) {
|
|
3688
|
+
const underPointer = pointerWithin(args);
|
|
3689
|
+
if (underPointer.length > 0) return underPointer;
|
|
3690
|
+
}
|
|
3691
|
+
return rectIntersection(args);
|
|
3692
|
+
};
|
|
3693
|
+
function dragOverlaySize(view, event, isDayDrag) {
|
|
3694
|
+
if (isDayDrag) return {};
|
|
3695
|
+
const minutes = differenceInMinutes6(event.end, event.start);
|
|
3696
|
+
if (view === "month") return { width: "100%" };
|
|
3697
|
+
if (view === "resource") return { width: `${Math.max(minutes / 60 * 100, 4)}px`, height: 80 };
|
|
3698
|
+
if (view === "week" || view === "day") return { width: "150px", height: minutes / 60 * (view === "day" ? 80 : 60) };
|
|
3699
|
+
return { width: "150px" };
|
|
3700
|
+
}
|
|
3701
|
+
|
|
3196
3702
|
// src/index.tsx
|
|
3197
3703
|
var Scheduler = ({
|
|
3198
3704
|
events = [],
|
|
@@ -3228,7 +3734,8 @@ var Scheduler = ({
|
|
|
3228
3734
|
locale
|
|
3229
3735
|
// Date-fns locale
|
|
3230
3736
|
}) => {
|
|
3231
|
-
const [activeDragEvent, setActiveDragEvent] =
|
|
3737
|
+
const [activeDragEvent, setActiveDragEvent] = useState8(null);
|
|
3738
|
+
const [activeDayDrag, setActiveDayDrag] = useState8(false);
|
|
3232
3739
|
const {
|
|
3233
3740
|
contextMenuEvent,
|
|
3234
3741
|
contextMenuPosition,
|
|
@@ -3244,6 +3751,7 @@ var Scheduler = ({
|
|
|
3244
3751
|
setIsModalOpen,
|
|
3245
3752
|
selectedEvent,
|
|
3246
3753
|
modalInitialDate,
|
|
3754
|
+
modalInitialAllDay,
|
|
3247
3755
|
handleViewChange,
|
|
3248
3756
|
handleDateChange,
|
|
3249
3757
|
handlePrev,
|
|
@@ -3251,6 +3759,7 @@ var Scheduler = ({
|
|
|
3251
3759
|
handleToday,
|
|
3252
3760
|
handleDateClick,
|
|
3253
3761
|
handleTimeSlotClick,
|
|
3762
|
+
handleAllDaySlotClick,
|
|
3254
3763
|
handleEventClickInternal,
|
|
3255
3764
|
handleCreateEvent,
|
|
3256
3765
|
handleModalSave,
|
|
@@ -3258,6 +3767,7 @@ var Scheduler = ({
|
|
|
3258
3767
|
handleEventDelete,
|
|
3259
3768
|
handleEventDuplicate,
|
|
3260
3769
|
handleEventResize,
|
|
3770
|
+
handleDayEventResize,
|
|
3261
3771
|
handleDragEnd,
|
|
3262
3772
|
expandedEvents
|
|
3263
3773
|
} = useCalendarLogic({
|
|
@@ -3291,60 +3801,45 @@ var Scheduler = ({
|
|
|
3291
3801
|
const swipeRef = useViewSwipe(handlePrev, handleNext, true);
|
|
3292
3802
|
const t = useMemo4(() => resolveTranslations(language, translations), [language, translations]);
|
|
3293
3803
|
const overlayTimeFormat = timeFormats(locale).time;
|
|
3294
|
-
const handleDragStart =
|
|
3804
|
+
const handleDragStart = useCallback6((event) => {
|
|
3295
3805
|
const draggedEvent = event.active.data.current?.event;
|
|
3296
3806
|
if (draggedEvent) {
|
|
3297
3807
|
setActiveDragEvent(draggedEvent);
|
|
3808
|
+
setActiveDayDrag(event.active.data.current?.grabDayOffset !== void 0);
|
|
3298
3809
|
}
|
|
3299
3810
|
}, []);
|
|
3300
|
-
const onDragEndWrapper =
|
|
3811
|
+
const onDragEndWrapper = useCallback6((event) => {
|
|
3301
3812
|
setActiveDragEvent(null);
|
|
3302
3813
|
handleDragEnd(event);
|
|
3303
3814
|
}, [handleDragEnd]);
|
|
3304
|
-
const
|
|
3305
|
-
if (!activeDragEvent) return void 0;
|
|
3306
|
-
if (view === "resource") {
|
|
3307
|
-
return 80;
|
|
3308
|
-
}
|
|
3309
|
-
if (view !== "week" && view !== "day") return void 0;
|
|
3310
|
-
const duration = differenceInMinutes6(activeDragEvent.end, activeDragEvent.start);
|
|
3311
|
-
const hourHeight = view === "day" ? 80 : 60;
|
|
3312
|
-
return duration / 60 * hourHeight;
|
|
3313
|
-
};
|
|
3314
|
-
const getDragWidth = () => {
|
|
3315
|
-
if (view === "month") return "100%";
|
|
3316
|
-
if (view === "resource" && activeDragEvent) {
|
|
3317
|
-
const duration = differenceInMinutes6(activeDragEvent.end, activeDragEvent.start);
|
|
3318
|
-
const width = duration / 60 * 100;
|
|
3319
|
-
return `${Math.max(width, 4)}px`;
|
|
3320
|
-
}
|
|
3321
|
-
return "150px";
|
|
3322
|
-
};
|
|
3815
|
+
const dragSize = activeDragEvent ? dragOverlaySize(view, activeDragEvent, activeDayDrag) : {};
|
|
3323
3816
|
const activeCalendarKey = calendars ? calendars.filter((c) => c.active !== false).map((c) => c.id).join("\0") : null;
|
|
3324
3817
|
const filteredEvents = useMemo4(() => {
|
|
3325
3818
|
if (activeCalendarKey === null) return expandedEvents;
|
|
3326
3819
|
const activeCalendarIds = new Set(activeCalendarKey.split("\0"));
|
|
3327
3820
|
return expandedEvents.filter((e) => !e.calendarId || activeCalendarIds.has(String(e.calendarId)));
|
|
3328
3821
|
}, [expandedEvents, activeCalendarKey]);
|
|
3329
|
-
const periodKey = view === "month" ?
|
|
3822
|
+
const periodKey = view === "month" ? format16(currentDate, "yyyy-MM") : view === "week" ? format16(startOfWeek3(currentDate, { weekStartsOn: resolveWeekStartsOn(locale, 1) }), "yyyy-MM-dd") : format16(currentDate, "yyyy-MM-dd");
|
|
3330
3823
|
const slotClickHandler = readOnly ? void 0 : handleTimeSlotClick;
|
|
3824
|
+
const allDaySlotClickHandler = readOnly ? void 0 : handleAllDaySlotClick;
|
|
3331
3825
|
const contextMenuHandler = readOnly ? void 0 : openContextMenu;
|
|
3332
|
-
return /* @__PURE__ */
|
|
3826
|
+
return /* @__PURE__ */ React20.createElement(
|
|
3333
3827
|
DndContext,
|
|
3334
3828
|
{
|
|
3335
3829
|
id,
|
|
3336
3830
|
sensors: dndSensors,
|
|
3337
3831
|
onDragStart: handleDragStart,
|
|
3338
3832
|
onDragEnd: onDragEndWrapper,
|
|
3339
|
-
modifiers
|
|
3833
|
+
modifiers,
|
|
3834
|
+
collisionDetection: dayAwareCollision
|
|
3340
3835
|
},
|
|
3341
|
-
/* @__PURE__ */
|
|
3836
|
+
/* @__PURE__ */ React20.createElement(
|
|
3342
3837
|
"div",
|
|
3343
3838
|
{
|
|
3344
3839
|
className: cn("flex flex-col h-full bg-background text-foreground relative", className),
|
|
3345
3840
|
style: getThemeStyles(theme)
|
|
3346
3841
|
},
|
|
3347
|
-
/* @__PURE__ */
|
|
3842
|
+
/* @__PURE__ */ React20.createElement(
|
|
3348
3843
|
CalendarHeader,
|
|
3349
3844
|
{
|
|
3350
3845
|
currentDate,
|
|
@@ -3363,7 +3858,7 @@ var Scheduler = ({
|
|
|
3363
3858
|
locale
|
|
3364
3859
|
}
|
|
3365
3860
|
),
|
|
3366
|
-
/* @__PURE__ */
|
|
3861
|
+
/* @__PURE__ */ React20.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ React20.createElement(
|
|
3367
3862
|
motion4.div,
|
|
3368
3863
|
{
|
|
3369
3864
|
className: cn(
|
|
@@ -3379,7 +3874,7 @@ var Scheduler = ({
|
|
|
3379
3874
|
ease: [0.4, 0, 0.2, 1]
|
|
3380
3875
|
}
|
|
3381
3876
|
},
|
|
3382
|
-
/* @__PURE__ */
|
|
3877
|
+
/* @__PURE__ */ React20.createElement(
|
|
3383
3878
|
Sidebar,
|
|
3384
3879
|
{
|
|
3385
3880
|
currentDate,
|
|
@@ -3396,7 +3891,7 @@ var Scheduler = ({
|
|
|
3396
3891
|
locale
|
|
3397
3892
|
}
|
|
3398
3893
|
)
|
|
3399
|
-
), /* @__PURE__ */
|
|
3894
|
+
), /* @__PURE__ */ React20.createElement("div", { className: "flex-1 flex flex-col overflow-hidden relative" }, isLoading ? /* @__PURE__ */ React20.createElement("div", { className: "flex-1 overflow-auto p-0 md:p-4" }, /* @__PURE__ */ React20.createElement("div", { className: "h-full min-w-full" }, view === "month" && /* @__PURE__ */ React20.createElement(MonthViewSkeleton, null), view === "week" && /* @__PURE__ */ React20.createElement(WeekViewSkeleton, null), view === "day" && /* @__PURE__ */ React20.createElement(DayViewSkeleton, null), view === "agenda" && /* @__PURE__ */ React20.createElement(AgendaViewSkeleton, null), view === "resource" && /* @__PURE__ */ React20.createElement(WeekViewSkeleton, null))) : /* @__PURE__ */ React20.createElement("div", { ref: swipeRef, className: "flex-1 overflow-auto p-0 md:p-4 touch-pan-y" }, /* @__PURE__ */ React20.createElement("div", { className: "h-full min-w-full" }, /* @__PURE__ */ React20.createElement(AnimatePresence3, { mode: "wait", initial: false }, /* @__PURE__ */ React20.createElement(
|
|
3400
3895
|
motion4.div,
|
|
3401
3896
|
{
|
|
3402
3897
|
key: `${view}-${periodKey}-${timezone || "local"}`,
|
|
@@ -3421,7 +3916,7 @@ var Scheduler = ({
|
|
|
3421
3916
|
},
|
|
3422
3917
|
className: "h-full"
|
|
3423
3918
|
},
|
|
3424
|
-
view === "month" && /* @__PURE__ */
|
|
3919
|
+
view === "month" && /* @__PURE__ */ React20.createElement(
|
|
3425
3920
|
MonthView,
|
|
3426
3921
|
{
|
|
3427
3922
|
currentDate,
|
|
@@ -3431,10 +3926,12 @@ var Scheduler = ({
|
|
|
3431
3926
|
timezone,
|
|
3432
3927
|
locale,
|
|
3433
3928
|
translations: t,
|
|
3434
|
-
onEventContextMenu: contextMenuHandler
|
|
3929
|
+
onEventContextMenu: contextMenuHandler,
|
|
3930
|
+
onDayEventResize: handleDayEventResize,
|
|
3931
|
+
readonly: readOnly
|
|
3435
3932
|
}
|
|
3436
3933
|
),
|
|
3437
|
-
view === "week" && /* @__PURE__ */
|
|
3934
|
+
view === "week" && /* @__PURE__ */ React20.createElement(
|
|
3438
3935
|
WeekView,
|
|
3439
3936
|
{
|
|
3440
3937
|
currentDate,
|
|
@@ -3445,10 +3942,13 @@ var Scheduler = ({
|
|
|
3445
3942
|
timezone,
|
|
3446
3943
|
locale,
|
|
3447
3944
|
readonly: readOnly,
|
|
3448
|
-
onEventContextMenu: contextMenuHandler
|
|
3945
|
+
onEventContextMenu: contextMenuHandler,
|
|
3946
|
+
onDayEventResize: handleDayEventResize,
|
|
3947
|
+
onAllDaySlotClick: allDaySlotClickHandler,
|
|
3948
|
+
translations: t
|
|
3449
3949
|
}
|
|
3450
3950
|
),
|
|
3451
|
-
view === "day" && /* @__PURE__ */
|
|
3951
|
+
view === "day" && /* @__PURE__ */ React20.createElement(
|
|
3452
3952
|
DayView,
|
|
3453
3953
|
{
|
|
3454
3954
|
currentDate,
|
|
@@ -3460,10 +3960,12 @@ var Scheduler = ({
|
|
|
3460
3960
|
locale,
|
|
3461
3961
|
readonly: readOnly,
|
|
3462
3962
|
translations: t,
|
|
3463
|
-
onEventContextMenu: contextMenuHandler
|
|
3963
|
+
onEventContextMenu: contextMenuHandler,
|
|
3964
|
+
onDayEventResize: handleDayEventResize,
|
|
3965
|
+
onAllDaySlotClick: allDaySlotClickHandler
|
|
3464
3966
|
}
|
|
3465
3967
|
),
|
|
3466
|
-
view === "agenda" && /* @__PURE__ */
|
|
3968
|
+
view === "agenda" && /* @__PURE__ */ React20.createElement(
|
|
3467
3969
|
AgendaView,
|
|
3468
3970
|
{
|
|
3469
3971
|
currentDate,
|
|
@@ -3476,7 +3978,7 @@ var Scheduler = ({
|
|
|
3476
3978
|
onEventContextMenu: contextMenuHandler
|
|
3477
3979
|
}
|
|
3478
3980
|
),
|
|
3479
|
-
view === "resource" && resources && /* @__PURE__ */
|
|
3981
|
+
view === "resource" && resources && /* @__PURE__ */ React20.createElement(
|
|
3480
3982
|
ResourceView,
|
|
3481
3983
|
{
|
|
3482
3984
|
currentDate,
|
|
@@ -3490,23 +3992,24 @@ var Scheduler = ({
|
|
|
3490
3992
|
onEventContextMenu: contextMenuHandler
|
|
3491
3993
|
}
|
|
3492
3994
|
)
|
|
3493
|
-
)))), !readOnly && /* @__PURE__ */
|
|
3995
|
+
)))), !readOnly && /* @__PURE__ */ React20.createElement("div", { className: "md:hidden absolute bottom-6 right-6 z-50" }, /* @__PURE__ */ React20.createElement(
|
|
3494
3996
|
"button",
|
|
3495
3997
|
{
|
|
3496
3998
|
onClick: handleCreateEvent,
|
|
3497
3999
|
"aria-label": t.createEvent,
|
|
3498
4000
|
className: "w-14 h-14 bg-blue-600 rounded-full shadow-lg flex items-center justify-center text-white active:scale-90 transition-transform"
|
|
3499
4001
|
},
|
|
3500
|
-
/* @__PURE__ */
|
|
4002
|
+
/* @__PURE__ */ React20.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__ */ React20.createElement("path", { d: "M5 12h14" }), /* @__PURE__ */ React20.createElement("path", { d: "M12 5v14" }))
|
|
3501
4003
|
)))),
|
|
3502
4004
|
renderEventForm ? renderEventForm({
|
|
3503
4005
|
isOpen: isModalOpen,
|
|
3504
4006
|
onClose: () => setIsModalOpen(false),
|
|
3505
4007
|
event: selectedEvent,
|
|
3506
4008
|
initialDate: modalInitialDate,
|
|
4009
|
+
initialAllDay: modalInitialAllDay,
|
|
3507
4010
|
onSave: handleModalSave,
|
|
3508
4011
|
onDelete: handleModalDelete
|
|
3509
|
-
}) : /* @__PURE__ */
|
|
4012
|
+
}) : /* @__PURE__ */ React20.createElement(
|
|
3510
4013
|
EventModal,
|
|
3511
4014
|
{
|
|
3512
4015
|
isOpen: isModalOpen,
|
|
@@ -3518,10 +4021,11 @@ var Scheduler = ({
|
|
|
3518
4021
|
calendars,
|
|
3519
4022
|
eventTypes,
|
|
3520
4023
|
translations: t,
|
|
3521
|
-
locale
|
|
4024
|
+
locale,
|
|
4025
|
+
initialAllDay: modalInitialAllDay
|
|
3522
4026
|
}
|
|
3523
4027
|
),
|
|
3524
|
-
/* @__PURE__ */
|
|
4028
|
+
/* @__PURE__ */ React20.createElement(
|
|
3525
4029
|
EventContextMenu,
|
|
3526
4030
|
{
|
|
3527
4031
|
event: contextMenuEvent,
|
|
@@ -3546,7 +4050,7 @@ var Scheduler = ({
|
|
|
3546
4050
|
}
|
|
3547
4051
|
}
|
|
3548
4052
|
),
|
|
3549
|
-
/* @__PURE__ */
|
|
4053
|
+
/* @__PURE__ */ React20.createElement(DragOverlay, { dropAnimation: null }, activeDragEvent ? /* @__PURE__ */ React20.createElement(
|
|
3550
4054
|
"div",
|
|
3551
4055
|
{
|
|
3552
4056
|
className: cn(
|
|
@@ -3558,19 +4062,19 @@ var Scheduler = ({
|
|
|
3558
4062
|
backgroundColor: activeDragEvent.color ? `${activeDragEvent.color}e0` : void 0,
|
|
3559
4063
|
borderColor: activeDragEvent.color ? `${activeDragEvent.color}80` : void 0,
|
|
3560
4064
|
color: activeDragEvent.color ? "#fff" : void 0,
|
|
3561
|
-
width:
|
|
3562
|
-
height:
|
|
4065
|
+
width: dragSize.width,
|
|
4066
|
+
height: dragSize.height ? `${dragSize.height}px` : void 0,
|
|
3563
4067
|
boxShadow: `0 20px 40px -15px ${activeDragEvent.color || "var(--primary)"}40, 0 10px 20px -10px rgba(0,0,0,0.2)`,
|
|
3564
4068
|
transform: "rotate(-2deg) scale(1.02)"
|
|
3565
4069
|
}
|
|
3566
4070
|
},
|
|
3567
|
-
/* @__PURE__ */
|
|
4071
|
+
/* @__PURE__ */ React20.createElement("div", { className: "p-2.5 h-full flex flex-col" }, /* @__PURE__ */ React20.createElement(
|
|
3568
4072
|
"div",
|
|
3569
4073
|
{
|
|
3570
4074
|
className: "absolute left-0 top-0 bottom-0 w-1 rounded-l-lg",
|
|
3571
4075
|
style: { backgroundColor: activeDragEvent.color || "var(--primary)" }
|
|
3572
4076
|
}
|
|
3573
|
-
), /* @__PURE__ */
|
|
4077
|
+
), /* @__PURE__ */ React20.createElement("div", { className: "pl-2" }, /* @__PURE__ */ React20.createElement("div", { className: "font-semibold truncate text-sm" }, activeDragEvent.title), (view === "week" || view === "day") && dragSize.height !== void 0 && dragSize.height > 40 && /* @__PURE__ */ React20.createElement("div", { className: "text-xs opacity-80 mt-0.5 flex items-center gap-1" }, /* @__PURE__ */ React20.createElement("svg", { className: "w-3 h-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2" }, /* @__PURE__ */ React20.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ React20.createElement("path", { d: "M12 6v6l4 2" })), format16(toDisplay(activeDragEvent.start, timezone), overlayTimeFormat, { locale }), " - ", format16(toDisplay(activeDragEvent.end, timezone), overlayTimeFormat, { locale }))), /* @__PURE__ */ React20.createElement("div", { className: "absolute bottom-1.5 right-1.5 opacity-60" }, /* @__PURE__ */ React20.createElement("svg", { className: "w-4 h-4", viewBox: "0 0 24 24", fill: "currentColor" }, /* @__PURE__ */ React20.createElement("circle", { cx: "9", cy: "5", r: "1.5" }), /* @__PURE__ */ React20.createElement("circle", { cx: "15", cy: "5", r: "1.5" }), /* @__PURE__ */ React20.createElement("circle", { cx: "9", cy: "12", r: "1.5" }), /* @__PURE__ */ React20.createElement("circle", { cx: "15", cy: "12", r: "1.5" }), /* @__PURE__ */ React20.createElement("circle", { cx: "9", cy: "19", r: "1.5" }), /* @__PURE__ */ React20.createElement("circle", { cx: "15", cy: "19", r: "1.5" }))))
|
|
3574
4078
|
) : null)
|
|
3575
4079
|
)
|
|
3576
4080
|
);
|