@open-mercato/core 0.6.4-develop.4106.1.12c205a613 → 0.6.4-develop.4110.1.836aafde58
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/planner/components/AvailabilityRulesEditor.js +39 -26
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/planner/components/availabilityRulesEditorState.js +8 -0
- package/dist/modules/planner/components/availabilityRulesEditorState.js.map +7 -0
- package/package.json +7 -7
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +40 -26
- package/src/modules/planner/components/availabilityRulesEditorState.ts +11 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -29,6 +29,7 @@ import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
|
|
|
29
29
|
import { parseAvailabilityRuleWindow } from "@open-mercato/core/modules/planner/lib/availabilitySchedule";
|
|
30
30
|
import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
|
|
31
31
|
import { Calendar, Clock, List, PencilLine, Plus, Trash2 } from "lucide-react";
|
|
32
|
+
import { resolveRuleSetSelectValue } from "./availabilityRulesEditorState.js";
|
|
32
33
|
const DAY_LABELS = [
|
|
33
34
|
{ code: "SU", short: "S", nameKey: "schedule.weekday.sunday", fallback: "Sunday" },
|
|
34
35
|
{ code: "MO", short: "M", nameKey: "schedule.weekday.monday", fallback: "Monday" },
|
|
@@ -313,6 +314,7 @@ function AvailabilityRulesEditor({
|
|
|
313
314
|
const [createRuleSetOpen, setCreateRuleSetOpen] = React.useState(false);
|
|
314
315
|
const [isWeeklyAutoSaving, setIsWeeklyAutoSaving] = React.useState(false);
|
|
315
316
|
const [customOverridesEnabled, setCustomOverridesEnabled] = React.useState(false);
|
|
317
|
+
const [selectedRulesetId, setSelectedRulesetId] = React.useState(rulesetId ?? null);
|
|
316
318
|
const autoSaveTimerRef = React.useRef(null);
|
|
317
319
|
const lastSavedWeeklyKeyRef = React.useRef(null);
|
|
318
320
|
const weeklySaveStateRef = React.useRef({ inFlight: false, queued: false });
|
|
@@ -321,7 +323,11 @@ function AvailabilityRulesEditor({
|
|
|
321
323
|
const viewModeRef = React.useRef(viewMode);
|
|
322
324
|
const saveWeeklyRef = React.useRef(null);
|
|
323
325
|
const timezoneOptions = React.useMemo(() => getTimezoneOptions(), []);
|
|
324
|
-
|
|
326
|
+
React.useEffect(() => {
|
|
327
|
+
setSelectedRulesetId(rulesetId ?? null);
|
|
328
|
+
}, [rulesetId]);
|
|
329
|
+
const effectiveRulesetId = selectedRulesetId;
|
|
330
|
+
const usingRuleSet = Boolean(effectiveRulesetId) && availabilityRules.length === 0 && !customOverridesEnabled;
|
|
325
331
|
const activeRules = usingRuleSet ? rulesetRules : availabilityRules;
|
|
326
332
|
const scheduleRules = React.useMemo(() => {
|
|
327
333
|
const dateBlockers = /* @__PURE__ */ new Set();
|
|
@@ -455,7 +461,7 @@ function AvailabilityRulesEditor({
|
|
|
455
461
|
}
|
|
456
462
|
}, [labelPrefix, subjectId, subjectType, t]);
|
|
457
463
|
const refreshRuleSetRules = React.useCallback(async () => {
|
|
458
|
-
if (!
|
|
464
|
+
if (!effectiveRulesetId) {
|
|
459
465
|
setRulesetRules([]);
|
|
460
466
|
return;
|
|
461
467
|
}
|
|
@@ -464,7 +470,7 @@ function AvailabilityRulesEditor({
|
|
|
464
470
|
page: "1",
|
|
465
471
|
pageSize: "100",
|
|
466
472
|
subjectType: "ruleset",
|
|
467
|
-
subjectIds:
|
|
473
|
+
subjectIds: effectiveRulesetId
|
|
468
474
|
});
|
|
469
475
|
const call = await apiCall(`/api/planner/availability?${params.toString()}`);
|
|
470
476
|
const items = Array.isArray(call.result?.items) ? call.result.items : [];
|
|
@@ -472,7 +478,7 @@ function AvailabilityRulesEditor({
|
|
|
472
478
|
} catch {
|
|
473
479
|
setRulesetRules([]);
|
|
474
480
|
}
|
|
475
|
-
}, [
|
|
481
|
+
}, [effectiveRulesetId]);
|
|
476
482
|
const refreshRuleSets = React.useCallback(async () => {
|
|
477
483
|
if (!onRulesetChange) return;
|
|
478
484
|
setRuleSetsLoading(true);
|
|
@@ -550,20 +556,20 @@ function AvailabilityRulesEditor({
|
|
|
550
556
|
}, [activeRules, initialTimezone, timezoneDirty]);
|
|
551
557
|
React.useEffect(() => {
|
|
552
558
|
if (timezoneDirty) return;
|
|
553
|
-
if (!usingRuleSet || !
|
|
554
|
-
const ruleset = ruleSets.find((entry) => entry.id ===
|
|
559
|
+
if (!usingRuleSet || !effectiveRulesetId) return;
|
|
560
|
+
const ruleset = ruleSets.find((entry) => entry.id === effectiveRulesetId);
|
|
555
561
|
if (ruleset?.timezone) setTimezone(ruleset.timezone);
|
|
556
|
-
}, [
|
|
562
|
+
}, [effectiveRulesetId, ruleSets, timezoneDirty, usingRuleSet]);
|
|
557
563
|
React.useEffect(() => {
|
|
558
564
|
if (availabilityRules.length > 0) {
|
|
559
565
|
setCustomOverridesEnabled(true);
|
|
560
566
|
}
|
|
561
567
|
}, [availabilityRules.length]);
|
|
562
568
|
React.useEffect(() => {
|
|
563
|
-
if (!
|
|
569
|
+
if (!effectiveRulesetId) {
|
|
564
570
|
setCustomOverridesEnabled(false);
|
|
565
571
|
}
|
|
566
|
-
}, [
|
|
572
|
+
}, [effectiveRulesetId]);
|
|
567
573
|
const refreshBookedEvents = React.useCallback(async () => {
|
|
568
574
|
if (!loadBookedEvents) return;
|
|
569
575
|
setBookedLoading(true);
|
|
@@ -647,7 +653,7 @@ function AvailabilityRulesEditor({
|
|
|
647
653
|
const saveWeeklyHours = React.useCallback(async (options) => {
|
|
648
654
|
if (isReadOnly) return;
|
|
649
655
|
const subjectForRules = usingRuleSet ? "ruleset" : subjectType;
|
|
650
|
-
const subjectIdForRules = usingRuleSet ?
|
|
656
|
+
const subjectIdForRules = usingRuleSet ? effectiveRulesetId ?? "" : subjectId;
|
|
651
657
|
if (!subjectIdForRules) return;
|
|
652
658
|
if (weeklyHasErrors) return;
|
|
653
659
|
const shouldSkipRefresh = Boolean(options?.skipRefresh);
|
|
@@ -684,7 +690,7 @@ function AvailabilityRulesEditor({
|
|
|
684
690
|
listLabels.saveWeeklySuccess,
|
|
685
691
|
refreshAvailability,
|
|
686
692
|
refreshRuleSetRules,
|
|
687
|
-
|
|
693
|
+
effectiveRulesetId,
|
|
688
694
|
subjectId,
|
|
689
695
|
subjectType,
|
|
690
696
|
timezone,
|
|
@@ -734,7 +740,7 @@ function AvailabilityRulesEditor({
|
|
|
734
740
|
if (isReadOnly) return;
|
|
735
741
|
if (timezoneSaveInFlightRef.current) return;
|
|
736
742
|
const trimmedTimezone = nextTimezone.trim() || "UTC";
|
|
737
|
-
const rulesetTimezoneId = subjectType === "ruleset" ? subjectId :
|
|
743
|
+
const rulesetTimezoneId = subjectType === "ruleset" ? subjectId : effectiveRulesetId;
|
|
738
744
|
const rulesToUpdate = activeRules.filter((rule) => rule.timezone !== trimmedTimezone);
|
|
739
745
|
if (!rulesToUpdate.length && !rulesetTimezoneId) {
|
|
740
746
|
setTimezoneDirty(false);
|
|
@@ -773,7 +779,7 @@ function AvailabilityRulesEditor({
|
|
|
773
779
|
listLabels.timezoneSaveError,
|
|
774
780
|
refreshAvailability,
|
|
775
781
|
refreshRuleSetRules,
|
|
776
|
-
|
|
782
|
+
effectiveRulesetId,
|
|
777
783
|
subjectId,
|
|
778
784
|
subjectType,
|
|
779
785
|
isReadOnly
|
|
@@ -802,7 +808,7 @@ function AvailabilityRulesEditor({
|
|
|
802
808
|
}, [canManageUnavailability, isReadOnly]);
|
|
803
809
|
const handleCustomize = React.useCallback(async () => {
|
|
804
810
|
if (isReadOnly) return;
|
|
805
|
-
if (!
|
|
811
|
+
if (!effectiveRulesetId) return;
|
|
806
812
|
try {
|
|
807
813
|
const creations = rulesetRules.map((rule) => createCrud("planner/availability", {
|
|
808
814
|
subjectType,
|
|
@@ -820,10 +826,10 @@ function AvailabilityRulesEditor({
|
|
|
820
826
|
const message = error2 instanceof Error ? error2.message : listLabels.saveWeeklyError;
|
|
821
827
|
flash(message, "error");
|
|
822
828
|
}
|
|
823
|
-
}, [listLabels.saveWeeklyError, refreshAvailability,
|
|
829
|
+
}, [effectiveRulesetId, listLabels.saveWeeklyError, refreshAvailability, rulesetRules, subjectId, subjectType, isReadOnly]);
|
|
824
830
|
const handleResetToRuleSet = React.useCallback(async () => {
|
|
825
831
|
if (isReadOnly) return;
|
|
826
|
-
if (!
|
|
832
|
+
if (!effectiveRulesetId) return;
|
|
827
833
|
try {
|
|
828
834
|
await Promise.all(
|
|
829
835
|
availabilityRules.map((rule) => deleteCrud("planner/availability", rule.id, { errorMessage: listLabels.saveWeeklyError }))
|
|
@@ -834,11 +840,11 @@ function AvailabilityRulesEditor({
|
|
|
834
840
|
const message = error2 instanceof Error ? error2.message : listLabels.saveWeeklyError;
|
|
835
841
|
flash(message, "error");
|
|
836
842
|
}
|
|
837
|
-
}, [availabilityRules, listLabels.saveWeeklyError, refreshAvailability,
|
|
843
|
+
}, [availabilityRules, effectiveRulesetId, listLabels.saveWeeklyError, refreshAvailability, isReadOnly]);
|
|
838
844
|
const handleRuleSetChange = React.useCallback(async (nextId) => {
|
|
839
845
|
if (isReadOnly) return;
|
|
840
846
|
if (!onRulesetChange) return;
|
|
841
|
-
if (availabilityRules.length > 0 && nextId !==
|
|
847
|
+
if (availabilityRules.length > 0 && nextId !== effectiveRulesetId) {
|
|
842
848
|
const confirmed = await confirm({
|
|
843
849
|
title: listLabels.ruleSetConfirm,
|
|
844
850
|
variant: "default"
|
|
@@ -848,17 +854,23 @@ function AvailabilityRulesEditor({
|
|
|
848
854
|
availabilityRules.map((rule) => deleteCrud("planner/availability", rule.id, { errorMessage: listLabels.saveWeeklyError }))
|
|
849
855
|
);
|
|
850
856
|
}
|
|
857
|
+
setSelectedRulesetId(nextId);
|
|
851
858
|
setCustomOverridesEnabled(false);
|
|
852
|
-
|
|
853
|
-
|
|
859
|
+
try {
|
|
860
|
+
await onRulesetChange(nextId);
|
|
861
|
+
await refreshAvailability();
|
|
862
|
+
} catch (error2) {
|
|
863
|
+
setSelectedRulesetId(effectiveRulesetId);
|
|
864
|
+
throw error2;
|
|
865
|
+
}
|
|
854
866
|
}, [
|
|
855
867
|
availabilityRules,
|
|
856
868
|
confirm,
|
|
869
|
+
effectiveRulesetId,
|
|
857
870
|
listLabels.ruleSetConfirm,
|
|
858
871
|
listLabels.saveWeeklyError,
|
|
859
872
|
onRulesetChange,
|
|
860
873
|
refreshAvailability,
|
|
861
|
-
rulesetId,
|
|
862
874
|
isReadOnly
|
|
863
875
|
]);
|
|
864
876
|
const ruleSetFormSchema = React.useMemo(
|
|
@@ -927,6 +939,7 @@ function AvailabilityRulesEditor({
|
|
|
927
939
|
}
|
|
928
940
|
await refreshRuleSets();
|
|
929
941
|
if (onRulesetChange) {
|
|
942
|
+
setSelectedRulesetId(id);
|
|
930
943
|
await onRulesetChange(id);
|
|
931
944
|
await refreshAvailability();
|
|
932
945
|
}
|
|
@@ -1015,7 +1028,7 @@ function AvailabilityRulesEditor({
|
|
|
1015
1028
|
if (isReadOnly) return;
|
|
1016
1029
|
if (editorUnavailable && !canManageUnavailability) return;
|
|
1017
1030
|
const subjectForRules = usingRuleSet ? "ruleset" : subjectType;
|
|
1018
|
-
const subjectIdForRules = usingRuleSet ?
|
|
1031
|
+
const subjectIdForRules = usingRuleSet ? effectiveRulesetId ?? "" : subjectId;
|
|
1019
1032
|
if (!subjectIdForRules) return;
|
|
1020
1033
|
if (!editorUnavailable && editorWindowErrors.some(Boolean)) return;
|
|
1021
1034
|
const validWindows = editorWindows;
|
|
@@ -1091,7 +1104,7 @@ function AvailabilityRulesEditor({
|
|
|
1091
1104
|
refreshAvailability,
|
|
1092
1105
|
refreshRuleSetRules,
|
|
1093
1106
|
reasonEntriesById,
|
|
1094
|
-
|
|
1107
|
+
effectiveRulesetId,
|
|
1095
1108
|
subjectId,
|
|
1096
1109
|
subjectType,
|
|
1097
1110
|
timezone,
|
|
@@ -1163,7 +1176,7 @@ function AvailabilityRulesEditor({
|
|
|
1163
1176
|
ruleSetsLoading ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: listLabels.ruleSetLoading }) : /* @__PURE__ */ jsxs(
|
|
1164
1177
|
Select,
|
|
1165
1178
|
{
|
|
1166
|
-
value:
|
|
1179
|
+
value: resolveRuleSetSelectValue(ruleSets, effectiveRulesetId),
|
|
1167
1180
|
onValueChange: (value) => {
|
|
1168
1181
|
void handleRuleSetChange(value ? value : null);
|
|
1169
1182
|
},
|
|
@@ -1178,8 +1191,8 @@ function AvailabilityRulesEditor({
|
|
|
1178
1191
|
/* @__PURE__ */ jsx(Plus, { className: "size-4 mr-2", "aria-hidden": true }),
|
|
1179
1192
|
listLabels.ruleSetCreateLabel
|
|
1180
1193
|
] }),
|
|
1181
|
-
|
|
1182
|
-
|
|
1194
|
+
effectiveRulesetId && usingRuleSet ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: handleCustomize, disabled: isReadOnly, children: listLabels.ruleSetCustomize }) : null,
|
|
1195
|
+
effectiveRulesetId && !usingRuleSet ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: handleResetToRuleSet, disabled: isReadOnly, children: listLabels.ruleSetReset }) : null
|
|
1183
1196
|
] }) : null,
|
|
1184
1197
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
1185
1198
|
/* @__PURE__ */ jsx("span", { children: listLabels.timezoneLabel }),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/planner/components/AvailabilityRulesEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { ScheduleView, type ScheduleItem, type ScheduleRange, type ScheduleSlot, type ScheduleViewMode } from '@open-mercato/ui/backend/schedule'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '@open-mercato/ui/primitives/dialog'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'\nimport { apiCall, apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { createCrud, deleteCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { ComboboxInput, TimePicker } from '@open-mercato/ui/backend/inputs'\nimport { DictionaryEntrySelect, type DictionarySelectLabels } from '@open-mercato/core/modules/dictionaries/components/DictionaryEntrySelect'\nimport {\n createUnavailabilityReasonEntry,\n loadUnavailabilityReasonEntries,\n type UnavailabilityReasonEntry,\n} from '@open-mercato/core/modules/planner/components/unavailabilityReasons'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { parseAvailabilityRuleWindow } from '@open-mercato/core/modules/planner/lib/availabilitySchedule'\nimport { CrudForm, type CrudField } from '@open-mercato/ui/backend/CrudForm'\nimport { Calendar, Clock, List, PencilLine, Plus, Trash2 } from 'lucide-react'\n\ntype AvailabilityRepeat = 'once' | 'daily' | 'weekly'\ntype AvailabilitySubjectType = 'member' | 'resource' | 'ruleset'\n\ntype AvailabilityRule = {\n id: string\n subjectType: AvailabilitySubjectType\n subjectId: string\n timezone: string\n rrule: string\n exdates: string[]\n kind?: 'availability' | 'unavailability'\n note?: string | null\n unavailabilityReasonEntryId?: string | null\n unavailabilityReasonValue?: string | null\n createdAt?: string | null\n}\n\ntype AvailabilityRuleSet = {\n id: string\n name: string\n timezone: string\n}\n\nexport type AvailabilityBookedEvent = {\n id: string\n title: string\n startsAt: string | Date\n endsAt: string | Date\n}\n\nexport type AvailabilityScheduleItemBuilder = (params: {\n availabilityRules: AvailabilityRule[]\n bookedEvents: AvailabilityBookedEvent[]\n translate: (key: string, fallback?: string) => string\n}) => ScheduleItem[]\n\nexport type AvailabilityRulesEditorProps = {\n subjectType: AvailabilitySubjectType\n subjectId: string\n labelPrefix: string\n mode?: 'availability' | 'unavailability'\n initialTimezone?: string\n rulesetId?: string | null\n onRulesetChange?: (rulesetId: string | null) => Promise<void>\n buildScheduleItems: AvailabilityScheduleItemBuilder\n loadBookedEvents?: (range: ScheduleRange) => Promise<AvailabilityBookedEvent[]>\n readOnly?: boolean\n allowUnavailability?: boolean\n}\n\ntype TimeWindow = { start: string; end: string }\ntype RuleSetFormValues = {\n name: string\n}\ntype WeeklyWindows = TimeWindow[][]\n\nconst DAY_LABELS = [\n { code: 'SU', short: 'S', nameKey: 'schedule.weekday.sunday', fallback: 'Sunday' },\n { code: 'MO', short: 'M', nameKey: 'schedule.weekday.monday', fallback: 'Monday' },\n { code: 'TU', short: 'T', nameKey: 'schedule.weekday.tuesday', fallback: 'Tuesday' },\n { code: 'WE', short: 'W', nameKey: 'schedule.weekday.wednesday', fallback: 'Wednesday' },\n { code: 'TH', short: 'T', nameKey: 'schedule.weekday.thursday', fallback: 'Thursday' },\n { code: 'FR', short: 'F', nameKey: 'schedule.weekday.friday', fallback: 'Friday' },\n { code: 'SA', short: 'S', nameKey: 'schedule.weekday.saturday', fallback: 'Saturday' },\n] as const\n\nconst DEFAULT_WINDOW: TimeWindow = { start: '09:00', end: '17:00' }\n\nfunction resolveRuleReasonEntryId(rule?: AvailabilityRule | null): string | null {\n if (!rule) return null\n if (typeof rule.unavailabilityReasonEntryId === 'string' && rule.unavailabilityReasonEntryId.length) {\n return rule.unavailabilityReasonEntryId\n }\n const fallback = (rule as Record<string, unknown>).unavailability_reason_entry_id\n return typeof fallback === 'string' && fallback.length ? fallback : null\n}\n\nfunction resolveRuleReasonValue(rule?: AvailabilityRule | null): string | null {\n if (!rule) return null\n if (typeof rule.unavailabilityReasonValue === 'string' && rule.unavailabilityReasonValue.length) {\n return rule.unavailabilityReasonValue\n }\n const fallback = (rule as Record<string, unknown>).unavailability_reason_value\n return typeof fallback === 'string' && fallback.length ? fallback : null\n}\n\nfunction createDefaultWindow(): TimeWindow {\n return { ...DEFAULT_WINDOW }\n}\n\nfunction getDefaultWindowDurationMinutes(): number {\n const start = parseTimeInput(DEFAULT_WINDOW.start)\n const end = parseTimeInput(DEFAULT_WINDOW.end)\n if (!start || !end) return 60\n const minutes = end.hours * 60 + end.minutes - (start.hours * 60 + start.minutes)\n return Math.max(1, minutes)\n}\n\nfunction formatTimeFromMinutes(totalMinutes: number): string {\n const clamped = Math.max(0, Math.min(23 * 60 + 59, totalMinutes))\n const hours = String(Math.floor(clamped / 60)).padStart(2, '0')\n const minutes = String(clamped % 60).padStart(2, '0')\n return `${hours}:${minutes}`\n}\n\nfunction buildNextWindow(windows: TimeWindow[]): TimeWindow {\n if (windows.length === 0) return createDefaultWindow()\n const lastWindow = windows[windows.length - 1]\n const end = parseTimeInput(lastWindow.end)\n if (!end) return createDefaultWindow()\n const startMinutes = end.hours * 60 + end.minutes\n if (startMinutes >= 23 * 60 + 59) return createDefaultWindow()\n const durationMinutes = getDefaultWindowDurationMinutes()\n const endMinutes = Math.min(startMinutes + durationMinutes, 23 * 60 + 59)\n if (endMinutes <= startMinutes) return createDefaultWindow()\n return {\n start: formatTimeFromMinutes(startMinutes),\n end: formatTimeFromMinutes(endMinutes),\n }\n}\n\nfunction getTimezoneOptions(): string[] {\n const options = new Set<string>()\n const resolved = Intl.DateTimeFormat().resolvedOptions().timeZone\n if (resolved) options.add(resolved)\n options.add('UTC')\n const intlWithSupportedValues = Intl as typeof Intl & { supportedValuesOf?: (input: 'timeZone') => string[] }\n if (typeof intlWithSupportedValues.supportedValuesOf === 'function') {\n intlWithSupportedValues.supportedValuesOf('timeZone').forEach((timezone) => {\n if (timezone) options.add(timezone)\n })\n }\n return Array.from(options).sort((a, b) => a.localeCompare(b))\n}\n\nfunction formatTimeInput(value: Date): string {\n const hours = String(value.getHours()).padStart(2, '0')\n const minutes = String(value.getMinutes()).padStart(2, '0')\n return `${hours}:${minutes}`\n}\n\nfunction formatDateInput(value: Date): string {\n const year = value.getFullYear()\n const month = String(value.getMonth() + 1).padStart(2, '0')\n const day = String(value.getDate()).padStart(2, '0')\n return `${year}-${month}-${day}`\n}\n\nfunction parseDateInput(value: string): Date | null {\n const [year, month, day] = value.split('-').map((part) => Number(part))\n if (!Number.isFinite(year) || !Number.isFinite(month) || !Number.isFinite(day)) return null\n const date = new Date(year, month - 1, day)\n if (Number.isNaN(date.getTime())) return null\n return date\n}\n\nfunction parseTimeInput(value: string): { hours: number; minutes: number } | null {\n const [hours, minutes] = value.split(':').map((part) => Number(part))\n if (!Number.isFinite(hours) || !Number.isFinite(minutes)) return null\n if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null\n return { hours, minutes }\n}\n\nfunction toDateForWeekday(weekday: number, time: string): Date | null {\n const parsed = parseTimeInput(time)\n if (!parsed) return null\n const now = new Date()\n const base = new Date(now.getFullYear(), now.getMonth(), now.getDate())\n const diff = (weekday - base.getDay() + 7) % 7\n const target = new Date(base.getTime() + diff * 24 * 60 * 60 * 1000)\n target.setHours(parsed.hours, parsed.minutes, 0, 0)\n return target\n}\n\nfunction toDateForDay(value: string, time: string): Date | null {\n if (!value) return null\n const parsed = parseTimeInput(time)\n if (!parsed) return null\n const parts = value.split('-').map((part) => Number(part))\n if (parts.length !== 3 || parts.some((part) => Number.isNaN(part))) return null\n const [year, month, day] = parts\n const date = new Date(year, month - 1, day, parsed.hours, parsed.minutes, 0, 0)\n return Number.isNaN(date.getTime()) ? null : date\n}\n\nfunction getWeekdayIndex(value: string): number | null {\n const date = toDateForDay(value, '00:00')\n return date ? date.getDay() : null\n}\n\nfunction getWindowError(window: TimeWindow, labels: { windowErrorRequired: string; windowErrorRange: string }): string | null {\n const start = parseTimeInput(window.start)\n const end = parseTimeInput(window.end)\n if (!start || !end) return labels.windowErrorRequired\n if (start.hours > end.hours || (start.hours === end.hours && start.minutes >= end.minutes)) {\n return labels.windowErrorRange\n }\n return null\n}\n\nfunction formatDuration(minutes: number): string {\n const clamped = Math.max(1, minutes)\n const hours = Math.floor(clamped / 60)\n const mins = clamped % 60\n if (hours > 0 && mins > 0) return `PT${hours}H${mins}M`\n if (hours > 0) return `PT${hours}H`\n return `PT${mins}M`\n}\n\nfunction buildAvailabilityRrule(start: Date, end: Date, repeat: AvailabilityRepeat): string {\n const dtStart = start.toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z'\n const durationMinutes = Math.max(1, Math.round((end.getTime() - start.getTime()) / 60000))\n const duration = formatDuration(durationMinutes)\n let rule = ''\n if (repeat === 'once') {\n rule = 'FREQ=DAILY;COUNT=1'\n } else if (repeat === 'weekly') {\n const dayCode = DAY_LABELS[start.getDay()].code\n rule = `FREQ=WEEKLY;BYDAY=${dayCode}`\n } else {\n rule = 'FREQ=DAILY'\n }\n return `DTSTART:${dtStart}\\nDURATION:${duration}\\nRRULE:${rule}`\n}\n\nfunction groupRulesByDate(rules: AvailabilityRule[]): Map<string, AvailabilityRule[]> {\n const map = new Map<string, AvailabilityRule[]>()\n rules.forEach((rule) => {\n const window = parseAvailabilityRuleWindow(rule)\n const key = formatDateInput(window.startAt)\n const list = map.get(key) ?? []\n list.push(rule)\n map.set(key, list)\n })\n return map\n}\n\nfunction buildWindowsFromRules(rules: AvailabilityRule[]): TimeWindow[] {\n return rules\n .map((rule) => {\n const window = parseAvailabilityRuleWindow(rule)\n return {\n start: formatTimeInput(window.startAt),\n end: formatTimeInput(window.endAt),\n }\n })\n .sort((a, b) => a.start.localeCompare(b.start))\n}\n\nfunction createEmptyWeeklyWindows(): WeeklyWindows {\n return Array.from({ length: 7 }, () => [])\n}\n\nfunction cloneWeeklyWindows(windows: WeeklyWindows): WeeklyWindows {\n return windows.map((dayWindows) => dayWindows.map((window) => ({ ...window })))\n}\n\nfunction normalizeWeeklyWindows(windows: WeeklyWindows): WeeklyWindows {\n return windows.map((dayWindows) => {\n const unique = new Map<string, TimeWindow>()\n dayWindows.forEach((window) => {\n if (!window.start || !window.end) return\n const key = `${window.start}-${window.end}`\n if (!unique.has(key)) unique.set(key, { start: window.start, end: window.end })\n })\n return Array.from(unique.values()).sort((left, right) => left.start.localeCompare(right.start))\n })\n}\n\nfunction buildWeeklyDraft(rules: AvailabilityRule[]): WeeklyWindows {\n const draft = createEmptyWeeklyWindows()\n rules.forEach((rule) => {\n const window = parseAvailabilityRuleWindow(rule)\n const repeat = window.repeat\n if (repeat === 'once') return\n const windowValue = {\n start: formatTimeInput(window.startAt),\n end: formatTimeInput(window.endAt),\n }\n if (repeat === 'daily') {\n for (let day = 0; day < 7; day += 1) {\n draft[day].push(windowValue)\n }\n return\n }\n const day = window.startAt.getDay()\n draft[day].push(windowValue)\n })\n return normalizeWeeklyWindows(draft)\n}\n\nfunction serializeWeeklyWindows(windows: WeeklyWindows): string {\n const payload = windows.map((dayWindows) => dayWindows.map((window) => ({ start: window.start, end: window.end })))\n return JSON.stringify(payload)\n}\n\nfunction buildWeeklyPayload(windows: WeeklyWindows): Array<{ weekday: number; start: string; end: string }> {\n const payload: Array<{ weekday: number; start: string; end: string }> = []\n const seen = new Set<string>()\n windows.forEach((dayWindows, day) => {\n dayWindows.forEach((window) => {\n const start = toDateForWeekday(day, window.start)\n const end = toDateForWeekday(day, window.end)\n if (!start || !end || start >= end) return\n const key = `${day}:${window.start}:${window.end}`\n if (seen.has(key)) return\n seen.add(key)\n payload.push({ weekday: day, start: window.start, end: window.end })\n })\n })\n return payload\n}\n\nexport function AvailabilityRulesEditor({\n subjectType,\n subjectId,\n labelPrefix,\n mode: _mode = 'availability',\n initialTimezone,\n rulesetId,\n onRulesetChange,\n buildScheduleItems,\n loadBookedEvents,\n readOnly,\n allowUnavailability,\n}: AvailabilityRulesEditorProps) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const isReadOnly = Boolean(readOnly)\n const canManageUnavailability = allowUnavailability ?? true\n const dialogRef = React.useRef<HTMLDivElement | null>(null)\n const createRuleSetDialogRef = React.useRef<HTMLDivElement | null>(null)\n const [availabilityRules, setAvailabilityRules] = React.useState<AvailabilityRule[]>([])\n const [rulesetRules, setRulesetRules] = React.useState<AvailabilityRule[]>([])\n const [availabilityLoading, setAvailabilityLoading] = React.useState(true)\n const [availabilityError, setAvailabilityError] = React.useState<string | null>(null)\n const [ruleSets, setRuleSets] = React.useState<AvailabilityRuleSet[]>([])\n const [ruleSetsLoading, setRuleSetsLoading] = React.useState(false)\n const [bookedEvents, setBookedEvents] = React.useState<AvailabilityBookedEvent[]>([])\n const [bookedLoading, setBookedLoading] = React.useState(false)\n const [bookedError, setBookedError] = React.useState<string | null>(null)\n const [viewMode, setViewMode] = React.useState<'list' | 'calendar'>('list')\n const [scheduleView, setScheduleView] = React.useState<ScheduleViewMode>('month')\n const [range, setRange] = React.useState<ScheduleRange>(() => {\n const now = new Date()\n const start = new Date(now.getFullYear(), now.getMonth(), 1)\n const end = new Date(now.getFullYear(), now.getMonth() + 1, 0)\n return { start, end }\n })\n const [timezone, setTimezone] = React.useState<string>(\n () => initialTimezone ?? (Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC'),\n )\n const [timezoneDirty, setTimezoneDirty] = React.useState(false)\n const [editorOpen, setEditorOpen] = React.useState(false)\n const [editorScope, setEditorScope] = React.useState<'date' | 'weekday'>('date')\n const [editorDates, setEditorDates] = React.useState<string[]>([])\n const [editorWeekday, setEditorWeekday] = React.useState<number>(new Date().getDay())\n const [editorWindows, setEditorWindows] = React.useState<TimeWindow[]>([createDefaultWindow()])\n const [editorRules, setEditorRules] = React.useState<AvailabilityRule[]>([])\n const [editorUnavailable, setEditorUnavailable] = React.useState(false)\n const [editorNote, setEditorNote] = React.useState('')\n const [editorReasonEntryId, setEditorReasonEntryId] = React.useState<string | null>(null)\n const [editorReasonValue, setEditorReasonValue] = React.useState('')\n const [reasonEntriesById, setReasonEntriesById] = React.useState<Record<string, UnavailabilityReasonEntry>>({})\n const [createRuleSetOpen, setCreateRuleSetOpen] = React.useState(false)\n const [isWeeklyAutoSaving, setIsWeeklyAutoSaving] = React.useState(false)\n const [customOverridesEnabled, setCustomOverridesEnabled] = React.useState(false)\n const autoSaveTimerRef = React.useRef<number | null>(null)\n const lastSavedWeeklyKeyRef = React.useRef<string | null>(null)\n const weeklySaveStateRef = React.useRef({ inFlight: false, queued: false })\n const timezoneSaveTimerRef = React.useRef<number | null>(null)\n const timezoneSaveInFlightRef = React.useRef(false)\n const viewModeRef = React.useRef(viewMode)\n const saveWeeklyRef = React.useRef<\n ((options?: { silentSuccess?: boolean; skipRefresh?: boolean }) => Promise<void>) | null\n >(null)\n const timezoneOptions = React.useMemo(() => getTimezoneOptions(), [])\n\n const usingRuleSet = Boolean(rulesetId) && availabilityRules.length === 0 && !customOverridesEnabled\n const activeRules = usingRuleSet ? rulesetRules : availabilityRules\n const scheduleRules = React.useMemo(() => {\n const dateBlockers = new Set<string>()\n activeRules.forEach((rule) => {\n if (rule.kind !== 'unavailability') return\n const window = parseAvailabilityRuleWindow(rule)\n if (window.repeat !== 'once') return\n dateBlockers.add(formatDateInput(window.startAt))\n })\n if (!dateBlockers.size) return activeRules\n return activeRules.filter((rule) => {\n const window = parseAvailabilityRuleWindow(rule)\n if (window.repeat !== 'once') return true\n if (rule.kind === 'unavailability') return true\n return !dateBlockers.has(formatDateInput(window.startAt))\n })\n }, [activeRules])\n const scheduleItems = React.useMemo(\n () => buildScheduleItems({ availabilityRules: scheduleRules, bookedEvents, translate: t }),\n [bookedEvents, buildScheduleItems, scheduleRules, t],\n )\n\n const listLabels = React.useMemo(() => {\n const modeBase = `${labelPrefix}.availability`\n return {\n title: t(`${labelPrefix}.availability.section.title`, 'Availability'),\n weeklyTitle: t(`${labelPrefix}.availability.weekly.title`, 'Weekly hours'),\n weeklySubtitle: t(`${labelPrefix}.availability.weekly.subtitle`, 'Set when you are typically available.'),\n dateSpecificTitle: t(`${labelPrefix}.availability.dateSpecific.title`, 'Date-specific hours'),\n dateSpecificSubtitle: t(`${labelPrefix}.availability.dateSpecific.subtitle`, 'Adjust hours for specific days.'),\n addHours: t(`${labelPrefix}.availability.dateSpecific.add`, 'Add hours'),\n timezoneLabel: t(`${labelPrefix}.availability.timezone`, 'Timezone'),\n timezonePlaceholder: t(`${labelPrefix}.availability.timezone.placeholder`, 'Search timezones...'),\n timezoneSaveError: t(`${labelPrefix}.availability.timezone.saveError`, 'Failed to save timezone.'),\n ruleSetLabel: t(`${labelPrefix}.availability.ruleset.label`, 'Schedule'),\n ruleSetPlaceholder: t(`${labelPrefix}.availability.ruleset.placeholder`, 'Custom schedule'),\n ruleSetCustomize: t(`${labelPrefix}.availability.ruleset.customize`, 'Customize schedule'),\n ruleSetReset: t(`${labelPrefix}.availability.ruleset.reset`, 'Reset to schedule'),\n ruleSetConfirm: t(`${labelPrefix}.availability.ruleset.confirm`, 'Changing the schedule will reset custom hours. Continue?'),\n ruleSetLoading: t(`${labelPrefix}.availability.ruleset.loading`, 'Loading schedules...'),\n ruleSetError: t(`${labelPrefix}.availability.ruleset.error`, 'Failed to load schedules.'),\n ruleSetCreateLabel: t(`${labelPrefix}.availability.ruleset.create`, 'New schedule'),\n ruleSetCreateTitle: t(`${labelPrefix}.availability.ruleset.createTitle`, 'Save as schedule'),\n ruleSetCreateSubmit: t(`${labelPrefix}.availability.ruleset.createSubmit`, 'Save schedule'),\n ruleSetCreateNameLabel: t(`${labelPrefix}.availability.ruleset.createName`, 'Schedule name'),\n ruleSetCreateTimezoneLabel: t(`${labelPrefix}.availability.ruleset.createTimezone`, 'Timezone'),\n ruleSetCreateSuccess: t(`${labelPrefix}.availability.ruleset.createSuccess`, 'Schedule saved.'),\n ruleSetCreateError: t(`${labelPrefix}.availability.ruleset.createError`, 'Failed to save schedule.'),\n editTitle: t(`${modeBase}.form.title.edit`, 'Edit availability'),\n addTitle: t(`${modeBase}.form.title.create`, 'Add availability'),\n applyLabel: t(`${labelPrefix}.availability.actions.apply`, 'Apply'),\n cancelLabel: t('ui.forms.actions.cancel', 'Cancel'),\n applyScopeLabel: t(`${labelPrefix}.availability.scope.label`, 'Apply to'),\n applyScopeDate: t(`${labelPrefix}.availability.scope.date`, 'This date'),\n applyScopeWeekday: t(`${labelPrefix}.availability.scope.weekday`, 'Weekday:'),\n windowsLabel: t(`${labelPrefix}.availability.windows.label`, 'What hours are you available?'),\n addWindow: t(`${labelPrefix}.availability.windows.add`, 'Add window'),\n removeWindow: t(`${labelPrefix}.availability.windows.remove`, 'Remove'),\n windowErrorRequired: t(`${labelPrefix}.availability.windows.errors.required`, 'Start and end times are required.'),\n windowErrorRange: t(`${labelPrefix}.availability.windows.errors.range`, 'End time must be after start.'),\n noHours: t(`${labelPrefix}.availability.weekly.empty`, 'Unavailable'),\n saveWeekly: t(`${labelPrefix}.availability.weekly.save`, 'Save weekly hours'),\n saveWeeklySuccess: t(`${labelPrefix}.availability.weekly.saved`, 'Weekly hours saved.'),\n saveWeeklyError: t(`${labelPrefix}.availability.weekly.error`, 'Failed to save weekly hours.'),\n saveDateSuccess: t(`${labelPrefix}.availability.dateSpecific.saved`, 'Date-specific hours saved.'),\n saveDateError: t(`${labelPrefix}.availability.dateSpecific.error`, 'Failed to save date-specific hours.'),\n unavailableLabel: t(`${labelPrefix}.availability.unavailable.label`, 'Unavailable on this day'),\n unavailableHelp: t(`${labelPrefix}.availability.unavailable.help`, 'Blocks availability for the entire day.'),\n unavailableTitle: t(`${labelPrefix}.availability.unavailable.title`, 'Unavailable'),\n unavailableNoteLabel: t(`${labelPrefix}.availability.unavailable.note`, 'Note'),\n unavailableNotePlaceholder: t(`${labelPrefix}.availability.unavailable.notePlaceholder`, 'Holiday'),\n unavailableReasonLabel: t(`${labelPrefix}.availability.unavailable.reason.label`, 'Reason'),\n unavailableReasonPlaceholder: t(`${labelPrefix}.availability.unavailable.reason.placeholder`, 'Select a reason'),\n unavailableReasonAddLabel: t(`${labelPrefix}.availability.unavailable.reason.addLabel`, 'Add reason'),\n unavailableReasonAddPrompt: t(`${labelPrefix}.availability.unavailable.reason.addPrompt`, 'Name the reason'),\n unavailableReasonDialogTitle: t(`${labelPrefix}.availability.unavailable.reason.dialogTitle`, 'Add reason'),\n unavailableReasonValueLabel: t(`${labelPrefix}.availability.unavailable.reason.valueLabel`, 'Reason'),\n unavailableReasonValuePlaceholder: t(`${labelPrefix}.availability.unavailable.reason.valuePlaceholder`, 'Reason name'),\n unavailableReasonLabelLabel: t(`${labelPrefix}.availability.unavailable.reason.labelLabel`, 'Label'),\n unavailableReasonLabelPlaceholder: t(`${labelPrefix}.availability.unavailable.reason.labelPlaceholder`, 'Display label (optional)'),\n unavailableReasonEmptyError: t(`${labelPrefix}.availability.unavailable.reason.emptyError`, 'Please enter a reason'),\n unavailableReasonSaveLabel: t(`${labelPrefix}.availability.unavailable.reason.saveLabel`, 'Save'),\n unavailableReasonErrorLoad: t(`${labelPrefix}.availability.unavailable.reason.errorLoad`, 'Failed to load reasons'),\n unavailableReasonErrorSave: t(`${labelPrefix}.availability.unavailable.reason.errorSave`, 'Failed to save reason'),\n unavailableReasonLoading: t(`${labelPrefix}.availability.unavailable.reason.loading`, 'Loading reasons...'),\n unavailableReasonManageTitle: t(`${labelPrefix}.availability.unavailable.reason.manageTitle`, 'Manage reasons'),\n scheduleError: t(`${labelPrefix}.schedule.error.load`, 'Failed to load schedule.'),\n scheduleLoading: t(`${labelPrefix}.schedule.loading`, 'Loading schedule...'),\n customizePrompt: t(`${labelPrefix}.availability.ruleset.customizePrompt`, 'This schedule is based on a shared ruleset. Customize it to make changes.'),\n calendarLabel: t(`${labelPrefix}.availability.view.calendar`, 'Calendar'),\n listLabel: t(`${labelPrefix}.availability.view.list`, 'List'),\n editAllLabel: t(`${labelPrefix}.availability.scope.weekdayShort`, 'All {{weekday}}s', { weekday: DAY_LABELS[editorWeekday].fallback }),\n addDateLabel: t(`${labelPrefix}.availability.dateSpecific.addDate`, 'Add date'),\n }\n }, [editorWeekday, labelPrefix, t])\n\n const unavailableReasonLabels = React.useMemo<DictionarySelectLabels>(() => ({\n placeholder: listLabels.unavailableReasonPlaceholder,\n addLabel: listLabels.unavailableReasonAddLabel,\n addPrompt: listLabels.unavailableReasonAddPrompt,\n dialogTitle: listLabels.unavailableReasonDialogTitle,\n valueLabel: listLabels.unavailableReasonValueLabel,\n valuePlaceholder: listLabels.unavailableReasonValuePlaceholder,\n labelLabel: listLabels.unavailableReasonLabelLabel,\n labelPlaceholder: listLabels.unavailableReasonLabelPlaceholder,\n emptyError: listLabels.unavailableReasonEmptyError,\n cancelLabel: listLabels.cancelLabel,\n saveLabel: listLabels.unavailableReasonSaveLabel,\n errorLoad: listLabels.unavailableReasonErrorLoad,\n errorSave: listLabels.unavailableReasonErrorSave,\n loadingLabel: listLabels.unavailableReasonLoading,\n manageTitle: listLabels.unavailableReasonManageTitle,\n }), [listLabels])\n\n const refreshAvailability = React.useCallback(async () => {\n if (!subjectId) return\n setAvailabilityLoading(true)\n setAvailabilityError(null)\n try {\n const params = new URLSearchParams({\n page: '1',\n pageSize: '100',\n subjectType,\n subjectIds: subjectId,\n })\n const call = await apiCall<{ items?: AvailabilityRule[] }>(`/api/planner/availability?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setAvailabilityRules(items)\n } catch (error) {\n const message = error instanceof Error ? error.message : t(`${labelPrefix}.availability.error.load`, 'Failed to load availability.')\n setAvailabilityError(message)\n } finally {\n setAvailabilityLoading(false)\n }\n }, [labelPrefix, subjectId, subjectType, t])\n\n const refreshRuleSetRules = React.useCallback(async () => {\n if (!rulesetId) {\n setRulesetRules([])\n return\n }\n try {\n const params = new URLSearchParams({\n page: '1',\n pageSize: '100',\n subjectType: 'ruleset',\n subjectIds: rulesetId,\n })\n const call = await apiCall<{ items?: AvailabilityRule[] }>(`/api/planner/availability?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setRulesetRules(items)\n } catch {\n setRulesetRules([])\n }\n }, [rulesetId])\n\n const refreshRuleSets = React.useCallback(async () => {\n if (!onRulesetChange) return\n setRuleSetsLoading(true)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100' })\n const call = await apiCall<{ items?: AvailabilityRuleSet[] }>(`/api/planner/availability-rule-sets?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setRuleSets(items)\n } catch {\n setRuleSets([])\n } finally {\n setRuleSetsLoading(false)\n }\n }, [onRulesetChange])\n\n const fetchUnavailabilityReasonOptions = React.useCallback(async () => {\n const entries = await loadUnavailabilityReasonEntries(subjectType)\n const map: Record<string, UnavailabilityReasonEntry> = {}\n entries.forEach((entry) => {\n map[entry.id] = entry\n })\n setReasonEntriesById(map)\n return entries.map((entry) => ({\n value: entry.id,\n label: entry.label ?? entry.value,\n color: entry.color,\n icon: entry.icon,\n }))\n }, [subjectType])\n\n const createUnavailabilityReasonOption = React.useCallback(async (input: { value: string; label?: string; color?: string | null; icon?: string | null }) => {\n const entry = await createUnavailabilityReasonEntry(subjectType, input)\n if (!entry) return null\n setReasonEntriesById((prev) => ({ ...prev, [entry.id]: entry }))\n return {\n value: entry.id,\n label: entry.label ?? entry.value,\n color: entry.color,\n icon: entry.icon,\n }\n }, [subjectType])\n\n React.useEffect(() => {\n if (!editorReasonEntryId) {\n if (editorReasonValue) setEditorReasonValue('')\n return\n }\n const entry = reasonEntriesById[editorReasonEntryId]\n if (entry && entry.value !== editorReasonValue) {\n setEditorReasonValue(entry.value)\n }\n }, [editorReasonEntryId, editorReasonValue, reasonEntriesById])\n\n React.useEffect(() => {\n void refreshAvailability()\n }, [refreshAvailability])\n\n React.useEffect(() => {\n void refreshRuleSetRules()\n }, [refreshRuleSetRules])\n\n React.useEffect(() => {\n if (viewMode !== 'calendar') return\n void refreshAvailability()\n void refreshRuleSetRules()\n }, [refreshAvailability, refreshRuleSetRules, viewMode])\n\n React.useEffect(() => {\n void refreshRuleSets()\n }, [refreshRuleSets])\n\n React.useEffect(() => {\n viewModeRef.current = viewMode\n }, [viewMode])\n\n React.useEffect(() => {\n if (timezoneDirty) return\n if (initialTimezone) {\n setTimezone(initialTimezone)\n return\n }\n const ruleTimezone = activeRules.find((rule) => rule.timezone)?.timezone\n if (ruleTimezone) setTimezone(ruleTimezone)\n }, [activeRules, initialTimezone, timezoneDirty])\n\n React.useEffect(() => {\n if (timezoneDirty) return\n if (!usingRuleSet || !rulesetId) return\n const ruleset = ruleSets.find((entry) => entry.id === rulesetId)\n if (ruleset?.timezone) setTimezone(ruleset.timezone)\n }, [rulesetId, ruleSets, timezoneDirty, usingRuleSet])\n\n React.useEffect(() => {\n if (availabilityRules.length > 0) {\n setCustomOverridesEnabled(true)\n }\n }, [availabilityRules.length])\n\n React.useEffect(() => {\n if (!rulesetId) {\n setCustomOverridesEnabled(false)\n }\n }, [rulesetId])\n\n const refreshBookedEvents = React.useCallback(async () => {\n if (!loadBookedEvents) return\n setBookedLoading(true)\n setBookedError(null)\n try {\n const items = await loadBookedEvents(range)\n setBookedEvents(Array.isArray(items) ? items : [])\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.scheduleError\n setBookedError(message)\n } finally {\n setBookedLoading(false)\n }\n }, [listLabels.scheduleError, loadBookedEvents, range])\n\n React.useEffect(() => {\n void refreshBookedEvents()\n }, [refreshBookedEvents])\n\n const weeklyDraft = React.useMemo(() => buildWeeklyDraft(activeRules), [activeRules])\n const [weeklyWindows, setWeeklyWindows] = React.useState<WeeklyWindows>(() => cloneWeeklyWindows(weeklyDraft))\n const weeklyWindowsRef = React.useRef<WeeklyWindows>(cloneWeeklyWindows(weeklyDraft))\n const weeklyDirtyRef = React.useRef(false)\n const weeklyDraftKey = React.useMemo(() => serializeWeeklyWindows(weeklyDraft), [weeklyDraft])\n const weeklyKey = React.useMemo(() => serializeWeeklyWindows(weeklyWindows), [weeklyWindows])\n const weeklyWindowErrors = React.useMemo(\n () => weeklyWindows.map((dayWindows) => dayWindows.map((window) => getWindowError(window, listLabels))),\n [listLabels, weeklyWindows],\n )\n const weeklyHasErrors = React.useMemo(\n () => weeklyWindowErrors.some((errors) => errors.some(Boolean)),\n [weeklyWindowErrors],\n )\n\n React.useEffect(() => {\n if (weeklyDirtyRef.current) return\n const nextWindows = cloneWeeklyWindows(weeklyDraft)\n setWeeklyWindows(nextWindows)\n weeklyWindowsRef.current = nextWindows\n }, [weeklyDraft])\n\n React.useEffect(() => {\n lastSavedWeeklyKeyRef.current = weeklyDraftKey\n }, [weeklyDraftKey])\n\n const dateSpecificRules = React.useMemo(\n () => activeRules.filter((rule) => parseAvailabilityRuleWindow(rule).repeat === 'once'),\n [activeRules],\n )\n const dateGroups = React.useMemo(() => groupRulesByDate(dateSpecificRules), [dateSpecificRules])\n\n const isLoading = availabilityLoading || bookedLoading\n const error = availabilityError ?? bookedError\n\n React.useEffect(() => {\n weeklyWindowsRef.current = weeklyWindows\n }, [weeklyWindows])\n\n const handleWeeklyWindowChange = React.useCallback((day: number, index: number, next: TimeWindow) => {\n weeklyDirtyRef.current = true\n setWeeklyWindows((prev) => {\n const nextWindows = prev.map((dayWindows) => [...dayWindows])\n const list = nextWindows[day] ?? []\n list[index] = next\n nextWindows[day] = list\n return nextWindows\n })\n }, [])\n\n const handleWeeklyWindowAdd = React.useCallback((day: number) => {\n weeklyDirtyRef.current = true\n setWeeklyWindows((prev) => {\n const nextWindows = prev.map((dayWindows) => [...dayWindows])\n const list = nextWindows[day] ?? []\n list.push(buildNextWindow(list))\n nextWindows[day] = list\n return nextWindows\n })\n }, [])\n\n const handleWeeklyWindowRemove = React.useCallback((day: number, index: number) => {\n weeklyDirtyRef.current = true\n setWeeklyWindows((prev) => {\n const nextWindows = prev.map((dayWindows) => [...dayWindows])\n const list = nextWindows[day] ?? []\n list.splice(index, 1)\n nextWindows[day] = list\n return nextWindows\n })\n }, [])\n\n const saveWeeklyHours = React.useCallback(async (options?: { silentSuccess?: boolean; skipRefresh?: boolean }) => {\n if (isReadOnly) return\n const subjectForRules: AvailabilitySubjectType = usingRuleSet ? 'ruleset' : subjectType\n const subjectIdForRules = usingRuleSet ? (rulesetId ?? '') : subjectId\n if (!subjectIdForRules) return\n if (weeklyHasErrors) return\n\n const shouldSkipRefresh = Boolean(options?.skipRefresh)\n setIsWeeklyAutoSaving(options?.silentSuccess === true)\n try {\n const windows = buildWeeklyPayload(normalizeWeeklyWindows(weeklyWindowsRef.current))\n await apiCallOrThrow('/api/planner/availability-weekly', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n subjectType: subjectForRules,\n subjectId: subjectIdForRules,\n timezone,\n windows,\n }),\n }, { errorMessage: listLabels.saveWeeklyError })\n lastSavedWeeklyKeyRef.current = weeklyKey\n weeklyDirtyRef.current = false\n if (!options?.silentSuccess) {\n flash(listLabels.saveWeeklySuccess, 'success')\n }\n if (!shouldSkipRefresh) {\n await refreshAvailability()\n await refreshRuleSetRules()\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.saveWeeklyError\n flash(message, 'error')\n } finally {\n setIsWeeklyAutoSaving(false)\n }\n }, [\n listLabels.saveWeeklyError,\n listLabels.saveWeeklySuccess,\n refreshAvailability,\n refreshRuleSetRules,\n rulesetId,\n subjectId,\n subjectType,\n timezone,\n usingRuleSet,\n weeklyHasErrors,\n weeklyKey,\n isReadOnly,\n ])\n\n React.useEffect(() => {\n saveWeeklyRef.current = saveWeeklyHours\n }, [saveWeeklyHours])\n\n const queueWeeklySave = React.useCallback((options?: { silentSuccess?: boolean; skipRefresh?: boolean }) => {\n if (weeklySaveStateRef.current.inFlight) {\n weeklySaveStateRef.current.queued = true\n return\n }\n weeklySaveStateRef.current.inFlight = true\n void (async () => {\n try {\n await saveWeeklyRef.current?.(options)\n } finally {\n weeklySaveStateRef.current.inFlight = false\n if (weeklySaveStateRef.current.queued) {\n weeklySaveStateRef.current.queued = false\n queueWeeklySave({ silentSuccess: true, skipRefresh: viewModeRef.current === 'list' })\n }\n }\n })()\n }, [])\n\n React.useEffect(() => {\n if (usingRuleSet) return\n if (weeklyHasErrors) return\n if (weeklyKey === lastSavedWeeklyKeyRef.current) return\n if (autoSaveTimerRef.current !== null) {\n window.clearTimeout(autoSaveTimerRef.current)\n }\n autoSaveTimerRef.current = window.setTimeout(() => {\n queueWeeklySave({ silentSuccess: true, skipRefresh: viewMode === 'list' })\n }, 600)\n return () => {\n if (autoSaveTimerRef.current !== null) {\n window.clearTimeout(autoSaveTimerRef.current)\n }\n }\n }, [queueWeeklySave, usingRuleSet, viewMode, weeklyHasErrors, weeklyKey])\n\n const persistTimezone = React.useCallback(async (nextTimezone: string) => {\n if (isReadOnly) return\n if (timezoneSaveInFlightRef.current) return\n const trimmedTimezone = nextTimezone.trim() || 'UTC'\n const rulesetTimezoneId = subjectType === 'ruleset' ? subjectId : rulesetId\n const rulesToUpdate = activeRules.filter((rule) => rule.timezone !== trimmedTimezone)\n if (!rulesToUpdate.length && !rulesetTimezoneId) {\n setTimezoneDirty(false)\n return\n }\n timezoneSaveInFlightRef.current = true\n try {\n const updates: Array<Promise<unknown>> = []\n rulesToUpdate.forEach((rule) => {\n updates.push(updateCrud('planner/availability', {\n id: rule.id,\n timezone: trimmedTimezone,\n }))\n })\n if (rulesetTimezoneId) {\n updates.push(updateCrud('planner/availability-rule-sets', {\n id: rulesetTimezoneId,\n timezone: trimmedTimezone,\n }))\n }\n if (updates.length) {\n await Promise.all(updates)\n await refreshAvailability()\n await refreshRuleSetRules()\n }\n setTimezoneDirty(false)\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.timezoneSaveError\n flash(message, 'error')\n setTimezoneDirty(false)\n } finally {\n timezoneSaveInFlightRef.current = false\n }\n }, [\n activeRules,\n listLabels.timezoneSaveError,\n refreshAvailability,\n refreshRuleSetRules,\n rulesetId,\n subjectId,\n subjectType,\n isReadOnly,\n ])\n\n React.useEffect(() => {\n if (!timezoneDirty) return\n const nextTimezone = timezone.trim()\n if (!nextTimezone) return\n if (timezoneSaveTimerRef.current !== null) {\n window.clearTimeout(timezoneSaveTimerRef.current)\n }\n timezoneSaveTimerRef.current = window.setTimeout(() => {\n void persistTimezone(nextTimezone)\n }, 400)\n return () => {\n if (timezoneSaveTimerRef.current !== null) {\n window.clearTimeout(timezoneSaveTimerRef.current)\n }\n }\n }, [persistTimezone, timezone, timezoneDirty])\n\n const handleTimezoneChange = React.useCallback((nextTimezone: string) => {\n if (isReadOnly) return\n const trimmed = nextTimezone.trim()\n setTimezone(trimmed || 'UTC')\n setTimezoneDirty(true)\n }, [canManageUnavailability, isReadOnly])\n\n const handleCustomize = React.useCallback(async () => {\n if (isReadOnly) return\n if (!rulesetId) return\n try {\n const creations = rulesetRules.map((rule) => createCrud('planner/availability', {\n subjectType,\n subjectId,\n timezone: rule.timezone,\n rrule: rule.rrule,\n exdates: rule.exdates ?? [],\n kind: rule.kind ?? 'availability',\n note: rule.note ?? null,\n }))\n await Promise.all(creations)\n setCustomOverridesEnabled(true)\n await refreshAvailability()\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.saveWeeklyError\n flash(message, 'error')\n }\n }, [listLabels.saveWeeklyError, refreshAvailability, rulesetId, rulesetRules, subjectId, subjectType, isReadOnly])\n\n const handleResetToRuleSet = React.useCallback(async () => {\n if (isReadOnly) return\n if (!rulesetId) return\n try {\n await Promise.all(\n availabilityRules.map((rule) => deleteCrud('planner/availability', rule.id, { errorMessage: listLabels.saveWeeklyError })),\n )\n setCustomOverridesEnabled(false)\n await refreshAvailability()\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.saveWeeklyError\n flash(message, 'error')\n }\n }, [availabilityRules, listLabels.saveWeeklyError, refreshAvailability, rulesetId, isReadOnly])\n\n const handleRuleSetChange = React.useCallback(async (nextId: string | null) => {\n if (isReadOnly) return\n if (!onRulesetChange) return\n if (availabilityRules.length > 0 && nextId !== rulesetId) {\n const confirmed = await confirm({\n title: listLabels.ruleSetConfirm,\n variant: 'default',\n })\n if (!confirmed) return\n await Promise.all(\n availabilityRules.map((rule) => deleteCrud('planner/availability', rule.id, { errorMessage: listLabels.saveWeeklyError })),\n )\n }\n setCustomOverridesEnabled(false)\n await onRulesetChange(nextId)\n await refreshAvailability()\n }, [\n availabilityRules,\n confirm,\n listLabels.ruleSetConfirm,\n listLabels.saveWeeklyError,\n onRulesetChange,\n refreshAvailability,\n rulesetId,\n isReadOnly,\n ])\n\n const ruleSetFormSchema = React.useMemo(\n () => z.object({\n name: z.string().min(1, t('ui.forms.errors.required', 'Required')),\n }),\n [t],\n )\n\n const ruleSetFormFields = React.useMemo<CrudField[]>(() => [\n {\n id: 'name',\n label: listLabels.ruleSetCreateNameLabel,\n type: 'text',\n required: true,\n placeholder: listLabels.ruleSetCreateNameLabel,\n },\n ], [listLabels.ruleSetCreateNameLabel])\n\n const ruleSetInitialValues = React.useMemo<Partial<RuleSetFormValues>>(() => ({\n name: '',\n }), [])\n\n const handleCreateRuleSet = React.useCallback(async (values: RuleSetFormValues) => {\n if (isReadOnly) return\n const name = values.name.trim()\n const timezoneValue = timezone\n const response = await createCrud('planner/availability-rule-sets', {\n name,\n timezone: timezoneValue,\n description: null,\n }, { errorMessage: listLabels.ruleSetCreateError })\n const id = typeof response.result?.id === 'string' ? response.result.id : null\n if (!id) throw new Error(listLabels.ruleSetCreateError)\n const creations: Array<Promise<unknown>> = []\n const weeklyWindows = buildWeeklyPayload(normalizeWeeklyWindows(weeklyWindowsRef.current))\n weeklyWindows.forEach((window) => {\n const start = toDateForWeekday(window.weekday, window.start)\n const end = toDateForWeekday(window.weekday, window.end)\n if (!start || !end) return\n const rrule = buildAvailabilityRrule(start, end, 'weekly')\n creations.push(createCrud('planner/availability', {\n subjectType: 'ruleset',\n subjectId: id,\n timezone: timezoneValue,\n rrule,\n exdates: [],\n kind: 'availability',\n note: null,\n }, { errorMessage: listLabels.ruleSetCreateError }))\n })\n if (dateSpecificRules.length) {\n dateSpecificRules.forEach((rule) => {\n creations.push(createCrud('planner/availability', {\n subjectType: 'ruleset',\n subjectId: id,\n timezone: rule.timezone || timezoneValue,\n rrule: rule.rrule,\n exdates: rule.exdates ?? [],\n kind: rule.kind ?? 'availability',\n note: rule.note ?? null,\n unavailabilityReasonEntryId: resolveRuleReasonEntryId(rule),\n unavailabilityReasonValue: resolveRuleReasonValue(rule),\n }, { errorMessage: listLabels.ruleSetCreateError }))\n })\n }\n if (creations.length) {\n await Promise.all(creations)\n }\n await refreshRuleSets()\n if (onRulesetChange) {\n await onRulesetChange(id)\n await refreshAvailability()\n }\n await refreshRuleSetRules()\n flash(listLabels.ruleSetCreateSuccess, 'success')\n setCreateRuleSetOpen(false)\n }, [\n activeRules,\n listLabels.ruleSetCreateError,\n listLabels.ruleSetCreateSuccess,\n dateSpecificRules,\n onRulesetChange,\n refreshAvailability,\n refreshRuleSetRules,\n refreshRuleSets,\n timezone,\n isReadOnly,\n ])\n\n const openEditor = React.useCallback((scope: 'date' | 'weekday', options?: { date?: Date; weekday?: number; rules?: AvailabilityRule[] }) => {\n if (isReadOnly) return\n setEditorScope(scope)\n const rules = options?.rules ?? []\n const unavailableRule = rules.find((rule) => rule.kind === 'unavailability')\n if (unavailableRule && !canManageUnavailability) return\n setEditorRules(rules)\n setEditorUnavailable(scope === 'date' && Boolean(unavailableRule))\n setEditorNote(unavailableRule?.note ?? '')\n setEditorReasonEntryId(scope === 'date' ? resolveRuleReasonEntryId(unavailableRule) : null)\n setEditorReasonValue(scope === 'date' ? (resolveRuleReasonValue(unavailableRule) ?? '') : '')\n if (scope === 'date') {\n const date = options?.date ?? new Date()\n const windows = buildWindowsFromRules(rules)\n setEditorDates([formatDateInput(date)])\n setEditorWeekday(date.getDay())\n setEditorWindows(windows.length ? windows : [createDefaultWindow()])\n } else {\n const weekday = options?.weekday ?? new Date().getDay()\n const windows = buildWindowsFromRules(rules)\n setEditorWeekday(weekday)\n setEditorDates([])\n setEditorWindows(windows.length ? windows : [createDefaultWindow()])\n setEditorUnavailable(false)\n setEditorNote('')\n setEditorReasonEntryId(null)\n setEditorReasonValue('')\n }\n setEditorOpen(true)\n }, [isReadOnly])\n\n const handleEditorWindowChange = React.useCallback((index: number, window: TimeWindow) => {\n setEditorWindows((prev) => {\n const next = [...prev]\n next[index] = window\n return next\n })\n }, [])\n\n const handleEditorWindowAdd = React.useCallback(() => {\n setEditorWindows((prev) => [...prev, buildNextWindow(prev)])\n }, [])\n\n const handleEditorWindowRemove = React.useCallback((index: number) => {\n setEditorWindows((prev) => prev.filter((_, idx) => idx !== index))\n }, [])\n\n const handleEditorDateAdd = React.useCallback(() => {\n setEditorDates((prev) => {\n const lastValue = [...prev].reverse().find((value) => value && value.length) ?? ''\n const base = lastValue ? parseDateInput(lastValue) : null\n const nextBase = base ?? new Date()\n const nextDate = new Date(nextBase.getFullYear(), nextBase.getMonth(), nextBase.getDate() + 1)\n return [...prev, formatDateInput(nextDate)]\n })\n }, [])\n\n const handleEditorDateChange = React.useCallback((index: number, value: string) => {\n setEditorDates((prev) => {\n const next = [...prev]\n next[index] = value\n return next\n })\n }, [])\n\n const handleEditorDateRemove = React.useCallback((index: number) => {\n setEditorDates((prev) => prev.filter((_, idx) => idx !== index))\n }, [])\n\n const editorWindowErrors = React.useMemo(\n () => (editorUnavailable ? [] : editorWindows.map((window) => getWindowError(window, listLabels))),\n [editorUnavailable, editorWindows, listLabels],\n )\n\n const handleEditorSubmit = React.useCallback(async () => {\n if (isReadOnly) return\n if (editorUnavailable && !canManageUnavailability) return\n const subjectForRules: AvailabilitySubjectType = usingRuleSet ? 'ruleset' : subjectType\n const subjectIdForRules = usingRuleSet ? (rulesetId ?? '') : subjectId\n if (!subjectIdForRules) return\n if (!editorUnavailable && editorWindowErrors.some(Boolean)) return\n const validWindows = editorWindows\n\n try {\n const dates = Array.from(new Set(editorDates.filter((value) => value && value.length)))\n if (editorScope === 'date') {\n const trimmedNote = editorNote.trim()\n const reasonEntryId = editorUnavailable ? editorReasonEntryId : null\n const fallbackReasonValue = editorReasonValue.trim()\n const reasonValue = reasonEntryId\n ? (reasonEntriesById[reasonEntryId]?.value ?? (fallbackReasonValue || null))\n : null\n const payload: Record<string, unknown> = {\n subjectType: subjectForRules,\n subjectId: subjectIdForRules,\n timezone,\n dates,\n windows: editorUnavailable ? [] : validWindows,\n kind: editorUnavailable ? 'unavailability' : 'availability',\n note: editorUnavailable && trimmedNote.length ? trimmedNote : null,\n unavailabilityReasonEntryId: editorUnavailable ? reasonEntryId : null,\n unavailabilityReasonValue: editorUnavailable ? reasonValue : null,\n }\n await apiCallOrThrow('/api/planner/availability-date-specific', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n }, { errorMessage: listLabels.saveDateError })\n } else {\n const rulesToDelete = editorRules\n const uniqueRuleIds = Array.from(new Set(rulesToDelete.map((rule) => rule.id)))\n await Promise.all(\n uniqueRuleIds.map((id) => deleteCrud('planner/availability', id, { errorMessage: listLabels.saveDateError })),\n )\n\n const creations: Array<Promise<unknown>> = []\n validWindows.forEach((window) => {\n const start = toDateForWeekday(editorWeekday, window.start)\n const end = toDateForWeekday(editorWeekday, window.end)\n if (!start || !end) return\n const rrule = buildAvailabilityRrule(start, end, 'weekly')\n creations.push(createCrud('planner/availability', {\n subjectType: subjectForRules,\n subjectId: subjectIdForRules,\n timezone,\n rrule,\n exdates: [],\n kind: 'availability',\n note: null,\n }, { errorMessage: listLabels.saveDateError }))\n })\n await Promise.all(creations)\n }\n flash(listLabels.saveDateSuccess, 'success')\n setEditorOpen(false)\n setEditorRules([])\n await refreshAvailability()\n await refreshRuleSetRules()\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.saveDateError\n flash(message, 'error')\n }\n }, [\n editorDates,\n editorRules,\n editorScope,\n editorUnavailable,\n editorNote,\n editorReasonEntryId,\n editorReasonValue,\n editorWeekday,\n editorWindowErrors,\n editorWindows,\n listLabels.saveDateError,\n listLabels.saveDateSuccess,\n refreshAvailability,\n refreshRuleSetRules,\n reasonEntriesById,\n rulesetId,\n subjectId,\n subjectType,\n timezone,\n usingRuleSet,\n canManageUnavailability,\n isReadOnly,\n ])\n\n const handleSlotClick = React.useCallback((slot: ScheduleSlot) => {\n if (usingRuleSet || isReadOnly) return\n openEditor('date', { date: slot.start })\n }, [openEditor, usingRuleSet, isReadOnly])\n\n const handleItemClick = React.useCallback((item: ScheduleItem) => {\n if (usingRuleSet || isReadOnly) return\n const rule = item.metadata?.rule as AvailabilityRule | undefined\n if (!rule) return\n const window = parseAvailabilityRuleWindow(rule)\n if (window.repeat === 'weekly') {\n const weekday = window.startAt.getDay()\n const rules = activeRules.filter((candidate) => {\n const candidateWindow = parseAvailabilityRuleWindow(candidate)\n return candidateWindow.repeat === 'weekly' && candidateWindow.startAt.getDay() === weekday\n })\n openEditor('weekday', { weekday, rules })\n } else {\n const dateKey = formatDateInput(window.startAt)\n const rules = activeRules.filter((candidate) => {\n const candidateWindow = parseAvailabilityRuleWindow(candidate)\n return candidateWindow.repeat === 'once' && formatDateInput(candidateWindow.startAt) === dateKey\n })\n openEditor('date', { date: window.startAt, rules })\n }\n }, [activeRules, openEditor, usingRuleSet, isReadOnly])\n\n return (\n <>\n <div className=\"rounded-xl border bg-card p-4 shadow-sm\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div>\n <h2 className=\"text-lg font-semibold text-foreground\">\n {listLabels.title}\n </h2>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setViewMode('list')}\n aria-label={listLabels.listLabel}\n title={listLabels.listLabel}\n className={viewMode === 'list' ? 'bg-accent text-accent-foreground' : undefined}\n >\n <List className=\"size-4\" aria-hidden />\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setViewMode('calendar')}\n aria-label={listLabels.calendarLabel}\n title={listLabels.calendarLabel}\n className={viewMode === 'calendar' ? 'bg-accent text-accent-foreground' : undefined}\n >\n <Calendar className=\"size-4\" aria-hidden />\n </Button>\n </div>\n </div>\n\n <div className=\"mt-4 space-y-3 rounded-lg border bg-muted/30 p-3\">\n {onRulesetChange ? (\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {listLabels.ruleSetLabel}\n </label>\n {ruleSetsLoading ? (\n <span className=\"text-xs text-muted-foreground\">{listLabels.ruleSetLoading}</span>\n ) : (\n <Select\n value={rulesetId || undefined}\n onValueChange={(value) => {\n void handleRuleSetChange(value ? value : null)\n }}\n disabled={isReadOnly}\n >\n <SelectTrigger size=\"sm\" className=\"w-auto min-w-[10rem]\">\n <SelectValue placeholder={listLabels.ruleSetPlaceholder} />\n </SelectTrigger>\n <SelectContent>\n {ruleSets.map((ruleSet) => (\n <SelectItem key={ruleSet.id} value={ruleSet.id}>\n {ruleSet.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setCreateRuleSetOpen(true)} disabled={isReadOnly}>\n <Plus className=\"size-4 mr-2\" aria-hidden />\n {listLabels.ruleSetCreateLabel}\n </Button>\n {rulesetId && usingRuleSet ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={handleCustomize} disabled={isReadOnly}>\n {listLabels.ruleSetCustomize}\n </Button>\n ) : null}\n {rulesetId && !usingRuleSet ? (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={handleResetToRuleSet} disabled={isReadOnly}>\n {listLabels.ruleSetReset}\n </Button>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span>{listLabels.timezoneLabel}</span>\n <div className=\"w-[220px]\">\n <ComboboxInput\n value={timezone}\n onChange={handleTimezoneChange}\n suggestions={timezoneOptions}\n placeholder={listLabels.timezonePlaceholder}\n allowCustomValues\n disabled={isReadOnly}\n />\n </div>\n </div>\n </div>\n\n <div className=\"mt-6\">\n {isLoading ? (\n <LoadingMessage label={listLabels.scheduleLoading} />\n ) : error ? (\n <ErrorMessage label={error} />\n ) : viewMode === 'calendar' ? (\n <ScheduleView\n items={scheduleItems}\n view={scheduleView}\n range={range}\n timezone={timezone}\n onRangeChange={setRange}\n onViewChange={setScheduleView}\n onTimezoneChange={handleTimezoneChange}\n onItemClick={handleItemClick}\n onSlotClick={handleSlotClick}\n />\n ) : (\n <div className=\"grid gap-6 lg:grid-cols-2\">\n {usingRuleSet ? (\n <div className=\"lg:col-span-2 rounded-lg border border-dashed p-4 text-sm text-muted-foreground\">\n {listLabels.customizePrompt}\n </div>\n ) : null}\n <section>\n <div className=\"flex items-center justify-between\">\n <div>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-base font-semibold\">{listLabels.weeklyTitle}</h3>\n {isWeeklyAutoSaving ? (\n <span className=\"inline-flex items-center gap-2 text-xs text-muted-foreground\">\n <Spinner size=\"sm\" />\n {t('ui.forms.status.saving', 'Saving...')}\n </span>\n ) : null}\n </div>\n <p className=\"text-sm text-muted-foreground\">{listLabels.weeklySubtitle}</p>\n </div>\n </div>\n <div className=\"mt-4 space-y-3\">\n {DAY_LABELS.map((day, index) => {\n const windows = weeklyWindows[index] ?? []\n return (\n <div key={day.code} className=\"flex flex-wrap items-start gap-3 rounded-lg border bg-background p-3\">\n <div className=\"flex w-10 justify-center\">\n <span className=\"flex h-8 w-8 items-center justify-center rounded-full bg-muted text-xs font-semibold\">\n {day.short}\n </span>\n </div>\n <div className=\"flex-1 space-y-2\">\n {windows.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">{listLabels.noHours}</p>\n ) : (\n windows.map((window, windowIndex) => {\n const windowError = weeklyWindowErrors[index]?.[windowIndex] ?? null\n const errorClass = windowError ? 'border-red-500 aria-invalid:ring-destructive' : ''\n return (\n <div key={`${day.code}-${windowIndex}`} className=\"space-y-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <TimePicker\n value={window.start}\n onChange={(value) => handleWeeklyWindowChange(index, windowIndex, { ...window, start: value ?? '' })}\n className={`w-[120px] ${errorClass}`}\n disabled={usingRuleSet || isReadOnly}\n showClearButton={false}\n />\n <span className=\"text-sm text-muted-foreground\">-</span>\n <TimePicker\n value={window.end}\n onChange={(value) => handleWeeklyWindowChange(index, windowIndex, { ...window, end: value ?? '' })}\n className={`w-[120px] ${errorClass}`}\n disabled={usingRuleSet || isReadOnly}\n showClearButton={false}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => handleWeeklyWindowRemove(index, windowIndex)}\n disabled={usingRuleSet || isReadOnly}\n aria-label={listLabels.removeWindow}\n >\n <Trash2 className=\"size-4\" aria-hidden />\n </Button>\n </div>\n {windowError ? (\n <div className=\"text-xs text-red-600\">{windowError}</div>\n ) : null}\n </div>\n )\n })\n )}\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => handleWeeklyWindowAdd(index)} disabled={usingRuleSet || isReadOnly}>\n <Plus className=\"size-4 mr-2\" aria-hidden />\n {listLabels.addWindow}\n </Button>\n </div>\n </div>\n )\n })}\n </div>\n </section>\n <section>\n <div className=\"flex items-center justify-between\">\n <div>\n <h3 className=\"text-base font-semibold\">{listLabels.dateSpecificTitle}</h3>\n <p className=\"text-sm text-muted-foreground\">{listLabels.dateSpecificSubtitle}</p>\n </div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => openEditor('date')} disabled={usingRuleSet || isReadOnly}>\n <Clock className=\"size-4 mr-2\" aria-hidden />\n {listLabels.addHours}\n </Button>\n </div>\n <div className=\"mt-4 space-y-3\">\n {Array.from(dateGroups.entries()).map(([date, rules]) => {\n const weekdayIndex = getWeekdayIndex(date)\n const weekdayLabel = weekdayIndex === null ? null : DAY_LABELS[weekdayIndex]\n const weekdayText = weekdayLabel ? t(weekdayLabel.nameKey, weekdayLabel.fallback) : date\n const weekdayShort = weekdayLabel ? weekdayLabel.short : '?'\n const unavailableRule = rules.find((rule) => rule.kind === 'unavailability')\n const unavailableReason = resolveRuleReasonValue(unavailableRule)\n const lockUnavailabilityActions = Boolean(unavailableRule) && !canManageUnavailability\n return (\n <div key={date} className=\"flex flex-wrap items-start gap-3 rounded-lg border bg-background p-3\">\n <div className=\"flex w-10 justify-center pt-1\">\n <span\n className=\"flex h-8 w-8 items-center justify-center rounded-full bg-muted text-xs font-semibold\"\n aria-label={weekdayText}\n title={weekdayText}\n >\n {weekdayShort}\n </span>\n </div>\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <div>\n <div className=\"flex items-center gap-2 text-sm font-semibold\">\n <Calendar className=\"size-4 text-muted-foreground\" aria-hidden />\n <span>{date}</span>\n </div>\n <div className=\"text-xs text-muted-foreground\">{weekdayText}</div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => openEditor('date', { date: new Date(`${date}T00:00:00`), rules })}\n disabled={usingRuleSet || isReadOnly || lockUnavailabilityActions}\n >\n <PencilLine className=\"size-4 mr-2\" aria-hidden />\n {listLabels.editTitle}\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={async () => {\n await Promise.all(rules.map((rule) => deleteCrud('planner/availability', rule.id)))\n await refreshAvailability()\n await refreshRuleSetRules()\n }}\n disabled={usingRuleSet || isReadOnly || lockUnavailabilityActions}\n aria-label={listLabels.removeWindow}\n >\n <Trash2 className=\"size-4\" aria-hidden />\n </Button>\n </div>\n </div>\n <div className=\"space-y-1 text-sm text-muted-foreground\">\n {unavailableRule ? (\n <div className=\"space-y-1\">\n <div className=\"font-medium text-foreground\">{listLabels.unavailableTitle}</div>\n {unavailableReason ? (\n <div className=\"text-xs text-muted-foreground\">{unavailableReason}</div>\n ) : null}\n {unavailableRule.note ? (\n <div className=\"text-xs text-muted-foreground\">{unavailableRule.note}</div>\n ) : null}\n </div>\n ) : (\n buildWindowsFromRules(rules).map((window, index) => (\n <div key={`${date}-${index}`}>\n {window.start} - {window.end}\n </div>\n ))\n )}\n </div>\n </div>\n </div>\n )\n })}\n </div>\n </section>\n </div>\n )}\n </div>\n </div>\n\n <Dialog\n open={editorOpen}\n onOpenChange={(open) => {\n if (!open) {\n setEditorOpen(false)\n setEditorRules([])\n setEditorUnavailable(false)\n setEditorNote('')\n setEditorReasonEntryId(null)\n setEditorReasonValue('')\n }\n }}\n >\n <DialogContent\n ref={dialogRef}\n onKeyDown={(event) => {\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n void handleEditorSubmit()\n }\n }}\n >\n <DialogHeader>\n <DialogTitle>\n {editorRules.length ? listLabels.editTitle : listLabels.addTitle}\n </DialogTitle>\n </DialogHeader>\n <CrudForm\n embedded\n fields={[\n {\n id: 'availabilityEditor',\n label: listLabels.applyScopeLabel,\n type: 'custom',\n component: () => (\n <div className=\"rounded-lg border bg-muted/30 p-4\">\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <div role=\"tablist\" aria-label={listLabels.applyScopeLabel} className=\"inline-flex rounded-lg border bg-muted p-1 text-xs\">\n <Button\n type=\"button\"\n role=\"tab\"\n aria-selected={editorScope === 'date'}\n variant=\"ghost\"\n size=\"sm\"\n className={`h-auto rounded-md px-3 py-1.5 font-medium ${\n editorScope === 'date'\n ? 'bg-background text-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n onClick={() => setEditorScope('date')}\n >\n {listLabels.applyScopeDate}\n </Button>\n <Button\n type=\"button\"\n role=\"tab\"\n aria-selected={editorScope === 'weekday'}\n variant=\"ghost\"\n size=\"sm\"\n className={`h-auto rounded-md px-3 py-1.5 font-medium ${\n editorScope === 'weekday'\n ? 'bg-background text-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n onClick={() => {\n setEditorScope('weekday')\n setEditorUnavailable(false)\n setEditorNote('')\n setEditorReasonEntryId(null)\n setEditorReasonValue('')\n }}\n >\n {listLabels.editAllLabel}\n </Button>\n </div>\n </div>\n\n {editorScope === 'date' ? (\n <div className=\"space-y-2\">\n {editorDates.map((value, index) => (\n <div key={`${value}-${index}`} className=\"flex items-center gap-2\">\n <Input\n type=\"date\"\n value={value}\n onChange={(event) => handleEditorDateChange(index, event.target.value)}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => handleEditorDateRemove(index)}\n aria-label={listLabels.removeWindow}\n >\n <Trash2 className=\"size-4\" aria-hidden />\n </Button>\n </div>\n ))}\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={handleEditorDateAdd}>\n <Plus className=\"size-4 mr-2\" aria-hidden />\n {listLabels.addDateLabel}\n </Button>\n <label\n htmlFor=\"availability-unavailable-toggle\"\n className=\"flex cursor-pointer items-start gap-2 pt-2 text-sm\"\n >\n <input\n id=\"availability-unavailable-toggle\"\n type=\"checkbox\"\n className=\"mt-0.5 size-4\"\n checked={editorUnavailable}\n disabled={!canManageUnavailability}\n onChange={(event) => {\n const checked = event.target.checked\n setEditorUnavailable(checked)\n if (!checked) {\n setEditorNote('')\n setEditorReasonEntryId(null)\n setEditorReasonValue('')\n }\n }}\n />\n <div>\n <div className=\"font-medium text-foreground\">{listLabels.unavailableLabel}</div>\n <div className=\"text-xs text-muted-foreground\">{listLabels.unavailableHelp}</div>\n </div>\n </label>\n {editorUnavailable ? (\n <div className=\"space-y-3\">\n <div className=\"space-y-2\">\n <label className=\"text-xs font-medium text-muted-foreground\">{listLabels.unavailableReasonLabel}</label>\n <DictionaryEntrySelect\n value={editorReasonEntryId ?? undefined}\n onChange={(next) => {\n setEditorReasonEntryId(next ?? null)\n setEditorReasonValue('')\n }}\n fetchOptions={fetchUnavailabilityReasonOptions}\n createOption={createUnavailabilityReasonOption}\n labels={unavailableReasonLabels}\n selectClassName=\"w-full\"\n manageHref=\"/backend/config/dictionaries\"\n disabled={!canManageUnavailability}\n />\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-xs font-medium text-muted-foreground\">{listLabels.unavailableNoteLabel}</label>\n <Input\n type=\"text\"\n value={editorNote}\n placeholder={listLabels.unavailableNotePlaceholder}\n disabled={!canManageUnavailability}\n onChange={(event) => setEditorNote(event.target.value)}\n />\n </div>\n </div>\n ) : null}\n </div>\n ) : (\n <div className=\"space-y-2\">\n <label className=\"text-xs text-muted-foreground\">{listLabels.applyScopeWeekday}</label>\n <Select\n value={String(editorWeekday)}\n onValueChange={(value) => setEditorWeekday(Number(value))}\n >\n <SelectTrigger size=\"sm\" className=\"w-auto min-w-[8rem]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {DAY_LABELS.map((day, index) => (\n <SelectItem key={day.code} value={String(index)}>\n {t(day.nameKey, day.fallback)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n\n {editorUnavailable && editorScope === 'date' ? null : (\n <div className=\"space-y-2\">\n <label className=\"text-xs font-medium text-muted-foreground\">{listLabels.windowsLabel}</label>\n {editorWindows.map((window, index) => {\n const windowError = editorWindowErrors[index] ?? null\n const errorClass = windowError ? 'border-red-500 aria-invalid:ring-destructive' : ''\n return (\n <div key={`${index}-${window.start}`} className=\"space-y-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <TimePicker\n value={window.start}\n onChange={(value) => handleEditorWindowChange(index, { ...window, start: value ?? '' })}\n className={`w-[120px] ${errorClass}`}\n showClearButton={false}\n />\n <span className=\"text-sm text-muted-foreground\">-</span>\n <TimePicker\n value={window.end}\n onChange={(value) => handleEditorWindowChange(index, { ...window, end: value ?? '' })}\n className={`w-[120px] ${errorClass}`}\n showClearButton={false}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => handleEditorWindowRemove(index)}\n aria-label={listLabels.removeWindow}\n >\n <Trash2 className=\"size-4\" aria-hidden />\n </Button>\n </div>\n {windowError ? (\n <div className=\"text-xs text-red-600\">{windowError}</div>\n ) : null}\n </div>\n )\n })}\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={handleEditorWindowAdd}>\n <Plus className=\"size-4 mr-2\" aria-hidden />\n {listLabels.addWindow}\n </Button>\n </div>\n )}\n </div>\n </div>\n ),\n },\n ]}\n onSubmit={handleEditorSubmit}\n submitLabel={listLabels.applyLabel}\n extraActions={(\n <Button type=\"button\" variant=\"ghost\" onClick={() => setEditorOpen(false)}>\n {listLabels.cancelLabel}\n </Button>\n )}\n />\n </DialogContent>\n </Dialog>\n\n <Dialog\n open={createRuleSetOpen}\n onOpenChange={(open) => setCreateRuleSetOpen(open)}\n >\n <DialogContent\n ref={createRuleSetDialogRef}\n onKeyDown={(event) => {\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n const form = createRuleSetDialogRef.current?.querySelector('form')\n form?.requestSubmit()\n }\n }}\n >\n <DialogHeader>\n <DialogTitle>{listLabels.ruleSetCreateTitle}</DialogTitle>\n </DialogHeader>\n <CrudForm<RuleSetFormValues>\n embedded\n schema={ruleSetFormSchema}\n fields={ruleSetFormFields}\n initialValues={ruleSetInitialValues}\n onSubmit={handleCreateRuleSet}\n submitLabel={listLabels.ruleSetCreateSubmit}\n extraActions={(\n <Button type=\"button\" variant=\"ghost\" onClick={() => setCreateRuleSetOpen(false)}>\n {listLabels.cancelLabel}\n </Button>\n )}\n />\n </DialogContent>\n </Dialog>\n {ConfirmDialogElement}\n </>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { ScheduleView, type ScheduleItem, type ScheduleRange, type ScheduleSlot, type ScheduleViewMode } from '@open-mercato/ui/backend/schedule'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '@open-mercato/ui/primitives/dialog'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'\nimport { apiCall, apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { createCrud, deleteCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { ComboboxInput, TimePicker } from '@open-mercato/ui/backend/inputs'\nimport { DictionaryEntrySelect, type DictionarySelectLabels } from '@open-mercato/core/modules/dictionaries/components/DictionaryEntrySelect'\nimport {\n createUnavailabilityReasonEntry,\n loadUnavailabilityReasonEntries,\n type UnavailabilityReasonEntry,\n} from '@open-mercato/core/modules/planner/components/unavailabilityReasons'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { parseAvailabilityRuleWindow } from '@open-mercato/core/modules/planner/lib/availabilitySchedule'\nimport { CrudForm, type CrudField } from '@open-mercato/ui/backend/CrudForm'\nimport { Calendar, Clock, List, PencilLine, Plus, Trash2 } from 'lucide-react'\nimport { resolveRuleSetSelectValue } from './availabilityRulesEditorState'\n\ntype AvailabilityRepeat = 'once' | 'daily' | 'weekly'\ntype AvailabilitySubjectType = 'member' | 'resource' | 'ruleset'\n\ntype AvailabilityRule = {\n id: string\n subjectType: AvailabilitySubjectType\n subjectId: string\n timezone: string\n rrule: string\n exdates: string[]\n kind?: 'availability' | 'unavailability'\n note?: string | null\n unavailabilityReasonEntryId?: string | null\n unavailabilityReasonValue?: string | null\n createdAt?: string | null\n}\n\ntype AvailabilityRuleSet = {\n id: string\n name: string\n timezone: string\n}\n\nexport type AvailabilityBookedEvent = {\n id: string\n title: string\n startsAt: string | Date\n endsAt: string | Date\n}\n\nexport type AvailabilityScheduleItemBuilder = (params: {\n availabilityRules: AvailabilityRule[]\n bookedEvents: AvailabilityBookedEvent[]\n translate: (key: string, fallback?: string) => string\n}) => ScheduleItem[]\n\nexport type AvailabilityRulesEditorProps = {\n subjectType: AvailabilitySubjectType\n subjectId: string\n labelPrefix: string\n mode?: 'availability' | 'unavailability'\n initialTimezone?: string\n rulesetId?: string | null\n onRulesetChange?: (rulesetId: string | null) => Promise<void>\n buildScheduleItems: AvailabilityScheduleItemBuilder\n loadBookedEvents?: (range: ScheduleRange) => Promise<AvailabilityBookedEvent[]>\n readOnly?: boolean\n allowUnavailability?: boolean\n}\n\ntype TimeWindow = { start: string; end: string }\ntype RuleSetFormValues = {\n name: string\n}\ntype WeeklyWindows = TimeWindow[][]\n\nconst DAY_LABELS = [\n { code: 'SU', short: 'S', nameKey: 'schedule.weekday.sunday', fallback: 'Sunday' },\n { code: 'MO', short: 'M', nameKey: 'schedule.weekday.monday', fallback: 'Monday' },\n { code: 'TU', short: 'T', nameKey: 'schedule.weekday.tuesday', fallback: 'Tuesday' },\n { code: 'WE', short: 'W', nameKey: 'schedule.weekday.wednesday', fallback: 'Wednesday' },\n { code: 'TH', short: 'T', nameKey: 'schedule.weekday.thursday', fallback: 'Thursday' },\n { code: 'FR', short: 'F', nameKey: 'schedule.weekday.friday', fallback: 'Friday' },\n { code: 'SA', short: 'S', nameKey: 'schedule.weekday.saturday', fallback: 'Saturday' },\n] as const\n\nconst DEFAULT_WINDOW: TimeWindow = { start: '09:00', end: '17:00' }\n\nfunction resolveRuleReasonEntryId(rule?: AvailabilityRule | null): string | null {\n if (!rule) return null\n if (typeof rule.unavailabilityReasonEntryId === 'string' && rule.unavailabilityReasonEntryId.length) {\n return rule.unavailabilityReasonEntryId\n }\n const fallback = (rule as Record<string, unknown>).unavailability_reason_entry_id\n return typeof fallback === 'string' && fallback.length ? fallback : null\n}\n\nfunction resolveRuleReasonValue(rule?: AvailabilityRule | null): string | null {\n if (!rule) return null\n if (typeof rule.unavailabilityReasonValue === 'string' && rule.unavailabilityReasonValue.length) {\n return rule.unavailabilityReasonValue\n }\n const fallback = (rule as Record<string, unknown>).unavailability_reason_value\n return typeof fallback === 'string' && fallback.length ? fallback : null\n}\n\nfunction createDefaultWindow(): TimeWindow {\n return { ...DEFAULT_WINDOW }\n}\n\nfunction getDefaultWindowDurationMinutes(): number {\n const start = parseTimeInput(DEFAULT_WINDOW.start)\n const end = parseTimeInput(DEFAULT_WINDOW.end)\n if (!start || !end) return 60\n const minutes = end.hours * 60 + end.minutes - (start.hours * 60 + start.minutes)\n return Math.max(1, minutes)\n}\n\nfunction formatTimeFromMinutes(totalMinutes: number): string {\n const clamped = Math.max(0, Math.min(23 * 60 + 59, totalMinutes))\n const hours = String(Math.floor(clamped / 60)).padStart(2, '0')\n const minutes = String(clamped % 60).padStart(2, '0')\n return `${hours}:${minutes}`\n}\n\nfunction buildNextWindow(windows: TimeWindow[]): TimeWindow {\n if (windows.length === 0) return createDefaultWindow()\n const lastWindow = windows[windows.length - 1]\n const end = parseTimeInput(lastWindow.end)\n if (!end) return createDefaultWindow()\n const startMinutes = end.hours * 60 + end.minutes\n if (startMinutes >= 23 * 60 + 59) return createDefaultWindow()\n const durationMinutes = getDefaultWindowDurationMinutes()\n const endMinutes = Math.min(startMinutes + durationMinutes, 23 * 60 + 59)\n if (endMinutes <= startMinutes) return createDefaultWindow()\n return {\n start: formatTimeFromMinutes(startMinutes),\n end: formatTimeFromMinutes(endMinutes),\n }\n}\n\nfunction getTimezoneOptions(): string[] {\n const options = new Set<string>()\n const resolved = Intl.DateTimeFormat().resolvedOptions().timeZone\n if (resolved) options.add(resolved)\n options.add('UTC')\n const intlWithSupportedValues = Intl as typeof Intl & { supportedValuesOf?: (input: 'timeZone') => string[] }\n if (typeof intlWithSupportedValues.supportedValuesOf === 'function') {\n intlWithSupportedValues.supportedValuesOf('timeZone').forEach((timezone) => {\n if (timezone) options.add(timezone)\n })\n }\n return Array.from(options).sort((a, b) => a.localeCompare(b))\n}\n\nfunction formatTimeInput(value: Date): string {\n const hours = String(value.getHours()).padStart(2, '0')\n const minutes = String(value.getMinutes()).padStart(2, '0')\n return `${hours}:${minutes}`\n}\n\nfunction formatDateInput(value: Date): string {\n const year = value.getFullYear()\n const month = String(value.getMonth() + 1).padStart(2, '0')\n const day = String(value.getDate()).padStart(2, '0')\n return `${year}-${month}-${day}`\n}\n\nfunction parseDateInput(value: string): Date | null {\n const [year, month, day] = value.split('-').map((part) => Number(part))\n if (!Number.isFinite(year) || !Number.isFinite(month) || !Number.isFinite(day)) return null\n const date = new Date(year, month - 1, day)\n if (Number.isNaN(date.getTime())) return null\n return date\n}\n\nfunction parseTimeInput(value: string): { hours: number; minutes: number } | null {\n const [hours, minutes] = value.split(':').map((part) => Number(part))\n if (!Number.isFinite(hours) || !Number.isFinite(minutes)) return null\n if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null\n return { hours, minutes }\n}\n\nfunction toDateForWeekday(weekday: number, time: string): Date | null {\n const parsed = parseTimeInput(time)\n if (!parsed) return null\n const now = new Date()\n const base = new Date(now.getFullYear(), now.getMonth(), now.getDate())\n const diff = (weekday - base.getDay() + 7) % 7\n const target = new Date(base.getTime() + diff * 24 * 60 * 60 * 1000)\n target.setHours(parsed.hours, parsed.minutes, 0, 0)\n return target\n}\n\nfunction toDateForDay(value: string, time: string): Date | null {\n if (!value) return null\n const parsed = parseTimeInput(time)\n if (!parsed) return null\n const parts = value.split('-').map((part) => Number(part))\n if (parts.length !== 3 || parts.some((part) => Number.isNaN(part))) return null\n const [year, month, day] = parts\n const date = new Date(year, month - 1, day, parsed.hours, parsed.minutes, 0, 0)\n return Number.isNaN(date.getTime()) ? null : date\n}\n\nfunction getWeekdayIndex(value: string): number | null {\n const date = toDateForDay(value, '00:00')\n return date ? date.getDay() : null\n}\n\nfunction getWindowError(window: TimeWindow, labels: { windowErrorRequired: string; windowErrorRange: string }): string | null {\n const start = parseTimeInput(window.start)\n const end = parseTimeInput(window.end)\n if (!start || !end) return labels.windowErrorRequired\n if (start.hours > end.hours || (start.hours === end.hours && start.minutes >= end.minutes)) {\n return labels.windowErrorRange\n }\n return null\n}\n\nfunction formatDuration(minutes: number): string {\n const clamped = Math.max(1, minutes)\n const hours = Math.floor(clamped / 60)\n const mins = clamped % 60\n if (hours > 0 && mins > 0) return `PT${hours}H${mins}M`\n if (hours > 0) return `PT${hours}H`\n return `PT${mins}M`\n}\n\nfunction buildAvailabilityRrule(start: Date, end: Date, repeat: AvailabilityRepeat): string {\n const dtStart = start.toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z'\n const durationMinutes = Math.max(1, Math.round((end.getTime() - start.getTime()) / 60000))\n const duration = formatDuration(durationMinutes)\n let rule = ''\n if (repeat === 'once') {\n rule = 'FREQ=DAILY;COUNT=1'\n } else if (repeat === 'weekly') {\n const dayCode = DAY_LABELS[start.getDay()].code\n rule = `FREQ=WEEKLY;BYDAY=${dayCode}`\n } else {\n rule = 'FREQ=DAILY'\n }\n return `DTSTART:${dtStart}\\nDURATION:${duration}\\nRRULE:${rule}`\n}\n\nfunction groupRulesByDate(rules: AvailabilityRule[]): Map<string, AvailabilityRule[]> {\n const map = new Map<string, AvailabilityRule[]>()\n rules.forEach((rule) => {\n const window = parseAvailabilityRuleWindow(rule)\n const key = formatDateInput(window.startAt)\n const list = map.get(key) ?? []\n list.push(rule)\n map.set(key, list)\n })\n return map\n}\n\nfunction buildWindowsFromRules(rules: AvailabilityRule[]): TimeWindow[] {\n return rules\n .map((rule) => {\n const window = parseAvailabilityRuleWindow(rule)\n return {\n start: formatTimeInput(window.startAt),\n end: formatTimeInput(window.endAt),\n }\n })\n .sort((a, b) => a.start.localeCompare(b.start))\n}\n\nfunction createEmptyWeeklyWindows(): WeeklyWindows {\n return Array.from({ length: 7 }, () => [])\n}\n\nfunction cloneWeeklyWindows(windows: WeeklyWindows): WeeklyWindows {\n return windows.map((dayWindows) => dayWindows.map((window) => ({ ...window })))\n}\n\nfunction normalizeWeeklyWindows(windows: WeeklyWindows): WeeklyWindows {\n return windows.map((dayWindows) => {\n const unique = new Map<string, TimeWindow>()\n dayWindows.forEach((window) => {\n if (!window.start || !window.end) return\n const key = `${window.start}-${window.end}`\n if (!unique.has(key)) unique.set(key, { start: window.start, end: window.end })\n })\n return Array.from(unique.values()).sort((left, right) => left.start.localeCompare(right.start))\n })\n}\n\nfunction buildWeeklyDraft(rules: AvailabilityRule[]): WeeklyWindows {\n const draft = createEmptyWeeklyWindows()\n rules.forEach((rule) => {\n const window = parseAvailabilityRuleWindow(rule)\n const repeat = window.repeat\n if (repeat === 'once') return\n const windowValue = {\n start: formatTimeInput(window.startAt),\n end: formatTimeInput(window.endAt),\n }\n if (repeat === 'daily') {\n for (let day = 0; day < 7; day += 1) {\n draft[day].push(windowValue)\n }\n return\n }\n const day = window.startAt.getDay()\n draft[day].push(windowValue)\n })\n return normalizeWeeklyWindows(draft)\n}\n\nfunction serializeWeeklyWindows(windows: WeeklyWindows): string {\n const payload = windows.map((dayWindows) => dayWindows.map((window) => ({ start: window.start, end: window.end })))\n return JSON.stringify(payload)\n}\n\nfunction buildWeeklyPayload(windows: WeeklyWindows): Array<{ weekday: number; start: string; end: string }> {\n const payload: Array<{ weekday: number; start: string; end: string }> = []\n const seen = new Set<string>()\n windows.forEach((dayWindows, day) => {\n dayWindows.forEach((window) => {\n const start = toDateForWeekday(day, window.start)\n const end = toDateForWeekday(day, window.end)\n if (!start || !end || start >= end) return\n const key = `${day}:${window.start}:${window.end}`\n if (seen.has(key)) return\n seen.add(key)\n payload.push({ weekday: day, start: window.start, end: window.end })\n })\n })\n return payload\n}\n\nexport function AvailabilityRulesEditor({\n subjectType,\n subjectId,\n labelPrefix,\n mode: _mode = 'availability',\n initialTimezone,\n rulesetId,\n onRulesetChange,\n buildScheduleItems,\n loadBookedEvents,\n readOnly,\n allowUnavailability,\n}: AvailabilityRulesEditorProps) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const isReadOnly = Boolean(readOnly)\n const canManageUnavailability = allowUnavailability ?? true\n const dialogRef = React.useRef<HTMLDivElement | null>(null)\n const createRuleSetDialogRef = React.useRef<HTMLDivElement | null>(null)\n const [availabilityRules, setAvailabilityRules] = React.useState<AvailabilityRule[]>([])\n const [rulesetRules, setRulesetRules] = React.useState<AvailabilityRule[]>([])\n const [availabilityLoading, setAvailabilityLoading] = React.useState(true)\n const [availabilityError, setAvailabilityError] = React.useState<string | null>(null)\n const [ruleSets, setRuleSets] = React.useState<AvailabilityRuleSet[]>([])\n const [ruleSetsLoading, setRuleSetsLoading] = React.useState(false)\n const [bookedEvents, setBookedEvents] = React.useState<AvailabilityBookedEvent[]>([])\n const [bookedLoading, setBookedLoading] = React.useState(false)\n const [bookedError, setBookedError] = React.useState<string | null>(null)\n const [viewMode, setViewMode] = React.useState<'list' | 'calendar'>('list')\n const [scheduleView, setScheduleView] = React.useState<ScheduleViewMode>('month')\n const [range, setRange] = React.useState<ScheduleRange>(() => {\n const now = new Date()\n const start = new Date(now.getFullYear(), now.getMonth(), 1)\n const end = new Date(now.getFullYear(), now.getMonth() + 1, 0)\n return { start, end }\n })\n const [timezone, setTimezone] = React.useState<string>(\n () => initialTimezone ?? (Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC'),\n )\n const [timezoneDirty, setTimezoneDirty] = React.useState(false)\n const [editorOpen, setEditorOpen] = React.useState(false)\n const [editorScope, setEditorScope] = React.useState<'date' | 'weekday'>('date')\n const [editorDates, setEditorDates] = React.useState<string[]>([])\n const [editorWeekday, setEditorWeekday] = React.useState<number>(new Date().getDay())\n const [editorWindows, setEditorWindows] = React.useState<TimeWindow[]>([createDefaultWindow()])\n const [editorRules, setEditorRules] = React.useState<AvailabilityRule[]>([])\n const [editorUnavailable, setEditorUnavailable] = React.useState(false)\n const [editorNote, setEditorNote] = React.useState('')\n const [editorReasonEntryId, setEditorReasonEntryId] = React.useState<string | null>(null)\n const [editorReasonValue, setEditorReasonValue] = React.useState('')\n const [reasonEntriesById, setReasonEntriesById] = React.useState<Record<string, UnavailabilityReasonEntry>>({})\n const [createRuleSetOpen, setCreateRuleSetOpen] = React.useState(false)\n const [isWeeklyAutoSaving, setIsWeeklyAutoSaving] = React.useState(false)\n const [customOverridesEnabled, setCustomOverridesEnabled] = React.useState(false)\n const [selectedRulesetId, setSelectedRulesetId] = React.useState<string | null>(rulesetId ?? null)\n const autoSaveTimerRef = React.useRef<number | null>(null)\n const lastSavedWeeklyKeyRef = React.useRef<string | null>(null)\n const weeklySaveStateRef = React.useRef({ inFlight: false, queued: false })\n const timezoneSaveTimerRef = React.useRef<number | null>(null)\n const timezoneSaveInFlightRef = React.useRef(false)\n const viewModeRef = React.useRef(viewMode)\n const saveWeeklyRef = React.useRef<\n ((options?: { silentSuccess?: boolean; skipRefresh?: boolean }) => Promise<void>) | null\n >(null)\n const timezoneOptions = React.useMemo(() => getTimezoneOptions(), [])\n\n React.useEffect(() => {\n setSelectedRulesetId(rulesetId ?? null)\n }, [rulesetId])\n\n const effectiveRulesetId = selectedRulesetId\n const usingRuleSet = Boolean(effectiveRulesetId) && availabilityRules.length === 0 && !customOverridesEnabled\n const activeRules = usingRuleSet ? rulesetRules : availabilityRules\n const scheduleRules = React.useMemo(() => {\n const dateBlockers = new Set<string>()\n activeRules.forEach((rule) => {\n if (rule.kind !== 'unavailability') return\n const window = parseAvailabilityRuleWindow(rule)\n if (window.repeat !== 'once') return\n dateBlockers.add(formatDateInput(window.startAt))\n })\n if (!dateBlockers.size) return activeRules\n return activeRules.filter((rule) => {\n const window = parseAvailabilityRuleWindow(rule)\n if (window.repeat !== 'once') return true\n if (rule.kind === 'unavailability') return true\n return !dateBlockers.has(formatDateInput(window.startAt))\n })\n }, [activeRules])\n const scheduleItems = React.useMemo(\n () => buildScheduleItems({ availabilityRules: scheduleRules, bookedEvents, translate: t }),\n [bookedEvents, buildScheduleItems, scheduleRules, t],\n )\n\n const listLabels = React.useMemo(() => {\n const modeBase = `${labelPrefix}.availability`\n return {\n title: t(`${labelPrefix}.availability.section.title`, 'Availability'),\n weeklyTitle: t(`${labelPrefix}.availability.weekly.title`, 'Weekly hours'),\n weeklySubtitle: t(`${labelPrefix}.availability.weekly.subtitle`, 'Set when you are typically available.'),\n dateSpecificTitle: t(`${labelPrefix}.availability.dateSpecific.title`, 'Date-specific hours'),\n dateSpecificSubtitle: t(`${labelPrefix}.availability.dateSpecific.subtitle`, 'Adjust hours for specific days.'),\n addHours: t(`${labelPrefix}.availability.dateSpecific.add`, 'Add hours'),\n timezoneLabel: t(`${labelPrefix}.availability.timezone`, 'Timezone'),\n timezonePlaceholder: t(`${labelPrefix}.availability.timezone.placeholder`, 'Search timezones...'),\n timezoneSaveError: t(`${labelPrefix}.availability.timezone.saveError`, 'Failed to save timezone.'),\n ruleSetLabel: t(`${labelPrefix}.availability.ruleset.label`, 'Schedule'),\n ruleSetPlaceholder: t(`${labelPrefix}.availability.ruleset.placeholder`, 'Custom schedule'),\n ruleSetCustomize: t(`${labelPrefix}.availability.ruleset.customize`, 'Customize schedule'),\n ruleSetReset: t(`${labelPrefix}.availability.ruleset.reset`, 'Reset to schedule'),\n ruleSetConfirm: t(`${labelPrefix}.availability.ruleset.confirm`, 'Changing the schedule will reset custom hours. Continue?'),\n ruleSetLoading: t(`${labelPrefix}.availability.ruleset.loading`, 'Loading schedules...'),\n ruleSetError: t(`${labelPrefix}.availability.ruleset.error`, 'Failed to load schedules.'),\n ruleSetCreateLabel: t(`${labelPrefix}.availability.ruleset.create`, 'New schedule'),\n ruleSetCreateTitle: t(`${labelPrefix}.availability.ruleset.createTitle`, 'Save as schedule'),\n ruleSetCreateSubmit: t(`${labelPrefix}.availability.ruleset.createSubmit`, 'Save schedule'),\n ruleSetCreateNameLabel: t(`${labelPrefix}.availability.ruleset.createName`, 'Schedule name'),\n ruleSetCreateTimezoneLabel: t(`${labelPrefix}.availability.ruleset.createTimezone`, 'Timezone'),\n ruleSetCreateSuccess: t(`${labelPrefix}.availability.ruleset.createSuccess`, 'Schedule saved.'),\n ruleSetCreateError: t(`${labelPrefix}.availability.ruleset.createError`, 'Failed to save schedule.'),\n editTitle: t(`${modeBase}.form.title.edit`, 'Edit availability'),\n addTitle: t(`${modeBase}.form.title.create`, 'Add availability'),\n applyLabel: t(`${labelPrefix}.availability.actions.apply`, 'Apply'),\n cancelLabel: t('ui.forms.actions.cancel', 'Cancel'),\n applyScopeLabel: t(`${labelPrefix}.availability.scope.label`, 'Apply to'),\n applyScopeDate: t(`${labelPrefix}.availability.scope.date`, 'This date'),\n applyScopeWeekday: t(`${labelPrefix}.availability.scope.weekday`, 'Weekday:'),\n windowsLabel: t(`${labelPrefix}.availability.windows.label`, 'What hours are you available?'),\n addWindow: t(`${labelPrefix}.availability.windows.add`, 'Add window'),\n removeWindow: t(`${labelPrefix}.availability.windows.remove`, 'Remove'),\n windowErrorRequired: t(`${labelPrefix}.availability.windows.errors.required`, 'Start and end times are required.'),\n windowErrorRange: t(`${labelPrefix}.availability.windows.errors.range`, 'End time must be after start.'),\n noHours: t(`${labelPrefix}.availability.weekly.empty`, 'Unavailable'),\n saveWeekly: t(`${labelPrefix}.availability.weekly.save`, 'Save weekly hours'),\n saveWeeklySuccess: t(`${labelPrefix}.availability.weekly.saved`, 'Weekly hours saved.'),\n saveWeeklyError: t(`${labelPrefix}.availability.weekly.error`, 'Failed to save weekly hours.'),\n saveDateSuccess: t(`${labelPrefix}.availability.dateSpecific.saved`, 'Date-specific hours saved.'),\n saveDateError: t(`${labelPrefix}.availability.dateSpecific.error`, 'Failed to save date-specific hours.'),\n unavailableLabel: t(`${labelPrefix}.availability.unavailable.label`, 'Unavailable on this day'),\n unavailableHelp: t(`${labelPrefix}.availability.unavailable.help`, 'Blocks availability for the entire day.'),\n unavailableTitle: t(`${labelPrefix}.availability.unavailable.title`, 'Unavailable'),\n unavailableNoteLabel: t(`${labelPrefix}.availability.unavailable.note`, 'Note'),\n unavailableNotePlaceholder: t(`${labelPrefix}.availability.unavailable.notePlaceholder`, 'Holiday'),\n unavailableReasonLabel: t(`${labelPrefix}.availability.unavailable.reason.label`, 'Reason'),\n unavailableReasonPlaceholder: t(`${labelPrefix}.availability.unavailable.reason.placeholder`, 'Select a reason'),\n unavailableReasonAddLabel: t(`${labelPrefix}.availability.unavailable.reason.addLabel`, 'Add reason'),\n unavailableReasonAddPrompt: t(`${labelPrefix}.availability.unavailable.reason.addPrompt`, 'Name the reason'),\n unavailableReasonDialogTitle: t(`${labelPrefix}.availability.unavailable.reason.dialogTitle`, 'Add reason'),\n unavailableReasonValueLabel: t(`${labelPrefix}.availability.unavailable.reason.valueLabel`, 'Reason'),\n unavailableReasonValuePlaceholder: t(`${labelPrefix}.availability.unavailable.reason.valuePlaceholder`, 'Reason name'),\n unavailableReasonLabelLabel: t(`${labelPrefix}.availability.unavailable.reason.labelLabel`, 'Label'),\n unavailableReasonLabelPlaceholder: t(`${labelPrefix}.availability.unavailable.reason.labelPlaceholder`, 'Display label (optional)'),\n unavailableReasonEmptyError: t(`${labelPrefix}.availability.unavailable.reason.emptyError`, 'Please enter a reason'),\n unavailableReasonSaveLabel: t(`${labelPrefix}.availability.unavailable.reason.saveLabel`, 'Save'),\n unavailableReasonErrorLoad: t(`${labelPrefix}.availability.unavailable.reason.errorLoad`, 'Failed to load reasons'),\n unavailableReasonErrorSave: t(`${labelPrefix}.availability.unavailable.reason.errorSave`, 'Failed to save reason'),\n unavailableReasonLoading: t(`${labelPrefix}.availability.unavailable.reason.loading`, 'Loading reasons...'),\n unavailableReasonManageTitle: t(`${labelPrefix}.availability.unavailable.reason.manageTitle`, 'Manage reasons'),\n scheduleError: t(`${labelPrefix}.schedule.error.load`, 'Failed to load schedule.'),\n scheduleLoading: t(`${labelPrefix}.schedule.loading`, 'Loading schedule...'),\n customizePrompt: t(`${labelPrefix}.availability.ruleset.customizePrompt`, 'This schedule is based on a shared ruleset. Customize it to make changes.'),\n calendarLabel: t(`${labelPrefix}.availability.view.calendar`, 'Calendar'),\n listLabel: t(`${labelPrefix}.availability.view.list`, 'List'),\n editAllLabel: t(`${labelPrefix}.availability.scope.weekdayShort`, 'All {{weekday}}s', { weekday: DAY_LABELS[editorWeekday].fallback }),\n addDateLabel: t(`${labelPrefix}.availability.dateSpecific.addDate`, 'Add date'),\n }\n }, [editorWeekday, labelPrefix, t])\n\n const unavailableReasonLabels = React.useMemo<DictionarySelectLabels>(() => ({\n placeholder: listLabels.unavailableReasonPlaceholder,\n addLabel: listLabels.unavailableReasonAddLabel,\n addPrompt: listLabels.unavailableReasonAddPrompt,\n dialogTitle: listLabels.unavailableReasonDialogTitle,\n valueLabel: listLabels.unavailableReasonValueLabel,\n valuePlaceholder: listLabels.unavailableReasonValuePlaceholder,\n labelLabel: listLabels.unavailableReasonLabelLabel,\n labelPlaceholder: listLabels.unavailableReasonLabelPlaceholder,\n emptyError: listLabels.unavailableReasonEmptyError,\n cancelLabel: listLabels.cancelLabel,\n saveLabel: listLabels.unavailableReasonSaveLabel,\n errorLoad: listLabels.unavailableReasonErrorLoad,\n errorSave: listLabels.unavailableReasonErrorSave,\n loadingLabel: listLabels.unavailableReasonLoading,\n manageTitle: listLabels.unavailableReasonManageTitle,\n }), [listLabels])\n\n const refreshAvailability = React.useCallback(async () => {\n if (!subjectId) return\n setAvailabilityLoading(true)\n setAvailabilityError(null)\n try {\n const params = new URLSearchParams({\n page: '1',\n pageSize: '100',\n subjectType,\n subjectIds: subjectId,\n })\n const call = await apiCall<{ items?: AvailabilityRule[] }>(`/api/planner/availability?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setAvailabilityRules(items)\n } catch (error) {\n const message = error instanceof Error ? error.message : t(`${labelPrefix}.availability.error.load`, 'Failed to load availability.')\n setAvailabilityError(message)\n } finally {\n setAvailabilityLoading(false)\n }\n }, [labelPrefix, subjectId, subjectType, t])\n\n const refreshRuleSetRules = React.useCallback(async () => {\n if (!effectiveRulesetId) {\n setRulesetRules([])\n return\n }\n try {\n const params = new URLSearchParams({\n page: '1',\n pageSize: '100',\n subjectType: 'ruleset',\n subjectIds: effectiveRulesetId,\n })\n const call = await apiCall<{ items?: AvailabilityRule[] }>(`/api/planner/availability?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setRulesetRules(items)\n } catch {\n setRulesetRules([])\n }\n }, [effectiveRulesetId])\n\n const refreshRuleSets = React.useCallback(async () => {\n if (!onRulesetChange) return\n setRuleSetsLoading(true)\n try {\n const params = new URLSearchParams({ page: '1', pageSize: '100' })\n const call = await apiCall<{ items?: AvailabilityRuleSet[] }>(`/api/planner/availability-rule-sets?${params.toString()}`)\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n setRuleSets(items)\n } catch {\n setRuleSets([])\n } finally {\n setRuleSetsLoading(false)\n }\n }, [onRulesetChange])\n\n const fetchUnavailabilityReasonOptions = React.useCallback(async () => {\n const entries = await loadUnavailabilityReasonEntries(subjectType)\n const map: Record<string, UnavailabilityReasonEntry> = {}\n entries.forEach((entry) => {\n map[entry.id] = entry\n })\n setReasonEntriesById(map)\n return entries.map((entry) => ({\n value: entry.id,\n label: entry.label ?? entry.value,\n color: entry.color,\n icon: entry.icon,\n }))\n }, [subjectType])\n\n const createUnavailabilityReasonOption = React.useCallback(async (input: { value: string; label?: string; color?: string | null; icon?: string | null }) => {\n const entry = await createUnavailabilityReasonEntry(subjectType, input)\n if (!entry) return null\n setReasonEntriesById((prev) => ({ ...prev, [entry.id]: entry }))\n return {\n value: entry.id,\n label: entry.label ?? entry.value,\n color: entry.color,\n icon: entry.icon,\n }\n }, [subjectType])\n\n React.useEffect(() => {\n if (!editorReasonEntryId) {\n if (editorReasonValue) setEditorReasonValue('')\n return\n }\n const entry = reasonEntriesById[editorReasonEntryId]\n if (entry && entry.value !== editorReasonValue) {\n setEditorReasonValue(entry.value)\n }\n }, [editorReasonEntryId, editorReasonValue, reasonEntriesById])\n\n React.useEffect(() => {\n void refreshAvailability()\n }, [refreshAvailability])\n\n React.useEffect(() => {\n void refreshRuleSetRules()\n }, [refreshRuleSetRules])\n\n React.useEffect(() => {\n if (viewMode !== 'calendar') return\n void refreshAvailability()\n void refreshRuleSetRules()\n }, [refreshAvailability, refreshRuleSetRules, viewMode])\n\n React.useEffect(() => {\n void refreshRuleSets()\n }, [refreshRuleSets])\n\n React.useEffect(() => {\n viewModeRef.current = viewMode\n }, [viewMode])\n\n React.useEffect(() => {\n if (timezoneDirty) return\n if (initialTimezone) {\n setTimezone(initialTimezone)\n return\n }\n const ruleTimezone = activeRules.find((rule) => rule.timezone)?.timezone\n if (ruleTimezone) setTimezone(ruleTimezone)\n }, [activeRules, initialTimezone, timezoneDirty])\n\n React.useEffect(() => {\n if (timezoneDirty) return\n if (!usingRuleSet || !effectiveRulesetId) return\n const ruleset = ruleSets.find((entry) => entry.id === effectiveRulesetId)\n if (ruleset?.timezone) setTimezone(ruleset.timezone)\n }, [effectiveRulesetId, ruleSets, timezoneDirty, usingRuleSet])\n\n React.useEffect(() => {\n if (availabilityRules.length > 0) {\n setCustomOverridesEnabled(true)\n }\n }, [availabilityRules.length])\n\n React.useEffect(() => {\n if (!effectiveRulesetId) {\n setCustomOverridesEnabled(false)\n }\n }, [effectiveRulesetId])\n\n const refreshBookedEvents = React.useCallback(async () => {\n if (!loadBookedEvents) return\n setBookedLoading(true)\n setBookedError(null)\n try {\n const items = await loadBookedEvents(range)\n setBookedEvents(Array.isArray(items) ? items : [])\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.scheduleError\n setBookedError(message)\n } finally {\n setBookedLoading(false)\n }\n }, [listLabels.scheduleError, loadBookedEvents, range])\n\n React.useEffect(() => {\n void refreshBookedEvents()\n }, [refreshBookedEvents])\n\n const weeklyDraft = React.useMemo(() => buildWeeklyDraft(activeRules), [activeRules])\n const [weeklyWindows, setWeeklyWindows] = React.useState<WeeklyWindows>(() => cloneWeeklyWindows(weeklyDraft))\n const weeklyWindowsRef = React.useRef<WeeklyWindows>(cloneWeeklyWindows(weeklyDraft))\n const weeklyDirtyRef = React.useRef(false)\n const weeklyDraftKey = React.useMemo(() => serializeWeeklyWindows(weeklyDraft), [weeklyDraft])\n const weeklyKey = React.useMemo(() => serializeWeeklyWindows(weeklyWindows), [weeklyWindows])\n const weeklyWindowErrors = React.useMemo(\n () => weeklyWindows.map((dayWindows) => dayWindows.map((window) => getWindowError(window, listLabels))),\n [listLabels, weeklyWindows],\n )\n const weeklyHasErrors = React.useMemo(\n () => weeklyWindowErrors.some((errors) => errors.some(Boolean)),\n [weeklyWindowErrors],\n )\n\n React.useEffect(() => {\n if (weeklyDirtyRef.current) return\n const nextWindows = cloneWeeklyWindows(weeklyDraft)\n setWeeklyWindows(nextWindows)\n weeklyWindowsRef.current = nextWindows\n }, [weeklyDraft])\n\n React.useEffect(() => {\n lastSavedWeeklyKeyRef.current = weeklyDraftKey\n }, [weeklyDraftKey])\n\n const dateSpecificRules = React.useMemo(\n () => activeRules.filter((rule) => parseAvailabilityRuleWindow(rule).repeat === 'once'),\n [activeRules],\n )\n const dateGroups = React.useMemo(() => groupRulesByDate(dateSpecificRules), [dateSpecificRules])\n\n const isLoading = availabilityLoading || bookedLoading\n const error = availabilityError ?? bookedError\n\n React.useEffect(() => {\n weeklyWindowsRef.current = weeklyWindows\n }, [weeklyWindows])\n\n const handleWeeklyWindowChange = React.useCallback((day: number, index: number, next: TimeWindow) => {\n weeklyDirtyRef.current = true\n setWeeklyWindows((prev) => {\n const nextWindows = prev.map((dayWindows) => [...dayWindows])\n const list = nextWindows[day] ?? []\n list[index] = next\n nextWindows[day] = list\n return nextWindows\n })\n }, [])\n\n const handleWeeklyWindowAdd = React.useCallback((day: number) => {\n weeklyDirtyRef.current = true\n setWeeklyWindows((prev) => {\n const nextWindows = prev.map((dayWindows) => [...dayWindows])\n const list = nextWindows[day] ?? []\n list.push(buildNextWindow(list))\n nextWindows[day] = list\n return nextWindows\n })\n }, [])\n\n const handleWeeklyWindowRemove = React.useCallback((day: number, index: number) => {\n weeklyDirtyRef.current = true\n setWeeklyWindows((prev) => {\n const nextWindows = prev.map((dayWindows) => [...dayWindows])\n const list = nextWindows[day] ?? []\n list.splice(index, 1)\n nextWindows[day] = list\n return nextWindows\n })\n }, [])\n\n const saveWeeklyHours = React.useCallback(async (options?: { silentSuccess?: boolean; skipRefresh?: boolean }) => {\n if (isReadOnly) return\n const subjectForRules: AvailabilitySubjectType = usingRuleSet ? 'ruleset' : subjectType\n const subjectIdForRules = usingRuleSet ? (effectiveRulesetId ?? '') : subjectId\n if (!subjectIdForRules) return\n if (weeklyHasErrors) return\n\n const shouldSkipRefresh = Boolean(options?.skipRefresh)\n setIsWeeklyAutoSaving(options?.silentSuccess === true)\n try {\n const windows = buildWeeklyPayload(normalizeWeeklyWindows(weeklyWindowsRef.current))\n await apiCallOrThrow('/api/planner/availability-weekly', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n subjectType: subjectForRules,\n subjectId: subjectIdForRules,\n timezone,\n windows,\n }),\n }, { errorMessage: listLabels.saveWeeklyError })\n lastSavedWeeklyKeyRef.current = weeklyKey\n weeklyDirtyRef.current = false\n if (!options?.silentSuccess) {\n flash(listLabels.saveWeeklySuccess, 'success')\n }\n if (!shouldSkipRefresh) {\n await refreshAvailability()\n await refreshRuleSetRules()\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.saveWeeklyError\n flash(message, 'error')\n } finally {\n setIsWeeklyAutoSaving(false)\n }\n }, [\n listLabels.saveWeeklyError,\n listLabels.saveWeeklySuccess,\n refreshAvailability,\n refreshRuleSetRules,\n effectiveRulesetId,\n subjectId,\n subjectType,\n timezone,\n usingRuleSet,\n weeklyHasErrors,\n weeklyKey,\n isReadOnly,\n ])\n\n React.useEffect(() => {\n saveWeeklyRef.current = saveWeeklyHours\n }, [saveWeeklyHours])\n\n const queueWeeklySave = React.useCallback((options?: { silentSuccess?: boolean; skipRefresh?: boolean }) => {\n if (weeklySaveStateRef.current.inFlight) {\n weeklySaveStateRef.current.queued = true\n return\n }\n weeklySaveStateRef.current.inFlight = true\n void (async () => {\n try {\n await saveWeeklyRef.current?.(options)\n } finally {\n weeklySaveStateRef.current.inFlight = false\n if (weeklySaveStateRef.current.queued) {\n weeklySaveStateRef.current.queued = false\n queueWeeklySave({ silentSuccess: true, skipRefresh: viewModeRef.current === 'list' })\n }\n }\n })()\n }, [])\n\n React.useEffect(() => {\n if (usingRuleSet) return\n if (weeklyHasErrors) return\n if (weeklyKey === lastSavedWeeklyKeyRef.current) return\n if (autoSaveTimerRef.current !== null) {\n window.clearTimeout(autoSaveTimerRef.current)\n }\n autoSaveTimerRef.current = window.setTimeout(() => {\n queueWeeklySave({ silentSuccess: true, skipRefresh: viewMode === 'list' })\n }, 600)\n return () => {\n if (autoSaveTimerRef.current !== null) {\n window.clearTimeout(autoSaveTimerRef.current)\n }\n }\n }, [queueWeeklySave, usingRuleSet, viewMode, weeklyHasErrors, weeklyKey])\n\n const persistTimezone = React.useCallback(async (nextTimezone: string) => {\n if (isReadOnly) return\n if (timezoneSaveInFlightRef.current) return\n const trimmedTimezone = nextTimezone.trim() || 'UTC'\n const rulesetTimezoneId = subjectType === 'ruleset' ? subjectId : effectiveRulesetId\n const rulesToUpdate = activeRules.filter((rule) => rule.timezone !== trimmedTimezone)\n if (!rulesToUpdate.length && !rulesetTimezoneId) {\n setTimezoneDirty(false)\n return\n }\n timezoneSaveInFlightRef.current = true\n try {\n const updates: Array<Promise<unknown>> = []\n rulesToUpdate.forEach((rule) => {\n updates.push(updateCrud('planner/availability', {\n id: rule.id,\n timezone: trimmedTimezone,\n }))\n })\n if (rulesetTimezoneId) {\n updates.push(updateCrud('planner/availability-rule-sets', {\n id: rulesetTimezoneId,\n timezone: trimmedTimezone,\n }))\n }\n if (updates.length) {\n await Promise.all(updates)\n await refreshAvailability()\n await refreshRuleSetRules()\n }\n setTimezoneDirty(false)\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.timezoneSaveError\n flash(message, 'error')\n setTimezoneDirty(false)\n } finally {\n timezoneSaveInFlightRef.current = false\n }\n }, [\n activeRules,\n listLabels.timezoneSaveError,\n refreshAvailability,\n refreshRuleSetRules,\n effectiveRulesetId,\n subjectId,\n subjectType,\n isReadOnly,\n ])\n\n React.useEffect(() => {\n if (!timezoneDirty) return\n const nextTimezone = timezone.trim()\n if (!nextTimezone) return\n if (timezoneSaveTimerRef.current !== null) {\n window.clearTimeout(timezoneSaveTimerRef.current)\n }\n timezoneSaveTimerRef.current = window.setTimeout(() => {\n void persistTimezone(nextTimezone)\n }, 400)\n return () => {\n if (timezoneSaveTimerRef.current !== null) {\n window.clearTimeout(timezoneSaveTimerRef.current)\n }\n }\n }, [persistTimezone, timezone, timezoneDirty])\n\n const handleTimezoneChange = React.useCallback((nextTimezone: string) => {\n if (isReadOnly) return\n const trimmed = nextTimezone.trim()\n setTimezone(trimmed || 'UTC')\n setTimezoneDirty(true)\n }, [canManageUnavailability, isReadOnly])\n\n const handleCustomize = React.useCallback(async () => {\n if (isReadOnly) return\n if (!effectiveRulesetId) return\n try {\n const creations = rulesetRules.map((rule) => createCrud('planner/availability', {\n subjectType,\n subjectId,\n timezone: rule.timezone,\n rrule: rule.rrule,\n exdates: rule.exdates ?? [],\n kind: rule.kind ?? 'availability',\n note: rule.note ?? null,\n }))\n await Promise.all(creations)\n setCustomOverridesEnabled(true)\n await refreshAvailability()\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.saveWeeklyError\n flash(message, 'error')\n }\n }, [effectiveRulesetId, listLabels.saveWeeklyError, refreshAvailability, rulesetRules, subjectId, subjectType, isReadOnly])\n\n const handleResetToRuleSet = React.useCallback(async () => {\n if (isReadOnly) return\n if (!effectiveRulesetId) return\n try {\n await Promise.all(\n availabilityRules.map((rule) => deleteCrud('planner/availability', rule.id, { errorMessage: listLabels.saveWeeklyError })),\n )\n setCustomOverridesEnabled(false)\n await refreshAvailability()\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.saveWeeklyError\n flash(message, 'error')\n }\n }, [availabilityRules, effectiveRulesetId, listLabels.saveWeeklyError, refreshAvailability, isReadOnly])\n\n const handleRuleSetChange = React.useCallback(async (nextId: string | null) => {\n if (isReadOnly) return\n if (!onRulesetChange) return\n if (availabilityRules.length > 0 && nextId !== effectiveRulesetId) {\n const confirmed = await confirm({\n title: listLabels.ruleSetConfirm,\n variant: 'default',\n })\n if (!confirmed) return\n await Promise.all(\n availabilityRules.map((rule) => deleteCrud('planner/availability', rule.id, { errorMessage: listLabels.saveWeeklyError })),\n )\n }\n setSelectedRulesetId(nextId)\n setCustomOverridesEnabled(false)\n try {\n await onRulesetChange(nextId)\n await refreshAvailability()\n } catch (error) {\n setSelectedRulesetId(effectiveRulesetId)\n throw error\n }\n }, [\n availabilityRules,\n confirm,\n effectiveRulesetId,\n listLabels.ruleSetConfirm,\n listLabels.saveWeeklyError,\n onRulesetChange,\n refreshAvailability,\n isReadOnly,\n ])\n\n const ruleSetFormSchema = React.useMemo(\n () => z.object({\n name: z.string().min(1, t('ui.forms.errors.required', 'Required')),\n }),\n [t],\n )\n\n const ruleSetFormFields = React.useMemo<CrudField[]>(() => [\n {\n id: 'name',\n label: listLabels.ruleSetCreateNameLabel,\n type: 'text',\n required: true,\n placeholder: listLabels.ruleSetCreateNameLabel,\n },\n ], [listLabels.ruleSetCreateNameLabel])\n\n const ruleSetInitialValues = React.useMemo<Partial<RuleSetFormValues>>(() => ({\n name: '',\n }), [])\n\n const handleCreateRuleSet = React.useCallback(async (values: RuleSetFormValues) => {\n if (isReadOnly) return\n const name = values.name.trim()\n const timezoneValue = timezone\n const response = await createCrud('planner/availability-rule-sets', {\n name,\n timezone: timezoneValue,\n description: null,\n }, { errorMessage: listLabels.ruleSetCreateError })\n const id = typeof response.result?.id === 'string' ? response.result.id : null\n if (!id) throw new Error(listLabels.ruleSetCreateError)\n const creations: Array<Promise<unknown>> = []\n const weeklyWindows = buildWeeklyPayload(normalizeWeeklyWindows(weeklyWindowsRef.current))\n weeklyWindows.forEach((window) => {\n const start = toDateForWeekday(window.weekday, window.start)\n const end = toDateForWeekday(window.weekday, window.end)\n if (!start || !end) return\n const rrule = buildAvailabilityRrule(start, end, 'weekly')\n creations.push(createCrud('planner/availability', {\n subjectType: 'ruleset',\n subjectId: id,\n timezone: timezoneValue,\n rrule,\n exdates: [],\n kind: 'availability',\n note: null,\n }, { errorMessage: listLabels.ruleSetCreateError }))\n })\n if (dateSpecificRules.length) {\n dateSpecificRules.forEach((rule) => {\n creations.push(createCrud('planner/availability', {\n subjectType: 'ruleset',\n subjectId: id,\n timezone: rule.timezone || timezoneValue,\n rrule: rule.rrule,\n exdates: rule.exdates ?? [],\n kind: rule.kind ?? 'availability',\n note: rule.note ?? null,\n unavailabilityReasonEntryId: resolveRuleReasonEntryId(rule),\n unavailabilityReasonValue: resolveRuleReasonValue(rule),\n }, { errorMessage: listLabels.ruleSetCreateError }))\n })\n }\n if (creations.length) {\n await Promise.all(creations)\n }\n await refreshRuleSets()\n if (onRulesetChange) {\n setSelectedRulesetId(id)\n await onRulesetChange(id)\n await refreshAvailability()\n }\n await refreshRuleSetRules()\n flash(listLabels.ruleSetCreateSuccess, 'success')\n setCreateRuleSetOpen(false)\n }, [\n activeRules,\n listLabels.ruleSetCreateError,\n listLabels.ruleSetCreateSuccess,\n dateSpecificRules,\n onRulesetChange,\n refreshAvailability,\n refreshRuleSetRules,\n refreshRuleSets,\n timezone,\n isReadOnly,\n ])\n\n const openEditor = React.useCallback((scope: 'date' | 'weekday', options?: { date?: Date; weekday?: number; rules?: AvailabilityRule[] }) => {\n if (isReadOnly) return\n setEditorScope(scope)\n const rules = options?.rules ?? []\n const unavailableRule = rules.find((rule) => rule.kind === 'unavailability')\n if (unavailableRule && !canManageUnavailability) return\n setEditorRules(rules)\n setEditorUnavailable(scope === 'date' && Boolean(unavailableRule))\n setEditorNote(unavailableRule?.note ?? '')\n setEditorReasonEntryId(scope === 'date' ? resolveRuleReasonEntryId(unavailableRule) : null)\n setEditorReasonValue(scope === 'date' ? (resolveRuleReasonValue(unavailableRule) ?? '') : '')\n if (scope === 'date') {\n const date = options?.date ?? new Date()\n const windows = buildWindowsFromRules(rules)\n setEditorDates([formatDateInput(date)])\n setEditorWeekday(date.getDay())\n setEditorWindows(windows.length ? windows : [createDefaultWindow()])\n } else {\n const weekday = options?.weekday ?? new Date().getDay()\n const windows = buildWindowsFromRules(rules)\n setEditorWeekday(weekday)\n setEditorDates([])\n setEditorWindows(windows.length ? windows : [createDefaultWindow()])\n setEditorUnavailable(false)\n setEditorNote('')\n setEditorReasonEntryId(null)\n setEditorReasonValue('')\n }\n setEditorOpen(true)\n }, [isReadOnly])\n\n const handleEditorWindowChange = React.useCallback((index: number, window: TimeWindow) => {\n setEditorWindows((prev) => {\n const next = [...prev]\n next[index] = window\n return next\n })\n }, [])\n\n const handleEditorWindowAdd = React.useCallback(() => {\n setEditorWindows((prev) => [...prev, buildNextWindow(prev)])\n }, [])\n\n const handleEditorWindowRemove = React.useCallback((index: number) => {\n setEditorWindows((prev) => prev.filter((_, idx) => idx !== index))\n }, [])\n\n const handleEditorDateAdd = React.useCallback(() => {\n setEditorDates((prev) => {\n const lastValue = [...prev].reverse().find((value) => value && value.length) ?? ''\n const base = lastValue ? parseDateInput(lastValue) : null\n const nextBase = base ?? new Date()\n const nextDate = new Date(nextBase.getFullYear(), nextBase.getMonth(), nextBase.getDate() + 1)\n return [...prev, formatDateInput(nextDate)]\n })\n }, [])\n\n const handleEditorDateChange = React.useCallback((index: number, value: string) => {\n setEditorDates((prev) => {\n const next = [...prev]\n next[index] = value\n return next\n })\n }, [])\n\n const handleEditorDateRemove = React.useCallback((index: number) => {\n setEditorDates((prev) => prev.filter((_, idx) => idx !== index))\n }, [])\n\n const editorWindowErrors = React.useMemo(\n () => (editorUnavailable ? [] : editorWindows.map((window) => getWindowError(window, listLabels))),\n [editorUnavailable, editorWindows, listLabels],\n )\n\n const handleEditorSubmit = React.useCallback(async () => {\n if (isReadOnly) return\n if (editorUnavailable && !canManageUnavailability) return\n const subjectForRules: AvailabilitySubjectType = usingRuleSet ? 'ruleset' : subjectType\n const subjectIdForRules = usingRuleSet ? (effectiveRulesetId ?? '') : subjectId\n if (!subjectIdForRules) return\n if (!editorUnavailable && editorWindowErrors.some(Boolean)) return\n const validWindows = editorWindows\n\n try {\n const dates = Array.from(new Set(editorDates.filter((value) => value && value.length)))\n if (editorScope === 'date') {\n const trimmedNote = editorNote.trim()\n const reasonEntryId = editorUnavailable ? editorReasonEntryId : null\n const fallbackReasonValue = editorReasonValue.trim()\n const reasonValue = reasonEntryId\n ? (reasonEntriesById[reasonEntryId]?.value ?? (fallbackReasonValue || null))\n : null\n const payload: Record<string, unknown> = {\n subjectType: subjectForRules,\n subjectId: subjectIdForRules,\n timezone,\n dates,\n windows: editorUnavailable ? [] : validWindows,\n kind: editorUnavailable ? 'unavailability' : 'availability',\n note: editorUnavailable && trimmedNote.length ? trimmedNote : null,\n unavailabilityReasonEntryId: editorUnavailable ? reasonEntryId : null,\n unavailabilityReasonValue: editorUnavailable ? reasonValue : null,\n }\n await apiCallOrThrow('/api/planner/availability-date-specific', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n }, { errorMessage: listLabels.saveDateError })\n } else {\n const rulesToDelete = editorRules\n const uniqueRuleIds = Array.from(new Set(rulesToDelete.map((rule) => rule.id)))\n await Promise.all(\n uniqueRuleIds.map((id) => deleteCrud('planner/availability', id, { errorMessage: listLabels.saveDateError })),\n )\n\n const creations: Array<Promise<unknown>> = []\n validWindows.forEach((window) => {\n const start = toDateForWeekday(editorWeekday, window.start)\n const end = toDateForWeekday(editorWeekday, window.end)\n if (!start || !end) return\n const rrule = buildAvailabilityRrule(start, end, 'weekly')\n creations.push(createCrud('planner/availability', {\n subjectType: subjectForRules,\n subjectId: subjectIdForRules,\n timezone,\n rrule,\n exdates: [],\n kind: 'availability',\n note: null,\n }, { errorMessage: listLabels.saveDateError }))\n })\n await Promise.all(creations)\n }\n flash(listLabels.saveDateSuccess, 'success')\n setEditorOpen(false)\n setEditorRules([])\n await refreshAvailability()\n await refreshRuleSetRules()\n } catch (error) {\n const message = error instanceof Error ? error.message : listLabels.saveDateError\n flash(message, 'error')\n }\n }, [\n editorDates,\n editorRules,\n editorScope,\n editorUnavailable,\n editorNote,\n editorReasonEntryId,\n editorReasonValue,\n editorWeekday,\n editorWindowErrors,\n editorWindows,\n listLabels.saveDateError,\n listLabels.saveDateSuccess,\n refreshAvailability,\n refreshRuleSetRules,\n reasonEntriesById,\n effectiveRulesetId,\n subjectId,\n subjectType,\n timezone,\n usingRuleSet,\n canManageUnavailability,\n isReadOnly,\n ])\n\n const handleSlotClick = React.useCallback((slot: ScheduleSlot) => {\n if (usingRuleSet || isReadOnly) return\n openEditor('date', { date: slot.start })\n }, [openEditor, usingRuleSet, isReadOnly])\n\n const handleItemClick = React.useCallback((item: ScheduleItem) => {\n if (usingRuleSet || isReadOnly) return\n const rule = item.metadata?.rule as AvailabilityRule | undefined\n if (!rule) return\n const window = parseAvailabilityRuleWindow(rule)\n if (window.repeat === 'weekly') {\n const weekday = window.startAt.getDay()\n const rules = activeRules.filter((candidate) => {\n const candidateWindow = parseAvailabilityRuleWindow(candidate)\n return candidateWindow.repeat === 'weekly' && candidateWindow.startAt.getDay() === weekday\n })\n openEditor('weekday', { weekday, rules })\n } else {\n const dateKey = formatDateInput(window.startAt)\n const rules = activeRules.filter((candidate) => {\n const candidateWindow = parseAvailabilityRuleWindow(candidate)\n return candidateWindow.repeat === 'once' && formatDateInput(candidateWindow.startAt) === dateKey\n })\n openEditor('date', { date: window.startAt, rules })\n }\n }, [activeRules, openEditor, usingRuleSet, isReadOnly])\n\n return (\n <>\n <div className=\"rounded-xl border bg-card p-4 shadow-sm\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div>\n <h2 className=\"text-lg font-semibold text-foreground\">\n {listLabels.title}\n </h2>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setViewMode('list')}\n aria-label={listLabels.listLabel}\n title={listLabels.listLabel}\n className={viewMode === 'list' ? 'bg-accent text-accent-foreground' : undefined}\n >\n <List className=\"size-4\" aria-hidden />\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setViewMode('calendar')}\n aria-label={listLabels.calendarLabel}\n title={listLabels.calendarLabel}\n className={viewMode === 'calendar' ? 'bg-accent text-accent-foreground' : undefined}\n >\n <Calendar className=\"size-4\" aria-hidden />\n </Button>\n </div>\n </div>\n\n <div className=\"mt-4 space-y-3 rounded-lg border bg-muted/30 p-3\">\n {onRulesetChange ? (\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {listLabels.ruleSetLabel}\n </label>\n {ruleSetsLoading ? (\n <span className=\"text-xs text-muted-foreground\">{listLabels.ruleSetLoading}</span>\n ) : (\n <Select\n value={resolveRuleSetSelectValue(ruleSets, effectiveRulesetId)}\n onValueChange={(value) => {\n void handleRuleSetChange(value ? value : null)\n }}\n disabled={isReadOnly}\n >\n <SelectTrigger size=\"sm\" className=\"w-auto min-w-[10rem]\">\n <SelectValue placeholder={listLabels.ruleSetPlaceholder} />\n </SelectTrigger>\n <SelectContent>\n {ruleSets.map((ruleSet) => (\n <SelectItem key={ruleSet.id} value={ruleSet.id}>\n {ruleSet.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setCreateRuleSetOpen(true)} disabled={isReadOnly}>\n <Plus className=\"size-4 mr-2\" aria-hidden />\n {listLabels.ruleSetCreateLabel}\n </Button>\n {effectiveRulesetId && usingRuleSet ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={handleCustomize} disabled={isReadOnly}>\n {listLabels.ruleSetCustomize}\n </Button>\n ) : null}\n {effectiveRulesetId && !usingRuleSet ? (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={handleResetToRuleSet} disabled={isReadOnly}>\n {listLabels.ruleSetReset}\n </Button>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span>{listLabels.timezoneLabel}</span>\n <div className=\"w-[220px]\">\n <ComboboxInput\n value={timezone}\n onChange={handleTimezoneChange}\n suggestions={timezoneOptions}\n placeholder={listLabels.timezonePlaceholder}\n allowCustomValues\n disabled={isReadOnly}\n />\n </div>\n </div>\n </div>\n\n <div className=\"mt-6\">\n {isLoading ? (\n <LoadingMessage label={listLabels.scheduleLoading} />\n ) : error ? (\n <ErrorMessage label={error} />\n ) : viewMode === 'calendar' ? (\n <ScheduleView\n items={scheduleItems}\n view={scheduleView}\n range={range}\n timezone={timezone}\n onRangeChange={setRange}\n onViewChange={setScheduleView}\n onTimezoneChange={handleTimezoneChange}\n onItemClick={handleItemClick}\n onSlotClick={handleSlotClick}\n />\n ) : (\n <div className=\"grid gap-6 lg:grid-cols-2\">\n {usingRuleSet ? (\n <div className=\"lg:col-span-2 rounded-lg border border-dashed p-4 text-sm text-muted-foreground\">\n {listLabels.customizePrompt}\n </div>\n ) : null}\n <section>\n <div className=\"flex items-center justify-between\">\n <div>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"text-base font-semibold\">{listLabels.weeklyTitle}</h3>\n {isWeeklyAutoSaving ? (\n <span className=\"inline-flex items-center gap-2 text-xs text-muted-foreground\">\n <Spinner size=\"sm\" />\n {t('ui.forms.status.saving', 'Saving...')}\n </span>\n ) : null}\n </div>\n <p className=\"text-sm text-muted-foreground\">{listLabels.weeklySubtitle}</p>\n </div>\n </div>\n <div className=\"mt-4 space-y-3\">\n {DAY_LABELS.map((day, index) => {\n const windows = weeklyWindows[index] ?? []\n return (\n <div key={day.code} className=\"flex flex-wrap items-start gap-3 rounded-lg border bg-background p-3\">\n <div className=\"flex w-10 justify-center\">\n <span className=\"flex h-8 w-8 items-center justify-center rounded-full bg-muted text-xs font-semibold\">\n {day.short}\n </span>\n </div>\n <div className=\"flex-1 space-y-2\">\n {windows.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">{listLabels.noHours}</p>\n ) : (\n windows.map((window, windowIndex) => {\n const windowError = weeklyWindowErrors[index]?.[windowIndex] ?? null\n const errorClass = windowError ? 'border-red-500 aria-invalid:ring-destructive' : ''\n return (\n <div key={`${day.code}-${windowIndex}`} className=\"space-y-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <TimePicker\n value={window.start}\n onChange={(value) => handleWeeklyWindowChange(index, windowIndex, { ...window, start: value ?? '' })}\n className={`w-[120px] ${errorClass}`}\n disabled={usingRuleSet || isReadOnly}\n showClearButton={false}\n />\n <span className=\"text-sm text-muted-foreground\">-</span>\n <TimePicker\n value={window.end}\n onChange={(value) => handleWeeklyWindowChange(index, windowIndex, { ...window, end: value ?? '' })}\n className={`w-[120px] ${errorClass}`}\n disabled={usingRuleSet || isReadOnly}\n showClearButton={false}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => handleWeeklyWindowRemove(index, windowIndex)}\n disabled={usingRuleSet || isReadOnly}\n aria-label={listLabels.removeWindow}\n >\n <Trash2 className=\"size-4\" aria-hidden />\n </Button>\n </div>\n {windowError ? (\n <div className=\"text-xs text-red-600\">{windowError}</div>\n ) : null}\n </div>\n )\n })\n )}\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => handleWeeklyWindowAdd(index)} disabled={usingRuleSet || isReadOnly}>\n <Plus className=\"size-4 mr-2\" aria-hidden />\n {listLabels.addWindow}\n </Button>\n </div>\n </div>\n )\n })}\n </div>\n </section>\n <section>\n <div className=\"flex items-center justify-between\">\n <div>\n <h3 className=\"text-base font-semibold\">{listLabels.dateSpecificTitle}</h3>\n <p className=\"text-sm text-muted-foreground\">{listLabels.dateSpecificSubtitle}</p>\n </div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => openEditor('date')} disabled={usingRuleSet || isReadOnly}>\n <Clock className=\"size-4 mr-2\" aria-hidden />\n {listLabels.addHours}\n </Button>\n </div>\n <div className=\"mt-4 space-y-3\">\n {Array.from(dateGroups.entries()).map(([date, rules]) => {\n const weekdayIndex = getWeekdayIndex(date)\n const weekdayLabel = weekdayIndex === null ? null : DAY_LABELS[weekdayIndex]\n const weekdayText = weekdayLabel ? t(weekdayLabel.nameKey, weekdayLabel.fallback) : date\n const weekdayShort = weekdayLabel ? weekdayLabel.short : '?'\n const unavailableRule = rules.find((rule) => rule.kind === 'unavailability')\n const unavailableReason = resolveRuleReasonValue(unavailableRule)\n const lockUnavailabilityActions = Boolean(unavailableRule) && !canManageUnavailability\n return (\n <div key={date} className=\"flex flex-wrap items-start gap-3 rounded-lg border bg-background p-3\">\n <div className=\"flex w-10 justify-center pt-1\">\n <span\n className=\"flex h-8 w-8 items-center justify-center rounded-full bg-muted text-xs font-semibold\"\n aria-label={weekdayText}\n title={weekdayText}\n >\n {weekdayShort}\n </span>\n </div>\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <div>\n <div className=\"flex items-center gap-2 text-sm font-semibold\">\n <Calendar className=\"size-4 text-muted-foreground\" aria-hidden />\n <span>{date}</span>\n </div>\n <div className=\"text-xs text-muted-foreground\">{weekdayText}</div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => openEditor('date', { date: new Date(`${date}T00:00:00`), rules })}\n disabled={usingRuleSet || isReadOnly || lockUnavailabilityActions}\n >\n <PencilLine className=\"size-4 mr-2\" aria-hidden />\n {listLabels.editTitle}\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={async () => {\n await Promise.all(rules.map((rule) => deleteCrud('planner/availability', rule.id)))\n await refreshAvailability()\n await refreshRuleSetRules()\n }}\n disabled={usingRuleSet || isReadOnly || lockUnavailabilityActions}\n aria-label={listLabels.removeWindow}\n >\n <Trash2 className=\"size-4\" aria-hidden />\n </Button>\n </div>\n </div>\n <div className=\"space-y-1 text-sm text-muted-foreground\">\n {unavailableRule ? (\n <div className=\"space-y-1\">\n <div className=\"font-medium text-foreground\">{listLabels.unavailableTitle}</div>\n {unavailableReason ? (\n <div className=\"text-xs text-muted-foreground\">{unavailableReason}</div>\n ) : null}\n {unavailableRule.note ? (\n <div className=\"text-xs text-muted-foreground\">{unavailableRule.note}</div>\n ) : null}\n </div>\n ) : (\n buildWindowsFromRules(rules).map((window, index) => (\n <div key={`${date}-${index}`}>\n {window.start} - {window.end}\n </div>\n ))\n )}\n </div>\n </div>\n </div>\n )\n })}\n </div>\n </section>\n </div>\n )}\n </div>\n </div>\n\n <Dialog\n open={editorOpen}\n onOpenChange={(open) => {\n if (!open) {\n setEditorOpen(false)\n setEditorRules([])\n setEditorUnavailable(false)\n setEditorNote('')\n setEditorReasonEntryId(null)\n setEditorReasonValue('')\n }\n }}\n >\n <DialogContent\n ref={dialogRef}\n onKeyDown={(event) => {\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n void handleEditorSubmit()\n }\n }}\n >\n <DialogHeader>\n <DialogTitle>\n {editorRules.length ? listLabels.editTitle : listLabels.addTitle}\n </DialogTitle>\n </DialogHeader>\n <CrudForm\n embedded\n fields={[\n {\n id: 'availabilityEditor',\n label: listLabels.applyScopeLabel,\n type: 'custom',\n component: () => (\n <div className=\"rounded-lg border bg-muted/30 p-4\">\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <div role=\"tablist\" aria-label={listLabels.applyScopeLabel} className=\"inline-flex rounded-lg border bg-muted p-1 text-xs\">\n <Button\n type=\"button\"\n role=\"tab\"\n aria-selected={editorScope === 'date'}\n variant=\"ghost\"\n size=\"sm\"\n className={`h-auto rounded-md px-3 py-1.5 font-medium ${\n editorScope === 'date'\n ? 'bg-background text-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n onClick={() => setEditorScope('date')}\n >\n {listLabels.applyScopeDate}\n </Button>\n <Button\n type=\"button\"\n role=\"tab\"\n aria-selected={editorScope === 'weekday'}\n variant=\"ghost\"\n size=\"sm\"\n className={`h-auto rounded-md px-3 py-1.5 font-medium ${\n editorScope === 'weekday'\n ? 'bg-background text-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n onClick={() => {\n setEditorScope('weekday')\n setEditorUnavailable(false)\n setEditorNote('')\n setEditorReasonEntryId(null)\n setEditorReasonValue('')\n }}\n >\n {listLabels.editAllLabel}\n </Button>\n </div>\n </div>\n\n {editorScope === 'date' ? (\n <div className=\"space-y-2\">\n {editorDates.map((value, index) => (\n <div key={`${value}-${index}`} className=\"flex items-center gap-2\">\n <Input\n type=\"date\"\n value={value}\n onChange={(event) => handleEditorDateChange(index, event.target.value)}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => handleEditorDateRemove(index)}\n aria-label={listLabels.removeWindow}\n >\n <Trash2 className=\"size-4\" aria-hidden />\n </Button>\n </div>\n ))}\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={handleEditorDateAdd}>\n <Plus className=\"size-4 mr-2\" aria-hidden />\n {listLabels.addDateLabel}\n </Button>\n <label\n htmlFor=\"availability-unavailable-toggle\"\n className=\"flex cursor-pointer items-start gap-2 pt-2 text-sm\"\n >\n <input\n id=\"availability-unavailable-toggle\"\n type=\"checkbox\"\n className=\"mt-0.5 size-4\"\n checked={editorUnavailable}\n disabled={!canManageUnavailability}\n onChange={(event) => {\n const checked = event.target.checked\n setEditorUnavailable(checked)\n if (!checked) {\n setEditorNote('')\n setEditorReasonEntryId(null)\n setEditorReasonValue('')\n }\n }}\n />\n <div>\n <div className=\"font-medium text-foreground\">{listLabels.unavailableLabel}</div>\n <div className=\"text-xs text-muted-foreground\">{listLabels.unavailableHelp}</div>\n </div>\n </label>\n {editorUnavailable ? (\n <div className=\"space-y-3\">\n <div className=\"space-y-2\">\n <label className=\"text-xs font-medium text-muted-foreground\">{listLabels.unavailableReasonLabel}</label>\n <DictionaryEntrySelect\n value={editorReasonEntryId ?? undefined}\n onChange={(next) => {\n setEditorReasonEntryId(next ?? null)\n setEditorReasonValue('')\n }}\n fetchOptions={fetchUnavailabilityReasonOptions}\n createOption={createUnavailabilityReasonOption}\n labels={unavailableReasonLabels}\n selectClassName=\"w-full\"\n manageHref=\"/backend/config/dictionaries\"\n disabled={!canManageUnavailability}\n />\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-xs font-medium text-muted-foreground\">{listLabels.unavailableNoteLabel}</label>\n <Input\n type=\"text\"\n value={editorNote}\n placeholder={listLabels.unavailableNotePlaceholder}\n disabled={!canManageUnavailability}\n onChange={(event) => setEditorNote(event.target.value)}\n />\n </div>\n </div>\n ) : null}\n </div>\n ) : (\n <div className=\"space-y-2\">\n <label className=\"text-xs text-muted-foreground\">{listLabels.applyScopeWeekday}</label>\n <Select\n value={String(editorWeekday)}\n onValueChange={(value) => setEditorWeekday(Number(value))}\n >\n <SelectTrigger size=\"sm\" className=\"w-auto min-w-[8rem]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {DAY_LABELS.map((day, index) => (\n <SelectItem key={day.code} value={String(index)}>\n {t(day.nameKey, day.fallback)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n\n {editorUnavailable && editorScope === 'date' ? null : (\n <div className=\"space-y-2\">\n <label className=\"text-xs font-medium text-muted-foreground\">{listLabels.windowsLabel}</label>\n {editorWindows.map((window, index) => {\n const windowError = editorWindowErrors[index] ?? null\n const errorClass = windowError ? 'border-red-500 aria-invalid:ring-destructive' : ''\n return (\n <div key={`${index}-${window.start}`} className=\"space-y-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <TimePicker\n value={window.start}\n onChange={(value) => handleEditorWindowChange(index, { ...window, start: value ?? '' })}\n className={`w-[120px] ${errorClass}`}\n showClearButton={false}\n />\n <span className=\"text-sm text-muted-foreground\">-</span>\n <TimePicker\n value={window.end}\n onChange={(value) => handleEditorWindowChange(index, { ...window, end: value ?? '' })}\n className={`w-[120px] ${errorClass}`}\n showClearButton={false}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => handleEditorWindowRemove(index)}\n aria-label={listLabels.removeWindow}\n >\n <Trash2 className=\"size-4\" aria-hidden />\n </Button>\n </div>\n {windowError ? (\n <div className=\"text-xs text-red-600\">{windowError}</div>\n ) : null}\n </div>\n )\n })}\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={handleEditorWindowAdd}>\n <Plus className=\"size-4 mr-2\" aria-hidden />\n {listLabels.addWindow}\n </Button>\n </div>\n )}\n </div>\n </div>\n ),\n },\n ]}\n onSubmit={handleEditorSubmit}\n submitLabel={listLabels.applyLabel}\n extraActions={(\n <Button type=\"button\" variant=\"ghost\" onClick={() => setEditorOpen(false)}>\n {listLabels.cancelLabel}\n </Button>\n )}\n />\n </DialogContent>\n </Dialog>\n\n <Dialog\n open={createRuleSetOpen}\n onOpenChange={(open) => setCreateRuleSetOpen(open)}\n >\n <DialogContent\n ref={createRuleSetDialogRef}\n onKeyDown={(event) => {\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n const form = createRuleSetDialogRef.current?.querySelector('form')\n form?.requestSubmit()\n }\n }}\n >\n <DialogHeader>\n <DialogTitle>{listLabels.ruleSetCreateTitle}</DialogTitle>\n </DialogHeader>\n <CrudForm<RuleSetFormValues>\n embedded\n schema={ruleSetFormSchema}\n fields={ruleSetFormFields}\n initialValues={ruleSetInitialValues}\n onSubmit={handleCreateRuleSet}\n submitLabel={listLabels.ruleSetCreateSubmit}\n extraActions={(\n <Button type=\"button\" variant=\"ghost\" onClick={() => setCreateRuleSetOpen(false)}>\n {listLabels.cancelLabel}\n </Button>\n )}\n />\n </DialogContent>\n </Dialog>\n {ConfirmDialogElement}\n </>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["window", "day", "error", "weeklyWindows"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
function resolveRuleSetSelectValue(ruleSets, selectedRulesetId) {
|
|
2
|
+
if (!selectedRulesetId) return void 0;
|
|
3
|
+
return ruleSets.some((ruleSet) => ruleSet.id === selectedRulesetId) ? selectedRulesetId : void 0;
|
|
4
|
+
}
|
|
5
|
+
export {
|
|
6
|
+
resolveRuleSetSelectValue
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=availabilityRulesEditorState.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/planner/components/availabilityRulesEditorState.ts"],
|
|
4
|
+
"sourcesContent": ["export type AvailabilityRuleSetOption = {\n id: string\n}\n\nexport function resolveRuleSetSelectValue(\n ruleSets: AvailabilityRuleSetOption[],\n selectedRulesetId: string | null | undefined,\n): string | undefined {\n if (!selectedRulesetId) return undefined\n return ruleSets.some((ruleSet) => ruleSet.id === selectedRulesetId) ? selectedRulesetId : undefined\n}\n"],
|
|
5
|
+
"mappings": "AAIO,SAAS,0BACd,UACA,mBACoB;AACpB,MAAI,CAAC,kBAAmB,QAAO;AAC/B,SAAO,SAAS,KAAK,CAAC,YAAY,QAAQ,OAAO,iBAAiB,IAAI,oBAAoB;AAC5F;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/core",
|
|
3
|
-
"version": "0.6.4-develop.
|
|
3
|
+
"version": "0.6.4-develop.4110.1.836aafde58",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -243,16 +243,16 @@
|
|
|
243
243
|
"zod": "^4.4.3"
|
|
244
244
|
},
|
|
245
245
|
"peerDependencies": {
|
|
246
|
-
"@open-mercato/ai-assistant": "0.6.4-develop.
|
|
247
|
-
"@open-mercato/shared": "0.6.4-develop.
|
|
248
|
-
"@open-mercato/ui": "0.6.4-develop.
|
|
246
|
+
"@open-mercato/ai-assistant": "0.6.4-develop.4110.1.836aafde58",
|
|
247
|
+
"@open-mercato/shared": "0.6.4-develop.4110.1.836aafde58",
|
|
248
|
+
"@open-mercato/ui": "0.6.4-develop.4110.1.836aafde58",
|
|
249
249
|
"react": "^19.0.0",
|
|
250
250
|
"react-dom": "^19.0.0"
|
|
251
251
|
},
|
|
252
252
|
"devDependencies": {
|
|
253
|
-
"@open-mercato/ai-assistant": "0.6.4-develop.
|
|
254
|
-
"@open-mercato/shared": "0.6.4-develop.
|
|
255
|
-
"@open-mercato/ui": "0.6.4-develop.
|
|
253
|
+
"@open-mercato/ai-assistant": "0.6.4-develop.4110.1.836aafde58",
|
|
254
|
+
"@open-mercato/shared": "0.6.4-develop.4110.1.836aafde58",
|
|
255
|
+
"@open-mercato/ui": "0.6.4-develop.4110.1.836aafde58",
|
|
256
256
|
"@testing-library/dom": "^10.4.1",
|
|
257
257
|
"@testing-library/jest-dom": "^6.9.1",
|
|
258
258
|
"@testing-library/react": "^16.3.1",
|
|
@@ -30,6 +30,7 @@ import { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'
|
|
|
30
30
|
import { parseAvailabilityRuleWindow } from '@open-mercato/core/modules/planner/lib/availabilitySchedule'
|
|
31
31
|
import { CrudForm, type CrudField } from '@open-mercato/ui/backend/CrudForm'
|
|
32
32
|
import { Calendar, Clock, List, PencilLine, Plus, Trash2 } from 'lucide-react'
|
|
33
|
+
import { resolveRuleSetSelectValue } from './availabilityRulesEditorState'
|
|
33
34
|
|
|
34
35
|
type AvailabilityRepeat = 'once' | 'daily' | 'weekly'
|
|
35
36
|
type AvailabilitySubjectType = 'member' | 'resource' | 'ruleset'
|
|
@@ -398,6 +399,7 @@ export function AvailabilityRulesEditor({
|
|
|
398
399
|
const [createRuleSetOpen, setCreateRuleSetOpen] = React.useState(false)
|
|
399
400
|
const [isWeeklyAutoSaving, setIsWeeklyAutoSaving] = React.useState(false)
|
|
400
401
|
const [customOverridesEnabled, setCustomOverridesEnabled] = React.useState(false)
|
|
402
|
+
const [selectedRulesetId, setSelectedRulesetId] = React.useState<string | null>(rulesetId ?? null)
|
|
401
403
|
const autoSaveTimerRef = React.useRef<number | null>(null)
|
|
402
404
|
const lastSavedWeeklyKeyRef = React.useRef<string | null>(null)
|
|
403
405
|
const weeklySaveStateRef = React.useRef({ inFlight: false, queued: false })
|
|
@@ -409,7 +411,12 @@ export function AvailabilityRulesEditor({
|
|
|
409
411
|
>(null)
|
|
410
412
|
const timezoneOptions = React.useMemo(() => getTimezoneOptions(), [])
|
|
411
413
|
|
|
412
|
-
|
|
414
|
+
React.useEffect(() => {
|
|
415
|
+
setSelectedRulesetId(rulesetId ?? null)
|
|
416
|
+
}, [rulesetId])
|
|
417
|
+
|
|
418
|
+
const effectiveRulesetId = selectedRulesetId
|
|
419
|
+
const usingRuleSet = Boolean(effectiveRulesetId) && availabilityRules.length === 0 && !customOverridesEnabled
|
|
413
420
|
const activeRules = usingRuleSet ? rulesetRules : availabilityRules
|
|
414
421
|
const scheduleRules = React.useMemo(() => {
|
|
415
422
|
const dateBlockers = new Set<string>()
|
|
@@ -547,7 +554,7 @@ export function AvailabilityRulesEditor({
|
|
|
547
554
|
}, [labelPrefix, subjectId, subjectType, t])
|
|
548
555
|
|
|
549
556
|
const refreshRuleSetRules = React.useCallback(async () => {
|
|
550
|
-
if (!
|
|
557
|
+
if (!effectiveRulesetId) {
|
|
551
558
|
setRulesetRules([])
|
|
552
559
|
return
|
|
553
560
|
}
|
|
@@ -556,7 +563,7 @@ export function AvailabilityRulesEditor({
|
|
|
556
563
|
page: '1',
|
|
557
564
|
pageSize: '100',
|
|
558
565
|
subjectType: 'ruleset',
|
|
559
|
-
subjectIds:
|
|
566
|
+
subjectIds: effectiveRulesetId,
|
|
560
567
|
})
|
|
561
568
|
const call = await apiCall<{ items?: AvailabilityRule[] }>(`/api/planner/availability?${params.toString()}`)
|
|
562
569
|
const items = Array.isArray(call.result?.items) ? call.result.items : []
|
|
@@ -564,7 +571,7 @@ export function AvailabilityRulesEditor({
|
|
|
564
571
|
} catch {
|
|
565
572
|
setRulesetRules([])
|
|
566
573
|
}
|
|
567
|
-
}, [
|
|
574
|
+
}, [effectiveRulesetId])
|
|
568
575
|
|
|
569
576
|
const refreshRuleSets = React.useCallback(async () => {
|
|
570
577
|
if (!onRulesetChange) return
|
|
@@ -653,10 +660,10 @@ export function AvailabilityRulesEditor({
|
|
|
653
660
|
|
|
654
661
|
React.useEffect(() => {
|
|
655
662
|
if (timezoneDirty) return
|
|
656
|
-
if (!usingRuleSet || !
|
|
657
|
-
const ruleset = ruleSets.find((entry) => entry.id ===
|
|
663
|
+
if (!usingRuleSet || !effectiveRulesetId) return
|
|
664
|
+
const ruleset = ruleSets.find((entry) => entry.id === effectiveRulesetId)
|
|
658
665
|
if (ruleset?.timezone) setTimezone(ruleset.timezone)
|
|
659
|
-
}, [
|
|
666
|
+
}, [effectiveRulesetId, ruleSets, timezoneDirty, usingRuleSet])
|
|
660
667
|
|
|
661
668
|
React.useEffect(() => {
|
|
662
669
|
if (availabilityRules.length > 0) {
|
|
@@ -665,10 +672,10 @@ export function AvailabilityRulesEditor({
|
|
|
665
672
|
}, [availabilityRules.length])
|
|
666
673
|
|
|
667
674
|
React.useEffect(() => {
|
|
668
|
-
if (!
|
|
675
|
+
if (!effectiveRulesetId) {
|
|
669
676
|
setCustomOverridesEnabled(false)
|
|
670
677
|
}
|
|
671
|
-
}, [
|
|
678
|
+
}, [effectiveRulesetId])
|
|
672
679
|
|
|
673
680
|
const refreshBookedEvents = React.useCallback(async () => {
|
|
674
681
|
if (!loadBookedEvents) return
|
|
@@ -764,7 +771,7 @@ export function AvailabilityRulesEditor({
|
|
|
764
771
|
const saveWeeklyHours = React.useCallback(async (options?: { silentSuccess?: boolean; skipRefresh?: boolean }) => {
|
|
765
772
|
if (isReadOnly) return
|
|
766
773
|
const subjectForRules: AvailabilitySubjectType = usingRuleSet ? 'ruleset' : subjectType
|
|
767
|
-
const subjectIdForRules = usingRuleSet ? (
|
|
774
|
+
const subjectIdForRules = usingRuleSet ? (effectiveRulesetId ?? '') : subjectId
|
|
768
775
|
if (!subjectIdForRules) return
|
|
769
776
|
if (weeklyHasErrors) return
|
|
770
777
|
|
|
@@ -802,7 +809,7 @@ export function AvailabilityRulesEditor({
|
|
|
802
809
|
listLabels.saveWeeklySuccess,
|
|
803
810
|
refreshAvailability,
|
|
804
811
|
refreshRuleSetRules,
|
|
805
|
-
|
|
812
|
+
effectiveRulesetId,
|
|
806
813
|
subjectId,
|
|
807
814
|
subjectType,
|
|
808
815
|
timezone,
|
|
@@ -856,7 +863,7 @@ export function AvailabilityRulesEditor({
|
|
|
856
863
|
if (isReadOnly) return
|
|
857
864
|
if (timezoneSaveInFlightRef.current) return
|
|
858
865
|
const trimmedTimezone = nextTimezone.trim() || 'UTC'
|
|
859
|
-
const rulesetTimezoneId = subjectType === 'ruleset' ? subjectId :
|
|
866
|
+
const rulesetTimezoneId = subjectType === 'ruleset' ? subjectId : effectiveRulesetId
|
|
860
867
|
const rulesToUpdate = activeRules.filter((rule) => rule.timezone !== trimmedTimezone)
|
|
861
868
|
if (!rulesToUpdate.length && !rulesetTimezoneId) {
|
|
862
869
|
setTimezoneDirty(false)
|
|
@@ -895,7 +902,7 @@ export function AvailabilityRulesEditor({
|
|
|
895
902
|
listLabels.timezoneSaveError,
|
|
896
903
|
refreshAvailability,
|
|
897
904
|
refreshRuleSetRules,
|
|
898
|
-
|
|
905
|
+
effectiveRulesetId,
|
|
899
906
|
subjectId,
|
|
900
907
|
subjectType,
|
|
901
908
|
isReadOnly,
|
|
@@ -927,7 +934,7 @@ export function AvailabilityRulesEditor({
|
|
|
927
934
|
|
|
928
935
|
const handleCustomize = React.useCallback(async () => {
|
|
929
936
|
if (isReadOnly) return
|
|
930
|
-
if (!
|
|
937
|
+
if (!effectiveRulesetId) return
|
|
931
938
|
try {
|
|
932
939
|
const creations = rulesetRules.map((rule) => createCrud('planner/availability', {
|
|
933
940
|
subjectType,
|
|
@@ -945,11 +952,11 @@ export function AvailabilityRulesEditor({
|
|
|
945
952
|
const message = error instanceof Error ? error.message : listLabels.saveWeeklyError
|
|
946
953
|
flash(message, 'error')
|
|
947
954
|
}
|
|
948
|
-
}, [listLabels.saveWeeklyError, refreshAvailability,
|
|
955
|
+
}, [effectiveRulesetId, listLabels.saveWeeklyError, refreshAvailability, rulesetRules, subjectId, subjectType, isReadOnly])
|
|
949
956
|
|
|
950
957
|
const handleResetToRuleSet = React.useCallback(async () => {
|
|
951
958
|
if (isReadOnly) return
|
|
952
|
-
if (!
|
|
959
|
+
if (!effectiveRulesetId) return
|
|
953
960
|
try {
|
|
954
961
|
await Promise.all(
|
|
955
962
|
availabilityRules.map((rule) => deleteCrud('planner/availability', rule.id, { errorMessage: listLabels.saveWeeklyError })),
|
|
@@ -960,12 +967,12 @@ export function AvailabilityRulesEditor({
|
|
|
960
967
|
const message = error instanceof Error ? error.message : listLabels.saveWeeklyError
|
|
961
968
|
flash(message, 'error')
|
|
962
969
|
}
|
|
963
|
-
}, [availabilityRules, listLabels.saveWeeklyError, refreshAvailability,
|
|
970
|
+
}, [availabilityRules, effectiveRulesetId, listLabels.saveWeeklyError, refreshAvailability, isReadOnly])
|
|
964
971
|
|
|
965
972
|
const handleRuleSetChange = React.useCallback(async (nextId: string | null) => {
|
|
966
973
|
if (isReadOnly) return
|
|
967
974
|
if (!onRulesetChange) return
|
|
968
|
-
if (availabilityRules.length > 0 && nextId !==
|
|
975
|
+
if (availabilityRules.length > 0 && nextId !== effectiveRulesetId) {
|
|
969
976
|
const confirmed = await confirm({
|
|
970
977
|
title: listLabels.ruleSetConfirm,
|
|
971
978
|
variant: 'default',
|
|
@@ -975,17 +982,23 @@ export function AvailabilityRulesEditor({
|
|
|
975
982
|
availabilityRules.map((rule) => deleteCrud('planner/availability', rule.id, { errorMessage: listLabels.saveWeeklyError })),
|
|
976
983
|
)
|
|
977
984
|
}
|
|
985
|
+
setSelectedRulesetId(nextId)
|
|
978
986
|
setCustomOverridesEnabled(false)
|
|
979
|
-
|
|
980
|
-
|
|
987
|
+
try {
|
|
988
|
+
await onRulesetChange(nextId)
|
|
989
|
+
await refreshAvailability()
|
|
990
|
+
} catch (error) {
|
|
991
|
+
setSelectedRulesetId(effectiveRulesetId)
|
|
992
|
+
throw error
|
|
993
|
+
}
|
|
981
994
|
}, [
|
|
982
995
|
availabilityRules,
|
|
983
996
|
confirm,
|
|
997
|
+
effectiveRulesetId,
|
|
984
998
|
listLabels.ruleSetConfirm,
|
|
985
999
|
listLabels.saveWeeklyError,
|
|
986
1000
|
onRulesetChange,
|
|
987
1001
|
refreshAvailability,
|
|
988
|
-
rulesetId,
|
|
989
1002
|
isReadOnly,
|
|
990
1003
|
])
|
|
991
1004
|
|
|
@@ -1058,6 +1071,7 @@ export function AvailabilityRulesEditor({
|
|
|
1058
1071
|
}
|
|
1059
1072
|
await refreshRuleSets()
|
|
1060
1073
|
if (onRulesetChange) {
|
|
1074
|
+
setSelectedRulesetId(id)
|
|
1061
1075
|
await onRulesetChange(id)
|
|
1062
1076
|
await refreshAvailability()
|
|
1063
1077
|
}
|
|
@@ -1155,7 +1169,7 @@ export function AvailabilityRulesEditor({
|
|
|
1155
1169
|
if (isReadOnly) return
|
|
1156
1170
|
if (editorUnavailable && !canManageUnavailability) return
|
|
1157
1171
|
const subjectForRules: AvailabilitySubjectType = usingRuleSet ? 'ruleset' : subjectType
|
|
1158
|
-
const subjectIdForRules = usingRuleSet ? (
|
|
1172
|
+
const subjectIdForRules = usingRuleSet ? (effectiveRulesetId ?? '') : subjectId
|
|
1159
1173
|
if (!subjectIdForRules) return
|
|
1160
1174
|
if (!editorUnavailable && editorWindowErrors.some(Boolean)) return
|
|
1161
1175
|
const validWindows = editorWindows
|
|
@@ -1235,7 +1249,7 @@ export function AvailabilityRulesEditor({
|
|
|
1235
1249
|
refreshAvailability,
|
|
1236
1250
|
refreshRuleSetRules,
|
|
1237
1251
|
reasonEntriesById,
|
|
1238
|
-
|
|
1252
|
+
effectiveRulesetId,
|
|
1239
1253
|
subjectId,
|
|
1240
1254
|
subjectType,
|
|
1241
1255
|
timezone,
|
|
@@ -1316,7 +1330,7 @@ export function AvailabilityRulesEditor({
|
|
|
1316
1330
|
<span className="text-xs text-muted-foreground">{listLabels.ruleSetLoading}</span>
|
|
1317
1331
|
) : (
|
|
1318
1332
|
<Select
|
|
1319
|
-
value={
|
|
1333
|
+
value={resolveRuleSetSelectValue(ruleSets, effectiveRulesetId)}
|
|
1320
1334
|
onValueChange={(value) => {
|
|
1321
1335
|
void handleRuleSetChange(value ? value : null)
|
|
1322
1336
|
}}
|
|
@@ -1338,12 +1352,12 @@ export function AvailabilityRulesEditor({
|
|
|
1338
1352
|
<Plus className="size-4 mr-2" aria-hidden />
|
|
1339
1353
|
{listLabels.ruleSetCreateLabel}
|
|
1340
1354
|
</Button>
|
|
1341
|
-
{
|
|
1355
|
+
{effectiveRulesetId && usingRuleSet ? (
|
|
1342
1356
|
<Button type="button" variant="outline" size="sm" onClick={handleCustomize} disabled={isReadOnly}>
|
|
1343
1357
|
{listLabels.ruleSetCustomize}
|
|
1344
1358
|
</Button>
|
|
1345
1359
|
) : null}
|
|
1346
|
-
{
|
|
1360
|
+
{effectiveRulesetId && !usingRuleSet ? (
|
|
1347
1361
|
<Button type="button" variant="ghost" size="sm" onClick={handleResetToRuleSet} disabled={isReadOnly}>
|
|
1348
1362
|
{listLabels.ruleSetReset}
|
|
1349
1363
|
</Button>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type AvailabilityRuleSetOption = {
|
|
2
|
+
id: string
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function resolveRuleSetSelectValue(
|
|
6
|
+
ruleSets: AvailabilityRuleSetOption[],
|
|
7
|
+
selectedRulesetId: string | null | undefined,
|
|
8
|
+
): string | undefined {
|
|
9
|
+
if (!selectedRulesetId) return undefined
|
|
10
|
+
return ruleSets.some((ruleSet) => ruleSet.id === selectedRulesetId) ? selectedRulesetId : undefined
|
|
11
|
+
}
|