@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.
@@ -1,4 +1,4 @@
1
- [build:core] found 2644 entry points
1
+ [build:core] found 2645 entry points
2
2
  [build:core] built successfully
3
3
  [build:core:generated] found 172 entry points
4
4
  [build:core:generated] built successfully
@@ -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
- const usingRuleSet = Boolean(rulesetId) && availabilityRules.length === 0 && !customOverridesEnabled;
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 (!rulesetId) {
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: rulesetId
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
- }, [rulesetId]);
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 || !rulesetId) return;
554
- const ruleset = ruleSets.find((entry) => entry.id === rulesetId);
559
+ if (!usingRuleSet || !effectiveRulesetId) return;
560
+ const ruleset = ruleSets.find((entry) => entry.id === effectiveRulesetId);
555
561
  if (ruleset?.timezone) setTimezone(ruleset.timezone);
556
- }, [rulesetId, ruleSets, timezoneDirty, usingRuleSet]);
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 (!rulesetId) {
569
+ if (!effectiveRulesetId) {
564
570
  setCustomOverridesEnabled(false);
565
571
  }
566
- }, [rulesetId]);
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 ? rulesetId ?? "" : subjectId;
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
- rulesetId,
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 : rulesetId;
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
- rulesetId,
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 (!rulesetId) return;
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, rulesetId, rulesetRules, subjectId, subjectType, isReadOnly]);
829
+ }, [effectiveRulesetId, listLabels.saveWeeklyError, refreshAvailability, rulesetRules, subjectId, subjectType, isReadOnly]);
824
830
  const handleResetToRuleSet = React.useCallback(async () => {
825
831
  if (isReadOnly) return;
826
- if (!rulesetId) return;
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, rulesetId, isReadOnly]);
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 !== rulesetId) {
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
- await onRulesetChange(nextId);
853
- await refreshAvailability();
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 ? rulesetId ?? "" : subjectId;
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
- rulesetId,
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: rulesetId || void 0,
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
- rulesetId && usingRuleSet ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: handleCustomize, disabled: isReadOnly, children: listLabels.ruleSetCustomize }) : null,
1182
- rulesetId && !usingRuleSet ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: handleResetToRuleSet, disabled: isReadOnly, children: listLabels.ruleSetReset }) : null
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.4106.1.12c205a613",
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.4106.1.12c205a613",
247
- "@open-mercato/shared": "0.6.4-develop.4106.1.12c205a613",
248
- "@open-mercato/ui": "0.6.4-develop.4106.1.12c205a613",
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.4106.1.12c205a613",
254
- "@open-mercato/shared": "0.6.4-develop.4106.1.12c205a613",
255
- "@open-mercato/ui": "0.6.4-develop.4106.1.12c205a613",
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
- const usingRuleSet = Boolean(rulesetId) && availabilityRules.length === 0 && !customOverridesEnabled
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 (!rulesetId) {
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: rulesetId,
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
- }, [rulesetId])
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 || !rulesetId) return
657
- const ruleset = ruleSets.find((entry) => entry.id === rulesetId)
663
+ if (!usingRuleSet || !effectiveRulesetId) return
664
+ const ruleset = ruleSets.find((entry) => entry.id === effectiveRulesetId)
658
665
  if (ruleset?.timezone) setTimezone(ruleset.timezone)
659
- }, [rulesetId, ruleSets, timezoneDirty, usingRuleSet])
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 (!rulesetId) {
675
+ if (!effectiveRulesetId) {
669
676
  setCustomOverridesEnabled(false)
670
677
  }
671
- }, [rulesetId])
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 ? (rulesetId ?? '') : subjectId
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
- rulesetId,
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 : rulesetId
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
- rulesetId,
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 (!rulesetId) return
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, rulesetId, rulesetRules, subjectId, subjectType, isReadOnly])
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 (!rulesetId) return
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, rulesetId, isReadOnly])
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 !== rulesetId) {
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
- await onRulesetChange(nextId)
980
- await refreshAvailability()
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 ? (rulesetId ?? '') : subjectId
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
- rulesetId,
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={rulesetId || undefined}
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
- {rulesetId && usingRuleSet ? (
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
- {rulesetId && !usingRuleSet ? (
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
+ }