@open-mercato/core 0.6.6-develop.6519.1.bdc91fb755 → 0.6.6-develop.6520.1.55df6df792
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/.turbo/turbo-build.log +1 -1
- package/dist/modules/customers/backend/calendar/page.js +9 -1
- package/dist/modules/customers/backend/calendar/page.js.map +2 -2
- package/dist/modules/customers/components/calendar/AgendaList.js +0 -11
- package/dist/modules/customers/components/calendar/AgendaList.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js +391 -235
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarScreen.js +5 -5
- package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +2 -2
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
- package/dist/modules/customers/components/calendar/MonthGrid.js +1 -11
- package/dist/modules/customers/components/calendar/MonthGrid.js.map +2 -2
- package/dist/modules/customers/components/calendar/TimeGrid.js +162 -176
- package/dist/modules/customers/components/calendar/TimeGrid.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/LocationField.js +61 -14
- package/dist/modules/customers/components/calendar/editor/LocationField.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/PeopleField.js +10 -5
- package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/PriorityField.js +85 -0
- package/dist/modules/customers/components/calendar/editor/PriorityField.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/RelatedToField.js +8 -3
- package/dist/modules/customers/components/calendar/editor/RelatedToField.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/ResourcesField.js +225 -0
- package/dist/modules/customers/components/calendar/editor/ResourcesField.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/SegmentGroup.js +12 -7
- package/dist/modules/customers/components/calendar/editor/SegmentGroup.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/inputs.js +68 -57
- package/dist/modules/customers/components/calendar/editor/inputs.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/lookups.js +82 -2
- package/dist/modules/customers/components/calendar/editor/lookups.js.map +2 -2
- package/dist/modules/customers/components/calendar/useCalendarItems.js +6 -1
- package/dist/modules/customers/components/calendar/useCalendarItems.js.map +2 -2
- package/dist/modules/customers/data/validators.js +3 -1
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/customers/lib/calendar/editorPayload.js +53 -22
- package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/page.js +1 -1
- package/dist/modules/entities/backend/entities/user/[entityId]/page.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/customers/backend/calendar/page.tsx +8 -1
- package/src/modules/customers/components/calendar/AgendaList.tsx +0 -10
- package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +444 -261
- package/src/modules/customers/components/calendar/CalendarScreen.tsx +12 -5
- package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +6 -6
- package/src/modules/customers/components/calendar/MonthGrid.tsx +0 -11
- package/src/modules/customers/components/calendar/TimeGrid.tsx +1 -24
- package/src/modules/customers/components/calendar/editor/LocationField.tsx +64 -2
- package/src/modules/customers/components/calendar/editor/PeopleField.tsx +11 -4
- package/src/modules/customers/components/calendar/editor/PriorityField.tsx +90 -0
- package/src/modules/customers/components/calendar/editor/RelatedToField.tsx +8 -3
- package/src/modules/customers/components/calendar/editor/ResourcesField.tsx +264 -0
- package/src/modules/customers/components/calendar/editor/SegmentGroup.tsx +14 -6
- package/src/modules/customers/components/calendar/editor/inputs.tsx +91 -50
- package/src/modules/customers/components/calendar/editor/lookups.ts +115 -2
- package/src/modules/customers/components/calendar/useCalendarItems.ts +8 -1
- package/src/modules/customers/data/validators.ts +3 -1
- package/src/modules/customers/i18n/de.json +12 -2
- package/src/modules/customers/i18n/en.json +12 -2
- package/src/modules/customers/i18n/es.json +12 -2
- package/src/modules/customers/i18n/pl.json +12 -2
- package/src/modules/customers/lib/calendar/editorPayload.ts +94 -37
- package/src/modules/entities/backend/entities/user/[entityId]/page.tsx +1 -1
- package/src/modules/entities/i18n/de.json +120 -0
- package/src/modules/entities/i18n/en.json +120 -0
- package/src/modules/entities/i18n/es.json +120 -0
- package/src/modules/entities/i18n/pl.json +120 -0
- package/dist/modules/customers/components/calendar/editor/CategoryField.js +0 -75
- package/dist/modules/customers/components/calendar/editor/CategoryField.js.map +0 -7
- package/src/modules/customers/components/calendar/editor/CategoryField.tsx +0 -79
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
5
5
|
import { addDays } from "date-fns/addDays";
|
|
6
6
|
import { isSameDay } from "date-fns/isSameDay";
|
|
7
7
|
import { startOfDay } from "date-fns/startOfDay";
|
|
@@ -9,7 +9,6 @@ import { cn } from "@open-mercato/shared/lib/utils";
|
|
|
9
9
|
import { useLocale, useT } from "@open-mercato/shared/lib/i18n/context";
|
|
10
10
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
11
11
|
import { IconButton } from "@open-mercato/ui/primitives/icon-button";
|
|
12
|
-
import { EmptyState } from "@open-mercato/ui/primitives/empty-state";
|
|
13
12
|
import { packOverlaps } from "../../lib/calendar/layout.js";
|
|
14
13
|
import { getVisibleRange } from "../../lib/calendar/range.js";
|
|
15
14
|
import {
|
|
@@ -117,7 +116,6 @@ function TimeGrid({
|
|
|
117
116
|
onItemClick,
|
|
118
117
|
onJoin,
|
|
119
118
|
onNavigate,
|
|
120
|
-
onCreate,
|
|
121
119
|
onCreateRange
|
|
122
120
|
}) {
|
|
123
121
|
const t = useT();
|
|
@@ -216,197 +214,185 @@ function TimeGrid({
|
|
|
216
214
|
return null;
|
|
217
215
|
});
|
|
218
216
|
};
|
|
219
|
-
return /* @__PURE__ */
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
children: [
|
|
227
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
228
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
229
|
-
/* @__PURE__ */
|
|
230
|
-
|
|
231
|
-
/* @__PURE__ */ jsx("span", { className: "flex flex-1 items-center justify-center border-e border-border", children: /* @__PURE__ */ jsx(IconButton, { type: "button", variant: "ghost", size: "xs", "aria-label": nextLabel, onClick: () => onNavigate(days), children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true }) }) })
|
|
232
|
-
] }),
|
|
233
|
-
dayColumns.map(({ dayStart }) => {
|
|
234
|
-
const isToday = isSameDay(dayStart, today);
|
|
235
|
-
return /* @__PURE__ */ jsx(
|
|
236
|
-
"div",
|
|
237
|
-
{
|
|
238
|
-
className: cn(
|
|
239
|
-
"flex min-w-0 flex-1 items-center justify-center border-e border-border bg-muted px-1 py-2 last:border-e-0",
|
|
240
|
-
days === 7 && "min-w-[120px] max-md:max-w-[120px] md:min-w-0"
|
|
241
|
-
),
|
|
242
|
-
children: /* @__PURE__ */ jsx(
|
|
243
|
-
"span",
|
|
244
|
-
{
|
|
245
|
-
className: cn(
|
|
246
|
-
"truncate text-xs uppercase tracking-wide",
|
|
247
|
-
isToday ? "font-semibold text-foreground" : "font-medium text-muted-foreground"
|
|
248
|
-
),
|
|
249
|
-
children: headerLabelFor(dayStart)
|
|
250
|
-
}
|
|
251
|
-
)
|
|
252
|
-
},
|
|
253
|
-
dayStart.getTime()
|
|
254
|
-
);
|
|
255
|
-
})
|
|
217
|
+
return /* @__PURE__ */ jsx("div", { className: "relative flex flex-col overflow-hidden rounded-lg border border-border bg-card", children: /* @__PURE__ */ jsxs(
|
|
218
|
+
"div",
|
|
219
|
+
{
|
|
220
|
+
ref: scrollRef,
|
|
221
|
+
className: "overflow-auto overscroll-contain",
|
|
222
|
+
style: { maxHeight: GRID_BODY_MAX_HEIGHT_PX },
|
|
223
|
+
children: [
|
|
224
|
+
/* @__PURE__ */ jsxs("div", { className: "sticky top-0 z-30 min-w-full bg-card max-md:w-max", children: [
|
|
225
|
+
/* @__PURE__ */ jsxs("div", { className: "flex border-b border-border", children: [
|
|
226
|
+
/* @__PURE__ */ jsxs("div", { className: "sticky start-0 z-10 flex w-14 shrink-0 bg-card md:w-26", children: [
|
|
227
|
+
/* @__PURE__ */ jsx("span", { className: "flex flex-1 items-center justify-center border-e border-border", children: /* @__PURE__ */ jsx(IconButton, { type: "button", variant: "ghost", size: "xs", "aria-label": previousLabel, onClick: () => onNavigate(-days), children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": true }) }) }),
|
|
228
|
+
/* @__PURE__ */ jsx("span", { className: "flex flex-1 items-center justify-center border-e border-border", children: /* @__PURE__ */ jsx(IconButton, { type: "button", variant: "ghost", size: "xs", "aria-label": nextLabel, onClick: () => onNavigate(days), children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true }) }) })
|
|
256
229
|
] }),
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
230
|
+
dayColumns.map(({ dayStart }) => {
|
|
231
|
+
const isToday = isSameDay(dayStart, today);
|
|
232
|
+
return /* @__PURE__ */ jsx(
|
|
260
233
|
"div",
|
|
261
234
|
{
|
|
262
235
|
className: cn(
|
|
263
|
-
"min-w-0 flex-1
|
|
236
|
+
"flex min-w-0 flex-1 items-center justify-center border-e border-border bg-muted px-1 py-2 last:border-e-0",
|
|
264
237
|
days === 7 && "min-w-[120px] max-md:max-w-[120px] md:min-w-0"
|
|
265
238
|
),
|
|
266
|
-
children:
|
|
239
|
+
children: /* @__PURE__ */ jsx(
|
|
240
|
+
"span",
|
|
241
|
+
{
|
|
242
|
+
className: cn(
|
|
243
|
+
"truncate text-xs uppercase tracking-wide",
|
|
244
|
+
isToday ? "font-semibold text-foreground" : "font-medium text-muted-foreground"
|
|
245
|
+
),
|
|
246
|
+
children: headerLabelFor(dayStart)
|
|
247
|
+
}
|
|
248
|
+
)
|
|
249
|
+
},
|
|
250
|
+
dayStart.getTime()
|
|
251
|
+
);
|
|
252
|
+
})
|
|
253
|
+
] }),
|
|
254
|
+
hasAllDayLane ? /* @__PURE__ */ jsxs("div", { className: "flex border-b border-border", children: [
|
|
255
|
+
/* @__PURE__ */ jsx("div", { className: "sticky start-0 z-10 flex w-14 shrink-0 items-center justify-center border-e border-border bg-card py-1 md:w-26", children: /* @__PURE__ */ jsx("span", { className: "truncate text-overline uppercase tracking-wide text-muted-foreground", children: t("customers.calendar.grid.allDay", "All day") }) }),
|
|
256
|
+
dayColumns.map(({ dayStart, allDayItems }) => /* @__PURE__ */ jsx(
|
|
257
|
+
"div",
|
|
258
|
+
{
|
|
259
|
+
className: cn(
|
|
260
|
+
"min-w-0 flex-1 space-y-1 border-e border-border p-1 last:border-e-0",
|
|
261
|
+
days === 7 && "min-w-[120px] max-md:max-w-[120px] md:min-w-0"
|
|
262
|
+
),
|
|
263
|
+
children: allDayItems.map((item) => /* @__PURE__ */ jsx(
|
|
264
|
+
EventPeekPopover,
|
|
265
|
+
{
|
|
266
|
+
item,
|
|
267
|
+
open: selectedId === item.id,
|
|
268
|
+
joinUrl: resolveJoinUrl(item.location),
|
|
269
|
+
aiSummaries,
|
|
270
|
+
canManage,
|
|
271
|
+
onOpenChange: (open) => setSelectedId(open ? item.id : null),
|
|
272
|
+
onJoin,
|
|
273
|
+
onEdit: onItemClick,
|
|
274
|
+
children: /* @__PURE__ */ jsx(
|
|
275
|
+
AllDayChip,
|
|
276
|
+
{
|
|
277
|
+
item,
|
|
278
|
+
conflicted: showConflicts && conflictIds.has(item.id),
|
|
279
|
+
highlighted: highlightItemId === item.id,
|
|
280
|
+
selected: selectedId === item.id,
|
|
281
|
+
nowMs
|
|
282
|
+
}
|
|
283
|
+
)
|
|
284
|
+
},
|
|
285
|
+
item.id
|
|
286
|
+
))
|
|
287
|
+
},
|
|
288
|
+
dayStart.getTime()
|
|
289
|
+
))
|
|
290
|
+
] }) : null
|
|
291
|
+
] }),
|
|
292
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-full max-md:w-max", style: { height: HOURS_PER_DAY * HOUR_HEIGHT_PX }, children: [
|
|
293
|
+
/* @__PURE__ */ jsx("div", { className: "sticky start-0 z-10 w-14 shrink-0 border-e border-border bg-card md:w-26", children: /* @__PURE__ */ jsx("div", { className: "relative h-full", children: hourLabels.map(
|
|
294
|
+
(label, hour) => hour === 0 ? null : /* @__PURE__ */ jsx(
|
|
295
|
+
"span",
|
|
296
|
+
{
|
|
297
|
+
className: "absolute w-full -translate-y-1/2 px-1 text-center text-xs font-medium text-muted-foreground md:px-3 md:text-sm",
|
|
298
|
+
style: { top: hour * HOUR_HEIGHT_PX },
|
|
299
|
+
children: label
|
|
300
|
+
},
|
|
301
|
+
hour
|
|
302
|
+
)
|
|
303
|
+
) }) }),
|
|
304
|
+
dayColumns.map(({ dayStart, blocks }) => {
|
|
305
|
+
const nonWorking = isWeekendDay(dayStart);
|
|
306
|
+
const conflictCount = showConflicts ? blocks.filter((block) => conflictIds.has(block.item.id)).length : 0;
|
|
307
|
+
const dragActive = drag && drag.moved && drag.dayMs === dayStart.getTime();
|
|
308
|
+
const dragRange = dragActive ? buildDragRange(dayStart, drag.startMin, drag.endMin) : null;
|
|
309
|
+
const dragStartMinutes = dragRange ? (dragRange.start.getTime() - startOfDay(dragRange.start).getTime()) / 6e4 : 0;
|
|
310
|
+
const dragDurationMinutes = dragRange ? (dragRange.end.getTime() - dragRange.start.getTime()) / 6e4 : 0;
|
|
311
|
+
return /* @__PURE__ */ jsxs(
|
|
312
|
+
"div",
|
|
313
|
+
{
|
|
314
|
+
className: cn(
|
|
315
|
+
"relative min-w-0 flex-1 border-e border-border last:border-e-0",
|
|
316
|
+
days === 7 && "min-w-[120px] max-md:max-w-[120px] md:min-w-0"
|
|
317
|
+
),
|
|
318
|
+
title: nonWorking ? nonWorkingLabel : void 0,
|
|
319
|
+
children: [
|
|
320
|
+
nonWorking ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: nonWorkingLabel }) : null,
|
|
321
|
+
/* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "absolute inset-0", children: Array.from({ length: HOURS_PER_DAY }, (_, hour) => /* @__PURE__ */ jsx("div", { className: "relative h-30 border-b border-border", children: /* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 top-1/2 h-px bg-border/50" }) }, hour)) }),
|
|
322
|
+
nonWorking ? /* @__PURE__ */ jsx(
|
|
323
|
+
"div",
|
|
324
|
+
{
|
|
325
|
+
"aria-hidden": true,
|
|
326
|
+
className: "pointer-events-none absolute inset-0",
|
|
327
|
+
style: { backgroundImage: NON_WORKING_HATCH_BACKGROUND }
|
|
328
|
+
}
|
|
329
|
+
) : null,
|
|
330
|
+
canCreateRange ? /* @__PURE__ */ jsx(
|
|
331
|
+
"div",
|
|
332
|
+
{
|
|
333
|
+
className: "absolute inset-0 cursor-cell",
|
|
334
|
+
onPointerDown: (event) => beginDrag(event, dayStart),
|
|
335
|
+
onPointerMove: moveDrag,
|
|
336
|
+
onPointerUp: () => endDrag(dayStart),
|
|
337
|
+
onPointerCancel: () => setDrag(null),
|
|
338
|
+
"aria-hidden": true
|
|
339
|
+
}
|
|
340
|
+
) : null,
|
|
341
|
+
dragRange ? /* @__PURE__ */ jsxs(
|
|
342
|
+
"div",
|
|
343
|
+
{
|
|
344
|
+
"aria-hidden": true,
|
|
345
|
+
className: "pointer-events-none absolute z-30 flex flex-col gap-0.5 overflow-hidden rounded-md border-2 border-dashed border-foreground bg-accent-indigo/10 px-2 pt-1.5",
|
|
346
|
+
style: {
|
|
347
|
+
top: dragStartMinutes / 60 * HOUR_HEIGHT_PX,
|
|
348
|
+
height: Math.max(MIN_BLOCK_HEIGHT_PX, dragDurationMinutes / 60 * HOUR_HEIGHT_PX),
|
|
349
|
+
insetInlineStart: 8,
|
|
350
|
+
insetInlineEnd: 8
|
|
351
|
+
},
|
|
352
|
+
children: [
|
|
353
|
+
/* @__PURE__ */ jsx("span", { className: "text-overline font-semibold text-foreground", children: t("customers.calendar.actions.newEvent", "New event") }),
|
|
354
|
+
/* @__PURE__ */ jsx("span", { className: "text-overline text-muted-foreground", children: formatTimeRange(locale, dragRange.start, dragRange.end) })
|
|
355
|
+
]
|
|
356
|
+
}
|
|
357
|
+
) : null,
|
|
358
|
+
conflictCount > 0 ? /* @__PURE__ */ jsx(ConflictBadge, { count: conflictCount }) : null,
|
|
359
|
+
/* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-y-0", style: { insetInlineStart: 8, insetInlineEnd: 8 }, children: blocks.map((block) => /* @__PURE__ */ jsx(
|
|
267
360
|
EventPeekPopover,
|
|
268
361
|
{
|
|
269
|
-
item,
|
|
270
|
-
open: selectedId === item.id,
|
|
271
|
-
joinUrl: resolveJoinUrl(item.location),
|
|
362
|
+
item: block.item,
|
|
363
|
+
open: selectedId === block.item.id,
|
|
364
|
+
joinUrl: resolveJoinUrl(block.item.location),
|
|
272
365
|
aiSummaries,
|
|
273
366
|
canManage,
|
|
274
|
-
onOpenChange: (open) => setSelectedId(open ? item.id : null),
|
|
367
|
+
onOpenChange: (open) => setSelectedId(open ? block.item.id : null),
|
|
275
368
|
onJoin,
|
|
276
369
|
onEdit: onItemClick,
|
|
277
370
|
children: /* @__PURE__ */ jsx(
|
|
278
|
-
|
|
371
|
+
EventBlock,
|
|
279
372
|
{
|
|
280
|
-
item,
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
373
|
+
item: block.item,
|
|
374
|
+
top: block.top,
|
|
375
|
+
height: block.height,
|
|
376
|
+
insetInlineStart: block.insetInlineStart,
|
|
377
|
+
width: block.width,
|
|
378
|
+
conflicted: showConflicts && conflictIds.has(block.item.id),
|
|
379
|
+
highlighted: highlightItemId === block.item.id,
|
|
380
|
+
selected: selectedId === block.item.id,
|
|
284
381
|
nowMs
|
|
285
382
|
}
|
|
286
383
|
)
|
|
287
384
|
},
|
|
288
|
-
item.id
|
|
289
|
-
))
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
)
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
{
|
|
300
|
-
className: "absolute w-full -translate-y-1/2 px-1 text-center text-xs font-medium text-muted-foreground md:px-3 md:text-sm",
|
|
301
|
-
style: { top: hour * HOUR_HEIGHT_PX },
|
|
302
|
-
children: label
|
|
303
|
-
},
|
|
304
|
-
hour
|
|
305
|
-
)
|
|
306
|
-
) }) }),
|
|
307
|
-
dayColumns.map(({ dayStart, blocks }) => {
|
|
308
|
-
const nonWorking = isWeekendDay(dayStart);
|
|
309
|
-
const conflictCount = showConflicts ? blocks.filter((block) => conflictIds.has(block.item.id)).length : 0;
|
|
310
|
-
const dragActive = drag && drag.moved && drag.dayMs === dayStart.getTime();
|
|
311
|
-
const dragRange = dragActive ? buildDragRange(dayStart, drag.startMin, drag.endMin) : null;
|
|
312
|
-
const dragStartMinutes = dragRange ? (dragRange.start.getTime() - startOfDay(dragRange.start).getTime()) / 6e4 : 0;
|
|
313
|
-
const dragDurationMinutes = dragRange ? (dragRange.end.getTime() - dragRange.start.getTime()) / 6e4 : 0;
|
|
314
|
-
return /* @__PURE__ */ jsxs(
|
|
315
|
-
"div",
|
|
316
|
-
{
|
|
317
|
-
className: cn(
|
|
318
|
-
"relative min-w-0 flex-1 border-e border-border last:border-e-0",
|
|
319
|
-
days === 7 && "min-w-[120px] max-md:max-w-[120px] md:min-w-0"
|
|
320
|
-
),
|
|
321
|
-
title: nonWorking ? nonWorkingLabel : void 0,
|
|
322
|
-
children: [
|
|
323
|
-
nonWorking ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: nonWorkingLabel }) : null,
|
|
324
|
-
/* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "absolute inset-0", children: Array.from({ length: HOURS_PER_DAY }, (_, hour) => /* @__PURE__ */ jsx("div", { className: "relative h-30 border-b border-border", children: /* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 top-1/2 h-px bg-border/50" }) }, hour)) }),
|
|
325
|
-
nonWorking ? /* @__PURE__ */ jsx(
|
|
326
|
-
"div",
|
|
327
|
-
{
|
|
328
|
-
"aria-hidden": true,
|
|
329
|
-
className: "pointer-events-none absolute inset-0",
|
|
330
|
-
style: { backgroundImage: NON_WORKING_HATCH_BACKGROUND }
|
|
331
|
-
}
|
|
332
|
-
) : null,
|
|
333
|
-
canCreateRange ? /* @__PURE__ */ jsx(
|
|
334
|
-
"div",
|
|
335
|
-
{
|
|
336
|
-
className: "absolute inset-0 cursor-cell",
|
|
337
|
-
onPointerDown: (event) => beginDrag(event, dayStart),
|
|
338
|
-
onPointerMove: moveDrag,
|
|
339
|
-
onPointerUp: () => endDrag(dayStart),
|
|
340
|
-
onPointerCancel: () => setDrag(null),
|
|
341
|
-
"aria-hidden": true
|
|
342
|
-
}
|
|
343
|
-
) : null,
|
|
344
|
-
dragRange ? /* @__PURE__ */ jsxs(
|
|
345
|
-
"div",
|
|
346
|
-
{
|
|
347
|
-
"aria-hidden": true,
|
|
348
|
-
className: "pointer-events-none absolute z-30 flex flex-col gap-0.5 overflow-hidden rounded-md border-2 border-dashed border-foreground bg-accent-indigo/10 px-2 pt-1.5",
|
|
349
|
-
style: {
|
|
350
|
-
top: dragStartMinutes / 60 * HOUR_HEIGHT_PX,
|
|
351
|
-
height: Math.max(MIN_BLOCK_HEIGHT_PX, dragDurationMinutes / 60 * HOUR_HEIGHT_PX),
|
|
352
|
-
insetInlineStart: 8,
|
|
353
|
-
insetInlineEnd: 8
|
|
354
|
-
},
|
|
355
|
-
children: [
|
|
356
|
-
/* @__PURE__ */ jsx("span", { className: "text-overline font-semibold text-foreground", children: t("customers.calendar.actions.newEvent", "New event") }),
|
|
357
|
-
/* @__PURE__ */ jsx("span", { className: "text-overline text-muted-foreground", children: formatTimeRange(locale, dragRange.start, dragRange.end) })
|
|
358
|
-
]
|
|
359
|
-
}
|
|
360
|
-
) : null,
|
|
361
|
-
conflictCount > 0 ? /* @__PURE__ */ jsx(ConflictBadge, { count: conflictCount }) : null,
|
|
362
|
-
/* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-y-0", style: { insetInlineStart: 8, insetInlineEnd: 8 }, children: blocks.map((block) => /* @__PURE__ */ jsx(
|
|
363
|
-
EventPeekPopover,
|
|
364
|
-
{
|
|
365
|
-
item: block.item,
|
|
366
|
-
open: selectedId === block.item.id,
|
|
367
|
-
joinUrl: resolveJoinUrl(block.item.location),
|
|
368
|
-
aiSummaries,
|
|
369
|
-
canManage,
|
|
370
|
-
onOpenChange: (open) => setSelectedId(open ? block.item.id : null),
|
|
371
|
-
onJoin,
|
|
372
|
-
onEdit: onItemClick,
|
|
373
|
-
children: /* @__PURE__ */ jsx(
|
|
374
|
-
EventBlock,
|
|
375
|
-
{
|
|
376
|
-
item: block.item,
|
|
377
|
-
top: block.top,
|
|
378
|
-
height: block.height,
|
|
379
|
-
insetInlineStart: block.insetInlineStart,
|
|
380
|
-
width: block.width,
|
|
381
|
-
conflicted: showConflicts && conflictIds.has(block.item.id),
|
|
382
|
-
highlighted: highlightItemId === block.item.id,
|
|
383
|
-
selected: selectedId === block.item.id,
|
|
384
|
-
nowMs
|
|
385
|
-
}
|
|
386
|
-
)
|
|
387
|
-
},
|
|
388
|
-
`${block.item.id}-${block.top}`
|
|
389
|
-
)) })
|
|
390
|
-
]
|
|
391
|
-
},
|
|
392
|
-
dayStart.getTime()
|
|
393
|
-
);
|
|
394
|
-
})
|
|
395
|
-
] })
|
|
396
|
-
]
|
|
397
|
-
}
|
|
398
|
-
),
|
|
399
|
-
items.length === 0 ? /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 z-40 flex items-center justify-center p-6", children: /* @__PURE__ */ jsx(
|
|
400
|
-
EmptyState,
|
|
401
|
-
{
|
|
402
|
-
className: "pointer-events-auto bg-card/95 shadow-sm",
|
|
403
|
-
icon: /* @__PURE__ */ jsx(CalendarDays, { className: "h-6 w-6", "aria-hidden": true }),
|
|
404
|
-
title: days === 7 ? t("customers.calendar.empty.week", "Nothing scheduled this week") : t("customers.calendar.empty.day", "Nothing scheduled this day"),
|
|
405
|
-
description: t("customers.calendar.empty.description", "Plan a meeting, event or task to fill your week."),
|
|
406
|
-
actions: onCreate ? /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", onClick: onCreate, children: t("customers.calendar.actions.newEvent", "New event") }) : void 0
|
|
407
|
-
}
|
|
408
|
-
) }) : null
|
|
409
|
-
] });
|
|
385
|
+
`${block.item.id}-${block.top}`
|
|
386
|
+
)) })
|
|
387
|
+
]
|
|
388
|
+
},
|
|
389
|
+
dayStart.getTime()
|
|
390
|
+
);
|
|
391
|
+
})
|
|
392
|
+
] })
|
|
393
|
+
]
|
|
394
|
+
}
|
|
395
|
+
) });
|
|
410
396
|
}
|
|
411
397
|
export {
|
|
412
398
|
TimeGrid
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/customers/components/calendar/TimeGrid.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { CalendarDays, ChevronLeft, ChevronRight } from 'lucide-react'\nimport { addDays } from 'date-fns/addDays'\nimport { isSameDay } from 'date-fns/isSameDay'\nimport { startOfDay } from 'date-fns/startOfDay'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { EmptyState } from '@open-mercato/ui/primitives/empty-state'\nimport { packOverlaps } from '../../lib/calendar/layout'\nimport { getVisibleRange } from '../../lib/calendar/range'\nimport {\n applyWeekendVisibility,\n buildDragRange,\n DRAG_SNAP_MINUTES,\n isWeekendDay,\n offsetYToMinutes,\n} from '../../lib/calendar/grid'\nimport { EventBlock, formatTimeRange, resolveEventTone } from './EventBlock'\nimport { EventPeekPopover } from './EventPeekPopover'\nimport type { CalendarItem, TimeGridProps } from './types'\n\nconst HOUR_HEIGHT_PX = 120\nconst HOURS_PER_DAY = 24\nconst GRID_BODY_MAX_HEIGHT_PX = 654\nconst INITIAL_SCROLL_HOUR = 8\nconst BLOCK_VERTICAL_GAP_PX = 1\nconst MIN_BLOCK_HEIGHT_PX = 32\nconst PACKED_COLUMN_GAP_PX = 2\n\nconst NON_WORKING_HATCH_BACKGROUND =\n 'repeating-linear-gradient(45deg, transparent 0px, transparent 8px, var(--border) 8px, var(--border) 9px)'\n\ntype PositionedBlock = {\n item: CalendarItem\n top: number\n height: number\n insetInlineStart: string\n width: string\n}\n\ntype DayColumnData = {\n dayStart: Date\n allDayItems: CalendarItem[]\n blocks: PositionedBlock[]\n}\n\ntype DragState = { dayMs: number; startMin: number; endMin: number; moved: boolean }\n\nfunction buildDayColumn(dayStart: Date, items: CalendarItem[]): DayColumnData {\n const dayEnd = addDays(dayStart, 1)\n const dayStartMs = dayStart.getTime()\n const dayEndMs = dayEnd.getTime()\n const allDayItems: CalendarItem[] = []\n const segments: Array<{ original: CalendarItem; start: Date; end: Date }> = []\n\n for (const item of items) {\n const startMs = item.start.getTime()\n const endMs = item.end.getTime()\n if (startMs >= dayEndMs || endMs <= dayStartMs) continue\n if (item.allDay) {\n allDayItems.push(item)\n continue\n }\n segments.push({\n original: item,\n start: startMs < dayStartMs ? dayStart : item.start,\n end: endMs > dayEndMs ? dayEnd : item.end,\n })\n }\n\n allDayItems.sort((first, second) => first.start.getTime() - second.start.getTime())\n\n const clones = segments.map((segment) => ({ ...segment.original, start: segment.start, end: segment.end }))\n const originalByClone = new Map<CalendarItem, CalendarItem>()\n clones.forEach((clone, index) => originalByClone.set(clone, segments[index].original))\n\n const blocks: PositionedBlock[] = packOverlaps(clones).map(({ item: clone, column, columns }) => {\n const startMinutes = (clone.start.getTime() - dayStartMs) / 60000\n const durationMinutes = (clone.end.getTime() - clone.start.getTime()) / 60000\n const rawTop = (startMinutes / 60) * HOUR_HEIGHT_PX\n const rawHeight = (durationMinutes / 60) * HOUR_HEIGHT_PX\n const widthPct = 100 / columns\n return {\n item: originalByClone.get(clone) ?? clone,\n top: rawTop + BLOCK_VERTICAL_GAP_PX,\n height: Math.max(MIN_BLOCK_HEIGHT_PX, rawHeight - BLOCK_VERTICAL_GAP_PX * 2),\n insetInlineStart: `calc(${column * widthPct}% + ${column * PACKED_COLUMN_GAP_PX}px)`,\n width: `calc(${widthPct}% - ${((columns - 1) * PACKED_COLUMN_GAP_PX) / columns}px)`,\n }\n })\n\n return { dayStart, allDayItems, blocks }\n}\n\ntype ConflictBadgeProps = { count: number }\n\nfunction ConflictBadge({ count }: ConflictBadgeProps) {\n const t = useT()\n const label =\n count === 1\n ? t('customers.calendar.grid.conflictCount', '1 conflict')\n : t('customers.calendar.grid.conflictsCount', '{count} conflicts', { count })\n return (\n <span className=\"pointer-events-none absolute left-2 top-1 z-40 inline-flex items-center gap-1 rounded-full bg-status-error-bg px-2 py-0.5 text-overline font-medium uppercase tracking-wide text-status-error-text\">\n <span aria-hidden className=\"size-1.5 rounded-full bg-status-error-icon\" />\n {label}\n </span>\n )\n}\n\ntype AllDayChipProps = {\n item: CalendarItem\n conflicted: boolean\n highlighted: boolean\n selected: boolean\n nowMs: number\n} & Omit<React.ComponentProps<typeof Button>, 'style' | 'children'>\n\nconst AllDayChip = React.forwardRef<HTMLButtonElement, AllDayChipProps>(function AllDayChip(\n { item, conflicted, highlighted, selected, nowMs, className, ...buttonProps },\n ref,\n) {\n const t = useT()\n const tone = resolveEventTone(item, nowMs)\n const title = item.title || t('customers.calendar.grid.untitled', 'Untitled')\n return (\n <Button\n ref={ref}\n type=\"button\"\n variant=\"ghost\"\n aria-label={`${title}, ${t('customers.calendar.grid.allDay', 'All day')}`}\n className={cn(\n 'h-auto w-full min-w-0 justify-start rounded-sm px-2 py-0.5 text-start hover:bg-muted/70',\n tone.surfaceClassName,\n conflicted && 'ring-1 ring-status-warning-icon',\n selected && 'shadow-md ring-2 ring-foreground',\n highlighted && 'motion-safe:animate-pulse',\n 'focus-visible:ring-2 focus-visible:ring-ring',\n className,\n )}\n style={tone.style}\n {...buttonProps}\n >\n <span className={cn('truncate text-xs font-medium', tone.titleClassName)}>{title}</span>\n </Button>\n )\n})\n\nAllDayChip.displayName = 'AllDayChip'\n\nexport function TimeGrid({\n days,\n anchor,\n items,\n conflictIds,\n showWeekends,\n showConflicts,\n aiSummaries,\n canManage = true,\n highlightItemId,\n onItemClick,\n onJoin,\n onNavigate,\n onCreate,\n onCreateRange,\n}: TimeGridProps) {\n const t = useT()\n const locale = useLocale()\n const scrollRef = React.useRef<HTMLDivElement | null>(null)\n const nowMs = Date.now()\n const today = startOfDay(new Date())\n const todayMs = today.getTime()\n const anchorMs = anchor.getTime()\n const [selectedId, setSelectedId] = React.useState<string | null>(null)\n const [drag, setDrag] = React.useState<DragState | null>(null)\n\n const dayStarts = React.useMemo(() => {\n const rangeStart = getVisibleRange(days === 7 ? 'week' : 'day', new Date(anchorMs), 0).from\n const all = Array.from({ length: days }, (_, index) => addDays(rangeStart, index))\n return days === 7 ? applyWeekendVisibility(all, showWeekends, new Date(todayMs)) : all\n }, [days, anchorMs, showWeekends, todayMs])\n\n const dayColumns = React.useMemo(\n () => dayStarts.map((dayStart) => buildDayColumn(dayStart, items)),\n [dayStarts, items],\n )\n\n const resolveJoinUrl = React.useCallback((location: string | null): string | null => {\n const trimmed = location?.trim() ?? ''\n if (!trimmed) return null\n if (/^https?:\\/\\//i.test(trimmed)) return trimmed\n if (/^www\\./i.test(trimmed)) return `https://${trimmed}`\n return null\n }, [])\n\n const hasAllDayLane = dayColumns.some((column) => column.allDayItems.length > 0)\n\n const formatters = React.useMemo(\n () => ({\n dayNumber: new Intl.DateTimeFormat(locale, { day: '2-digit' }),\n weekdayShort: new Intl.DateTimeFormat(locale, { weekday: 'short' }),\n weekdayLong: new Intl.DateTimeFormat(locale, { weekday: 'long' }),\n }),\n [locale],\n )\n\n const hourLabels = React.useMemo(() => {\n const formatter = new Intl.DateTimeFormat(locale, { hour: 'numeric' })\n return Array.from({ length: HOURS_PER_DAY }, (_, hour) => formatter.format(new Date(2024, 0, 1, hour)))\n }, [locale])\n\n React.useEffect(() => {\n const node = scrollRef.current\n if (!node) return\n node.scrollTop = INITIAL_SCROLL_HOUR * HOUR_HEIGHT_PX\n }, [])\n\n React.useEffect(() => {\n if (!highlightItemId) return\n const node = scrollRef.current\n if (!node) return\n const target = items.find((item) => item.id === highlightItemId && !item.allDay)\n if (!target) return\n const minutes = (target.start.getTime() - startOfDay(target.start).getTime()) / 60000\n const top = (minutes / 60) * HOUR_HEIGHT_PX\n const reduceMotion =\n typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches\n node.scrollTo({ top: Math.max(0, top - HOUR_HEIGHT_PX), behavior: reduceMotion ? 'auto' : 'smooth' })\n }, [highlightItemId, items])\n\n const nonWorkingLabel = t('customers.calendar.grid.nonWorking', 'Non-working day')\n const previousLabel =\n days === 7\n ? t('customers.calendar.previousWeek', 'Previous week')\n : t('customers.calendar.grid.previousDay', 'Previous day')\n const nextLabel =\n days === 7 ? t('customers.calendar.nextWeek', 'Next week') : t('customers.calendar.grid.nextDay', 'Next day')\n\n const headerLabelFor = (dayStart: Date): string => {\n const dayNumber = formatters.dayNumber.format(dayStart)\n if (days === 1) return `${formatters.weekdayLong.format(dayStart).toUpperCase()} \u00B7 ${dayNumber}`\n return `${dayNumber} ${formatters.weekdayShort.format(dayStart).toUpperCase()}`\n }\n\n const canCreateRange = Boolean(onCreateRange)\n\n const beginDrag = (event: React.PointerEvent<HTMLDivElement>, dayStart: Date) => {\n if (!canCreateRange || event.button !== 0) return\n const layer = event.currentTarget\n const rect = layer.getBoundingClientRect()\n const minute = offsetYToMinutes(event.clientY - rect.top, HOUR_HEIGHT_PX)\n try {\n layer.setPointerCapture(event.pointerId)\n } catch {\n // Pointer capture is best-effort; ignore environments that reject it.\n }\n setSelectedId(null)\n setDrag({ dayMs: dayStart.getTime(), startMin: minute, endMin: minute, moved: false })\n }\n\n const moveDrag = (event: React.PointerEvent<HTMLDivElement>) => {\n // Read the layer rect synchronously: `event.currentTarget` is only valid during\n // event dispatch, but the setDrag updater below runs later during re-render.\n const rect = event.currentTarget.getBoundingClientRect()\n const minute = offsetYToMinutes(event.clientY - rect.top, HOUR_HEIGHT_PX)\n setDrag((previous) => {\n if (!previous) return previous\n return {\n ...previous,\n endMin: minute,\n moved: previous.moved || Math.abs(minute - previous.startMin) >= DRAG_SNAP_MINUTES,\n }\n })\n }\n\n const endDrag = (dayStart: Date) => {\n setDrag((previous) => {\n if (previous && previous.moved && onCreateRange) {\n const range = buildDragRange(dayStart, previous.startMin, previous.endMin)\n onCreateRange(range.start, range.end)\n }\n return null\n })\n }\n\n return (\n <div className=\"relative flex flex-col overflow-hidden rounded-lg border border-border bg-card\">\n <div\n ref={scrollRef}\n className=\"overflow-auto overscroll-contain\"\n style={{ maxHeight: GRID_BODY_MAX_HEIGHT_PX }}\n >\n <div className=\"sticky top-0 z-30 min-w-full bg-card max-md:w-max\">\n <div className=\"flex border-b border-border\">\n <div className=\"sticky start-0 z-10 flex w-14 shrink-0 bg-card md:w-26\">\n <span className=\"flex flex-1 items-center justify-center border-e border-border\">\n <IconButton type=\"button\" variant=\"ghost\" size=\"xs\" aria-label={previousLabel} onClick={() => onNavigate(-days)}>\n <ChevronLeft aria-hidden />\n </IconButton>\n </span>\n <span className=\"flex flex-1 items-center justify-center border-e border-border\">\n <IconButton type=\"button\" variant=\"ghost\" size=\"xs\" aria-label={nextLabel} onClick={() => onNavigate(days)}>\n <ChevronRight aria-hidden />\n </IconButton>\n </span>\n </div>\n {dayColumns.map(({ dayStart }) => {\n const isToday = isSameDay(dayStart, today)\n return (\n <div\n key={dayStart.getTime()}\n className={cn(\n 'flex min-w-0 flex-1 items-center justify-center border-e border-border bg-muted px-1 py-2 last:border-e-0',\n days === 7 && 'min-w-[120px] max-md:max-w-[120px] md:min-w-0',\n )}\n >\n <span\n className={cn(\n 'truncate text-xs uppercase tracking-wide',\n isToday ? 'font-semibold text-foreground' : 'font-medium text-muted-foreground',\n )}\n >\n {headerLabelFor(dayStart)}\n </span>\n </div>\n )\n })}\n </div>\n {hasAllDayLane ? (\n <div className=\"flex border-b border-border\">\n <div className=\"sticky start-0 z-10 flex w-14 shrink-0 items-center justify-center border-e border-border bg-card py-1 md:w-26\">\n <span className=\"truncate text-overline uppercase tracking-wide text-muted-foreground\">\n {t('customers.calendar.grid.allDay', 'All day')}\n </span>\n </div>\n {dayColumns.map(({ dayStart, allDayItems }) => (\n <div\n key={dayStart.getTime()}\n className={cn(\n 'min-w-0 flex-1 space-y-1 border-e border-border p-1 last:border-e-0',\n days === 7 && 'min-w-[120px] max-md:max-w-[120px] md:min-w-0',\n )}\n >\n {allDayItems.map((item) => (\n <EventPeekPopover\n key={item.id}\n item={item}\n open={selectedId === item.id}\n joinUrl={resolveJoinUrl(item.location)}\n aiSummaries={aiSummaries}\n canManage={canManage}\n onOpenChange={(open) => setSelectedId(open ? item.id : null)}\n onJoin={onJoin}\n onEdit={onItemClick}\n >\n <AllDayChip\n item={item}\n conflicted={showConflicts && conflictIds.has(item.id)}\n highlighted={highlightItemId === item.id}\n selected={selectedId === item.id}\n nowMs={nowMs}\n />\n </EventPeekPopover>\n ))}\n </div>\n ))}\n </div>\n ) : null}\n </div>\n <div className=\"flex min-w-full max-md:w-max\" style={{ height: HOURS_PER_DAY * HOUR_HEIGHT_PX }}>\n <div className=\"sticky start-0 z-10 w-14 shrink-0 border-e border-border bg-card md:w-26\">\n <div className=\"relative h-full\">\n {hourLabels.map((label, hour) =>\n hour === 0 ? null : (\n <span\n key={hour}\n className=\"absolute w-full -translate-y-1/2 px-1 text-center text-xs font-medium text-muted-foreground md:px-3 md:text-sm\"\n style={{ top: hour * HOUR_HEIGHT_PX }}\n >\n {label}\n </span>\n ),\n )}\n </div>\n </div>\n {dayColumns.map(({ dayStart, blocks }) => {\n const nonWorking = isWeekendDay(dayStart)\n const conflictCount = showConflicts\n ? blocks.filter((block) => conflictIds.has(block.item.id)).length\n : 0\n const dragActive = drag && drag.moved && drag.dayMs === dayStart.getTime()\n const dragRange = dragActive ? buildDragRange(dayStart, drag.startMin, drag.endMin) : null\n const dragStartMinutes = dragRange\n ? (dragRange.start.getTime() - startOfDay(dragRange.start).getTime()) / 60000\n : 0\n const dragDurationMinutes = dragRange\n ? (dragRange.end.getTime() - dragRange.start.getTime()) / 60000\n : 0\n return (\n <div\n key={dayStart.getTime()}\n className={cn(\n 'relative min-w-0 flex-1 border-e border-border last:border-e-0',\n days === 7 && 'min-w-[120px] max-md:max-w-[120px] md:min-w-0',\n )}\n title={nonWorking ? nonWorkingLabel : undefined}\n >\n {nonWorking ? <span className=\"sr-only\">{nonWorkingLabel}</span> : null}\n <div aria-hidden className=\"absolute inset-0\">\n {Array.from({ length: HOURS_PER_DAY }, (_, hour) => (\n <div key={hour} className=\"relative h-30 border-b border-border\">\n <span className=\"absolute inset-x-0 top-1/2 h-px bg-border/50\" />\n </div>\n ))}\n </div>\n {nonWorking ? (\n <div\n aria-hidden\n className=\"pointer-events-none absolute inset-0\"\n style={{ backgroundImage: NON_WORKING_HATCH_BACKGROUND }}\n />\n ) : null}\n {canCreateRange ? (\n <div\n className=\"absolute inset-0 cursor-cell\"\n onPointerDown={(event) => beginDrag(event, dayStart)}\n onPointerMove={moveDrag}\n onPointerUp={() => endDrag(dayStart)}\n onPointerCancel={() => setDrag(null)}\n aria-hidden\n />\n ) : null}\n {dragRange ? (\n <div\n aria-hidden\n className=\"pointer-events-none absolute z-30 flex flex-col gap-0.5 overflow-hidden rounded-md border-2 border-dashed border-foreground bg-accent-indigo/10 px-2 pt-1.5\"\n style={{\n top: (dragStartMinutes / 60) * HOUR_HEIGHT_PX,\n height: Math.max(MIN_BLOCK_HEIGHT_PX, (dragDurationMinutes / 60) * HOUR_HEIGHT_PX),\n insetInlineStart: 8,\n insetInlineEnd: 8,\n }}\n >\n <span className=\"text-overline font-semibold text-foreground\">\n {t('customers.calendar.actions.newEvent', 'New event')}\n </span>\n <span className=\"text-overline text-muted-foreground\">\n {formatTimeRange(locale, dragRange.start, dragRange.end)}\n </span>\n </div>\n ) : null}\n {conflictCount > 0 ? <ConflictBadge count={conflictCount} /> : null}\n {/* Click-through container so empty space reaches the drag-to-create layer\n below; each block re-enables pointer events for its own click/peek. */}\n <div className=\"pointer-events-none absolute inset-y-0\" style={{ insetInlineStart: 8, insetInlineEnd: 8 }}>\n {blocks.map((block) => (\n <EventPeekPopover\n key={`${block.item.id}-${block.top}`}\n item={block.item}\n open={selectedId === block.item.id}\n joinUrl={resolveJoinUrl(block.item.location)}\n aiSummaries={aiSummaries}\n canManage={canManage}\n onOpenChange={(open) => setSelectedId(open ? block.item.id : null)}\n onJoin={onJoin}\n onEdit={onItemClick}\n >\n <EventBlock\n item={block.item}\n top={block.top}\n height={block.height}\n insetInlineStart={block.insetInlineStart}\n width={block.width}\n conflicted={showConflicts && conflictIds.has(block.item.id)}\n highlighted={highlightItemId === block.item.id}\n selected={selectedId === block.item.id}\n nowMs={nowMs}\n />\n </EventPeekPopover>\n ))}\n </div>\n </div>\n )\n })}\n </div>\n </div>\n {items.length === 0 ? (\n <div className=\"pointer-events-none absolute inset-0 z-40 flex items-center justify-center p-6\">\n <EmptyState\n className=\"pointer-events-auto bg-card/95 shadow-sm\"\n icon={<CalendarDays className=\"h-6 w-6\" aria-hidden />}\n title={\n days === 7\n ? t('customers.calendar.empty.week', 'Nothing scheduled this week')\n : t('customers.calendar.empty.day', 'Nothing scheduled this day')\n }\n description={t('customers.calendar.empty.description', 'Plan a meeting, event or task to fill your week.')}\n actions={\n onCreate ? (\n <Button type=\"button\" size=\"sm\" onClick={onCreate}>\n {t('customers.calendar.actions.newEvent', 'New event')}\n </Button>\n ) : undefined\n }\n />\n </div>\n ) : null}\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\nimport { addDays } from 'date-fns/addDays'\nimport { isSameDay } from 'date-fns/isSameDay'\nimport { startOfDay } from 'date-fns/startOfDay'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { packOverlaps } from '../../lib/calendar/layout'\nimport { getVisibleRange } from '../../lib/calendar/range'\nimport {\n applyWeekendVisibility,\n buildDragRange,\n DRAG_SNAP_MINUTES,\n isWeekendDay,\n offsetYToMinutes,\n} from '../../lib/calendar/grid'\nimport { EventBlock, formatTimeRange, resolveEventTone } from './EventBlock'\nimport { EventPeekPopover } from './EventPeekPopover'\nimport type { CalendarItem, TimeGridProps } from './types'\n\nconst HOUR_HEIGHT_PX = 120\nconst HOURS_PER_DAY = 24\nconst GRID_BODY_MAX_HEIGHT_PX = 654\nconst INITIAL_SCROLL_HOUR = 8\nconst BLOCK_VERTICAL_GAP_PX = 1\nconst MIN_BLOCK_HEIGHT_PX = 32\nconst PACKED_COLUMN_GAP_PX = 2\n\nconst NON_WORKING_HATCH_BACKGROUND =\n 'repeating-linear-gradient(45deg, transparent 0px, transparent 8px, var(--border) 8px, var(--border) 9px)'\n\ntype PositionedBlock = {\n item: CalendarItem\n top: number\n height: number\n insetInlineStart: string\n width: string\n}\n\ntype DayColumnData = {\n dayStart: Date\n allDayItems: CalendarItem[]\n blocks: PositionedBlock[]\n}\n\ntype DragState = { dayMs: number; startMin: number; endMin: number; moved: boolean }\n\nfunction buildDayColumn(dayStart: Date, items: CalendarItem[]): DayColumnData {\n const dayEnd = addDays(dayStart, 1)\n const dayStartMs = dayStart.getTime()\n const dayEndMs = dayEnd.getTime()\n const allDayItems: CalendarItem[] = []\n const segments: Array<{ original: CalendarItem; start: Date; end: Date }> = []\n\n for (const item of items) {\n const startMs = item.start.getTime()\n const endMs = item.end.getTime()\n if (startMs >= dayEndMs || endMs <= dayStartMs) continue\n if (item.allDay) {\n allDayItems.push(item)\n continue\n }\n segments.push({\n original: item,\n start: startMs < dayStartMs ? dayStart : item.start,\n end: endMs > dayEndMs ? dayEnd : item.end,\n })\n }\n\n allDayItems.sort((first, second) => first.start.getTime() - second.start.getTime())\n\n const clones = segments.map((segment) => ({ ...segment.original, start: segment.start, end: segment.end }))\n const originalByClone = new Map<CalendarItem, CalendarItem>()\n clones.forEach((clone, index) => originalByClone.set(clone, segments[index].original))\n\n const blocks: PositionedBlock[] = packOverlaps(clones).map(({ item: clone, column, columns }) => {\n const startMinutes = (clone.start.getTime() - dayStartMs) / 60000\n const durationMinutes = (clone.end.getTime() - clone.start.getTime()) / 60000\n const rawTop = (startMinutes / 60) * HOUR_HEIGHT_PX\n const rawHeight = (durationMinutes / 60) * HOUR_HEIGHT_PX\n const widthPct = 100 / columns\n return {\n item: originalByClone.get(clone) ?? clone,\n top: rawTop + BLOCK_VERTICAL_GAP_PX,\n height: Math.max(MIN_BLOCK_HEIGHT_PX, rawHeight - BLOCK_VERTICAL_GAP_PX * 2),\n insetInlineStart: `calc(${column * widthPct}% + ${column * PACKED_COLUMN_GAP_PX}px)`,\n width: `calc(${widthPct}% - ${((columns - 1) * PACKED_COLUMN_GAP_PX) / columns}px)`,\n }\n })\n\n return { dayStart, allDayItems, blocks }\n}\n\ntype ConflictBadgeProps = { count: number }\n\nfunction ConflictBadge({ count }: ConflictBadgeProps) {\n const t = useT()\n const label =\n count === 1\n ? t('customers.calendar.grid.conflictCount', '1 conflict')\n : t('customers.calendar.grid.conflictsCount', '{count} conflicts', { count })\n return (\n <span className=\"pointer-events-none absolute left-2 top-1 z-40 inline-flex items-center gap-1 rounded-full bg-status-error-bg px-2 py-0.5 text-overline font-medium uppercase tracking-wide text-status-error-text\">\n <span aria-hidden className=\"size-1.5 rounded-full bg-status-error-icon\" />\n {label}\n </span>\n )\n}\n\ntype AllDayChipProps = {\n item: CalendarItem\n conflicted: boolean\n highlighted: boolean\n selected: boolean\n nowMs: number\n} & Omit<React.ComponentProps<typeof Button>, 'style' | 'children'>\n\nconst AllDayChip = React.forwardRef<HTMLButtonElement, AllDayChipProps>(function AllDayChip(\n { item, conflicted, highlighted, selected, nowMs, className, ...buttonProps },\n ref,\n) {\n const t = useT()\n const tone = resolveEventTone(item, nowMs)\n const title = item.title || t('customers.calendar.grid.untitled', 'Untitled')\n return (\n <Button\n ref={ref}\n type=\"button\"\n variant=\"ghost\"\n aria-label={`${title}, ${t('customers.calendar.grid.allDay', 'All day')}`}\n className={cn(\n 'h-auto w-full min-w-0 justify-start rounded-sm px-2 py-0.5 text-start hover:bg-muted/70',\n tone.surfaceClassName,\n conflicted && 'ring-1 ring-status-warning-icon',\n selected && 'shadow-md ring-2 ring-foreground',\n highlighted && 'motion-safe:animate-pulse',\n 'focus-visible:ring-2 focus-visible:ring-ring',\n className,\n )}\n style={tone.style}\n {...buttonProps}\n >\n <span className={cn('truncate text-xs font-medium', tone.titleClassName)}>{title}</span>\n </Button>\n )\n})\n\nAllDayChip.displayName = 'AllDayChip'\n\nexport function TimeGrid({\n days,\n anchor,\n items,\n conflictIds,\n showWeekends,\n showConflicts,\n aiSummaries,\n canManage = true,\n highlightItemId,\n onItemClick,\n onJoin,\n onNavigate,\n onCreateRange,\n}: TimeGridProps) {\n const t = useT()\n const locale = useLocale()\n const scrollRef = React.useRef<HTMLDivElement | null>(null)\n const nowMs = Date.now()\n const today = startOfDay(new Date())\n const todayMs = today.getTime()\n const anchorMs = anchor.getTime()\n const [selectedId, setSelectedId] = React.useState<string | null>(null)\n const [drag, setDrag] = React.useState<DragState | null>(null)\n\n const dayStarts = React.useMemo(() => {\n const rangeStart = getVisibleRange(days === 7 ? 'week' : 'day', new Date(anchorMs), 0).from\n const all = Array.from({ length: days }, (_, index) => addDays(rangeStart, index))\n return days === 7 ? applyWeekendVisibility(all, showWeekends, new Date(todayMs)) : all\n }, [days, anchorMs, showWeekends, todayMs])\n\n const dayColumns = React.useMemo(\n () => dayStarts.map((dayStart) => buildDayColumn(dayStart, items)),\n [dayStarts, items],\n )\n\n const resolveJoinUrl = React.useCallback((location: string | null): string | null => {\n const trimmed = location?.trim() ?? ''\n if (!trimmed) return null\n if (/^https?:\\/\\//i.test(trimmed)) return trimmed\n if (/^www\\./i.test(trimmed)) return `https://${trimmed}`\n return null\n }, [])\n\n const hasAllDayLane = dayColumns.some((column) => column.allDayItems.length > 0)\n\n const formatters = React.useMemo(\n () => ({\n dayNumber: new Intl.DateTimeFormat(locale, { day: '2-digit' }),\n weekdayShort: new Intl.DateTimeFormat(locale, { weekday: 'short' }),\n weekdayLong: new Intl.DateTimeFormat(locale, { weekday: 'long' }),\n }),\n [locale],\n )\n\n const hourLabels = React.useMemo(() => {\n const formatter = new Intl.DateTimeFormat(locale, { hour: 'numeric' })\n return Array.from({ length: HOURS_PER_DAY }, (_, hour) => formatter.format(new Date(2024, 0, 1, hour)))\n }, [locale])\n\n React.useEffect(() => {\n const node = scrollRef.current\n if (!node) return\n node.scrollTop = INITIAL_SCROLL_HOUR * HOUR_HEIGHT_PX\n }, [])\n\n React.useEffect(() => {\n if (!highlightItemId) return\n const node = scrollRef.current\n if (!node) return\n const target = items.find((item) => item.id === highlightItemId && !item.allDay)\n if (!target) return\n const minutes = (target.start.getTime() - startOfDay(target.start).getTime()) / 60000\n const top = (minutes / 60) * HOUR_HEIGHT_PX\n const reduceMotion =\n typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches\n node.scrollTo({ top: Math.max(0, top - HOUR_HEIGHT_PX), behavior: reduceMotion ? 'auto' : 'smooth' })\n }, [highlightItemId, items])\n\n const nonWorkingLabel = t('customers.calendar.grid.nonWorking', 'Non-working day')\n const previousLabel =\n days === 7\n ? t('customers.calendar.previousWeek', 'Previous week')\n : t('customers.calendar.grid.previousDay', 'Previous day')\n const nextLabel =\n days === 7 ? t('customers.calendar.nextWeek', 'Next week') : t('customers.calendar.grid.nextDay', 'Next day')\n\n const headerLabelFor = (dayStart: Date): string => {\n const dayNumber = formatters.dayNumber.format(dayStart)\n if (days === 1) return `${formatters.weekdayLong.format(dayStart).toUpperCase()} \u00B7 ${dayNumber}`\n return `${dayNumber} ${formatters.weekdayShort.format(dayStart).toUpperCase()}`\n }\n\n const canCreateRange = Boolean(onCreateRange)\n\n const beginDrag = (event: React.PointerEvent<HTMLDivElement>, dayStart: Date) => {\n if (!canCreateRange || event.button !== 0) return\n const layer = event.currentTarget\n const rect = layer.getBoundingClientRect()\n const minute = offsetYToMinutes(event.clientY - rect.top, HOUR_HEIGHT_PX)\n try {\n layer.setPointerCapture(event.pointerId)\n } catch {\n // Pointer capture is best-effort; ignore environments that reject it.\n }\n setSelectedId(null)\n setDrag({ dayMs: dayStart.getTime(), startMin: minute, endMin: minute, moved: false })\n }\n\n const moveDrag = (event: React.PointerEvent<HTMLDivElement>) => {\n // Read the layer rect synchronously: `event.currentTarget` is only valid during\n // event dispatch, but the setDrag updater below runs later during re-render.\n const rect = event.currentTarget.getBoundingClientRect()\n const minute = offsetYToMinutes(event.clientY - rect.top, HOUR_HEIGHT_PX)\n setDrag((previous) => {\n if (!previous) return previous\n return {\n ...previous,\n endMin: minute,\n moved: previous.moved || Math.abs(minute - previous.startMin) >= DRAG_SNAP_MINUTES,\n }\n })\n }\n\n const endDrag = (dayStart: Date) => {\n setDrag((previous) => {\n if (previous && previous.moved && onCreateRange) {\n const range = buildDragRange(dayStart, previous.startMin, previous.endMin)\n onCreateRange(range.start, range.end)\n }\n return null\n })\n }\n\n return (\n <div className=\"relative flex flex-col overflow-hidden rounded-lg border border-border bg-card\">\n <div\n ref={scrollRef}\n className=\"overflow-auto overscroll-contain\"\n style={{ maxHeight: GRID_BODY_MAX_HEIGHT_PX }}\n >\n <div className=\"sticky top-0 z-30 min-w-full bg-card max-md:w-max\">\n <div className=\"flex border-b border-border\">\n <div className=\"sticky start-0 z-10 flex w-14 shrink-0 bg-card md:w-26\">\n <span className=\"flex flex-1 items-center justify-center border-e border-border\">\n <IconButton type=\"button\" variant=\"ghost\" size=\"xs\" aria-label={previousLabel} onClick={() => onNavigate(-days)}>\n <ChevronLeft aria-hidden />\n </IconButton>\n </span>\n <span className=\"flex flex-1 items-center justify-center border-e border-border\">\n <IconButton type=\"button\" variant=\"ghost\" size=\"xs\" aria-label={nextLabel} onClick={() => onNavigate(days)}>\n <ChevronRight aria-hidden />\n </IconButton>\n </span>\n </div>\n {dayColumns.map(({ dayStart }) => {\n const isToday = isSameDay(dayStart, today)\n return (\n <div\n key={dayStart.getTime()}\n className={cn(\n 'flex min-w-0 flex-1 items-center justify-center border-e border-border bg-muted px-1 py-2 last:border-e-0',\n days === 7 && 'min-w-[120px] max-md:max-w-[120px] md:min-w-0',\n )}\n >\n <span\n className={cn(\n 'truncate text-xs uppercase tracking-wide',\n isToday ? 'font-semibold text-foreground' : 'font-medium text-muted-foreground',\n )}\n >\n {headerLabelFor(dayStart)}\n </span>\n </div>\n )\n })}\n </div>\n {hasAllDayLane ? (\n <div className=\"flex border-b border-border\">\n <div className=\"sticky start-0 z-10 flex w-14 shrink-0 items-center justify-center border-e border-border bg-card py-1 md:w-26\">\n <span className=\"truncate text-overline uppercase tracking-wide text-muted-foreground\">\n {t('customers.calendar.grid.allDay', 'All day')}\n </span>\n </div>\n {dayColumns.map(({ dayStart, allDayItems }) => (\n <div\n key={dayStart.getTime()}\n className={cn(\n 'min-w-0 flex-1 space-y-1 border-e border-border p-1 last:border-e-0',\n days === 7 && 'min-w-[120px] max-md:max-w-[120px] md:min-w-0',\n )}\n >\n {allDayItems.map((item) => (\n <EventPeekPopover\n key={item.id}\n item={item}\n open={selectedId === item.id}\n joinUrl={resolveJoinUrl(item.location)}\n aiSummaries={aiSummaries}\n canManage={canManage}\n onOpenChange={(open) => setSelectedId(open ? item.id : null)}\n onJoin={onJoin}\n onEdit={onItemClick}\n >\n <AllDayChip\n item={item}\n conflicted={showConflicts && conflictIds.has(item.id)}\n highlighted={highlightItemId === item.id}\n selected={selectedId === item.id}\n nowMs={nowMs}\n />\n </EventPeekPopover>\n ))}\n </div>\n ))}\n </div>\n ) : null}\n </div>\n <div className=\"flex min-w-full max-md:w-max\" style={{ height: HOURS_PER_DAY * HOUR_HEIGHT_PX }}>\n <div className=\"sticky start-0 z-10 w-14 shrink-0 border-e border-border bg-card md:w-26\">\n <div className=\"relative h-full\">\n {hourLabels.map((label, hour) =>\n hour === 0 ? null : (\n <span\n key={hour}\n className=\"absolute w-full -translate-y-1/2 px-1 text-center text-xs font-medium text-muted-foreground md:px-3 md:text-sm\"\n style={{ top: hour * HOUR_HEIGHT_PX }}\n >\n {label}\n </span>\n ),\n )}\n </div>\n </div>\n {dayColumns.map(({ dayStart, blocks }) => {\n const nonWorking = isWeekendDay(dayStart)\n const conflictCount = showConflicts\n ? blocks.filter((block) => conflictIds.has(block.item.id)).length\n : 0\n const dragActive = drag && drag.moved && drag.dayMs === dayStart.getTime()\n const dragRange = dragActive ? buildDragRange(dayStart, drag.startMin, drag.endMin) : null\n const dragStartMinutes = dragRange\n ? (dragRange.start.getTime() - startOfDay(dragRange.start).getTime()) / 60000\n : 0\n const dragDurationMinutes = dragRange\n ? (dragRange.end.getTime() - dragRange.start.getTime()) / 60000\n : 0\n return (\n <div\n key={dayStart.getTime()}\n className={cn(\n 'relative min-w-0 flex-1 border-e border-border last:border-e-0',\n days === 7 && 'min-w-[120px] max-md:max-w-[120px] md:min-w-0',\n )}\n title={nonWorking ? nonWorkingLabel : undefined}\n >\n {nonWorking ? <span className=\"sr-only\">{nonWorkingLabel}</span> : null}\n <div aria-hidden className=\"absolute inset-0\">\n {Array.from({ length: HOURS_PER_DAY }, (_, hour) => (\n <div key={hour} className=\"relative h-30 border-b border-border\">\n <span className=\"absolute inset-x-0 top-1/2 h-px bg-border/50\" />\n </div>\n ))}\n </div>\n {nonWorking ? (\n <div\n aria-hidden\n className=\"pointer-events-none absolute inset-0\"\n style={{ backgroundImage: NON_WORKING_HATCH_BACKGROUND }}\n />\n ) : null}\n {canCreateRange ? (\n <div\n className=\"absolute inset-0 cursor-cell\"\n onPointerDown={(event) => beginDrag(event, dayStart)}\n onPointerMove={moveDrag}\n onPointerUp={() => endDrag(dayStart)}\n onPointerCancel={() => setDrag(null)}\n aria-hidden\n />\n ) : null}\n {dragRange ? (\n <div\n aria-hidden\n className=\"pointer-events-none absolute z-30 flex flex-col gap-0.5 overflow-hidden rounded-md border-2 border-dashed border-foreground bg-accent-indigo/10 px-2 pt-1.5\"\n style={{\n top: (dragStartMinutes / 60) * HOUR_HEIGHT_PX,\n height: Math.max(MIN_BLOCK_HEIGHT_PX, (dragDurationMinutes / 60) * HOUR_HEIGHT_PX),\n insetInlineStart: 8,\n insetInlineEnd: 8,\n }}\n >\n <span className=\"text-overline font-semibold text-foreground\">\n {t('customers.calendar.actions.newEvent', 'New event')}\n </span>\n <span className=\"text-overline text-muted-foreground\">\n {formatTimeRange(locale, dragRange.start, dragRange.end)}\n </span>\n </div>\n ) : null}\n {conflictCount > 0 ? <ConflictBadge count={conflictCount} /> : null}\n {/* Click-through container so empty space reaches the drag-to-create layer\n below; each block re-enables pointer events for its own click/peek. */}\n <div className=\"pointer-events-none absolute inset-y-0\" style={{ insetInlineStart: 8, insetInlineEnd: 8 }}>\n {blocks.map((block) => (\n <EventPeekPopover\n key={`${block.item.id}-${block.top}`}\n item={block.item}\n open={selectedId === block.item.id}\n joinUrl={resolveJoinUrl(block.item.location)}\n aiSummaries={aiSummaries}\n canManage={canManage}\n onOpenChange={(open) => setSelectedId(open ? block.item.id : null)}\n onJoin={onJoin}\n onEdit={onItemClick}\n >\n <EventBlock\n item={block.item}\n top={block.top}\n height={block.height}\n insetInlineStart={block.insetInlineStart}\n width={block.width}\n conflicted={showConflicts && conflictIds.has(block.item.id)}\n highlighted={highlightItemId === block.item.id}\n selected={selectedId === block.item.id}\n nowMs={nowMs}\n />\n </EventPeekPopover>\n ))}\n </div>\n </div>\n )\n })}\n </div>\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["AllDayChip"]
|
|
7
7
|
}
|