@adatechnology/scheduling-ui 0.1.0-rc.1 → 0.1.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -360,6 +360,7 @@ var pt_BR_default = {
360
360
  "agenda.viewDay": "Dia",
361
361
  "agenda.viewWeek": "Semana",
362
362
  "agenda.empty": "Sem reservas neste per\xEDodo",
363
+ "agenda.moreResults": "Este per\xEDodo tem mais reservas do que as exibidas. Filtre por recurso ou reduza a janela para ver o restante.",
363
364
  "availability.weeklyRulesTitle": "Regras semanais",
364
365
  "availability.exceptionsTitle": "Exce\xE7\xF5es",
365
366
  "availability.resourceTimezone": "Fuso do recurso",
@@ -387,6 +388,8 @@ var pt_BR_default = {
387
388
  "booking.complete": "Concluir",
388
389
  "booking.markNoShow": "Marcar n\xE3o compareceu",
389
390
  "booking.reschedule": "Reagendar",
391
+ "booking.rescheduleStart": "Novo in\xEDcio",
392
+ "booking.rescheduleEnd": "Novo fim",
390
393
  "booking.detailTitle": "Detalhes da reserva",
391
394
  "booking.cancelReason": "Motivo do cancelamento",
392
395
  "booking.cancelledBy": "Cancelado por",
@@ -403,7 +406,11 @@ var pt_BR_default = {
403
406
  "availability.startsAtLocal": "In\xEDcio",
404
407
  "availability.endsAtLocal": "Fim",
405
408
  "availability.exceptionFrom": "De",
406
- "availability.exceptionUntil": "At\xE9"
409
+ "availability.exceptionUntil": "At\xE9",
410
+ "datetime.year": "Ano",
411
+ "datetime.month": "M\xEAs",
412
+ "datetime.day": "Dia",
413
+ "datetime.time": "Hora"
407
414
  };
408
415
 
409
416
  // src/locales/en.json
@@ -447,6 +454,7 @@ var en_default = {
447
454
  "agenda.viewDay": "Day",
448
455
  "agenda.viewWeek": "Week",
449
456
  "agenda.empty": "No bookings in this period",
457
+ "agenda.moreResults": "This period has more bookings than shown. Filter by resource or narrow the window to see the rest.",
450
458
  "availability.weeklyRulesTitle": "Weekly rules",
451
459
  "availability.exceptionsTitle": "Exceptions",
452
460
  "availability.resourceTimezone": "Resource timezone",
@@ -474,6 +482,8 @@ var en_default = {
474
482
  "booking.complete": "Complete",
475
483
  "booking.markNoShow": "Mark no-show",
476
484
  "booking.reschedule": "Reschedule",
485
+ "booking.rescheduleStart": "New start",
486
+ "booking.rescheduleEnd": "New end",
477
487
  "booking.detailTitle": "Booking details",
478
488
  "booking.cancelReason": "Cancellation reason",
479
489
  "booking.cancelledBy": "Cancelled by",
@@ -490,7 +500,11 @@ var en_default = {
490
500
  "availability.startsAtLocal": "Starts",
491
501
  "availability.endsAtLocal": "Ends",
492
502
  "availability.exceptionFrom": "From",
493
- "availability.exceptionUntil": "Until"
503
+ "availability.exceptionUntil": "Until",
504
+ "datetime.year": "Year",
505
+ "datetime.month": "Month",
506
+ "datetime.day": "Day",
507
+ "datetime.time": "Time"
494
508
  };
495
509
 
496
510
  // src/locales/index.ts
@@ -577,7 +591,7 @@ function AgendaGrid({ bookings, days }) {
577
591
  const dayBookings = bookingsOnDay(bookings, day, agendaStartHour, agendaEndHour);
578
592
  const positioned = layoutDayBookings(dayBookings);
579
593
  const dayStart = startOfDay(day);
580
- return /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-[160px] border-r border-gray-200 dark:border-gray-700 last:border-r-0", children: [
594
+ return /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-40 border-r border-gray-200 dark:border-gray-700 last:border-r-0", children: [
581
595
  /* @__PURE__ */ jsx2("div", { className: "h-8 px-2 flex items-center text-xs font-medium text-gray-700 dark:text-gray-300 border-b border-gray-200 dark:border-gray-700", children: day.toLocaleDateString(locale, { weekday: "short", day: "2-digit", month: "2-digit" }) }),
582
596
  /* @__PURE__ */ jsxs("div", { className: "relative", style: { height: `${hours.length * 4}rem` }, children: [
583
597
  positioned.length === 0 && /* @__PURE__ */ jsx2("p", { className: "absolute inset-x-2 top-2 text-xs text-gray-400", children: messages["agenda.empty"] }),
@@ -616,7 +630,7 @@ function AgendaGrid({ bookings, days }) {
616
630
  }
617
631
 
618
632
  // src/workspace/AgendaArea.tsx
619
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
633
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
620
634
  var DAY_IN_MS = 24 * 60 * 6e4;
621
635
  function startOfWeek(date, weekStartsOn) {
622
636
  const start = startOfDay(date);
@@ -692,7 +706,10 @@ function AgendaArea() {
692
706
  ] })
693
707
  ] }),
694
708
  isError && /* @__PURE__ */ jsx3("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.loadFailure"] }),
695
- isLoading ? /* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }) : /* @__PURE__ */ jsx3(AgendaGrid, { bookings: bookingsPage?.data ?? [], days })
709
+ isLoading ? /* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
710
+ bookingsPage && bookingsPage.total > bookingsPage.data.length && /* @__PURE__ */ jsx3("p", { className: "text-sm text-amber-700 bg-amber-50 rounded-lg px-3 py-2", children: messages["agenda.moreResults"] }),
711
+ /* @__PURE__ */ jsx3(AgendaGrid, { bookings: bookingsPage?.data ?? [], days })
712
+ ] })
696
713
  ] });
697
714
  }
698
715
 
@@ -825,16 +842,175 @@ function WeeklyRulesEditor({ resourceId }) {
825
842
  import { Plus as Plus2, Trash2 as Trash22 } from "lucide-react";
826
843
  import { useState as useState3 } from "react";
827
844
  import { AVAILABILITY_EXCEPTION_KIND } from "@adatechnology/scheduling-contracts";
845
+
846
+ // src/components/DateTimeField.tsx
847
+ import { useId } from "react";
848
+
849
+ // src/components/dateTimeParts.util.ts
850
+ var DATE_TIME_LOCAL_PATTERN = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/;
851
+ var MONTHS_IN_YEAR = 12;
852
+ function parseDateTimeParts(value) {
853
+ const match = DATE_TIME_LOCAL_PATTERN.exec(value);
854
+ if (!match) return void 0;
855
+ const [, year, month, day, hour, minute] = match;
856
+ return { year: Number(year), month: Number(month), day: Number(day), time: `${hour}:${minute}` };
857
+ }
858
+ function daysInMonth(params) {
859
+ return new Date(Date.UTC(params.year, params.month, 0)).getUTCDate();
860
+ }
861
+ function pad(value) {
862
+ return String(value).padStart(2, "0");
863
+ }
864
+ function formatDateTimeParts(parts) {
865
+ const lastDay = daysInMonth({ year: parts.year, month: parts.month });
866
+ const day = Math.min(Math.max(parts.day, 1), lastDay);
867
+ return `${String(parts.year).padStart(4, "0")}-${pad(parts.month)}-${pad(day)}T${parts.time}`;
868
+ }
869
+ function buildYearOptions(params) {
870
+ const current = params.today.getFullYear();
871
+ const first = Math.min(current - params.past, params.year);
872
+ const last = Math.max(current + params.future, params.year);
873
+ return Array.from({ length: last - first + 1 }, (_, index) => first + index);
874
+ }
875
+
876
+ // src/components/DateTimeField.tsx
828
877
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
878
+ var FIELD_CLASS = "min-h-11 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 px-2 text-sm";
879
+ var YEAR_WINDOW = { PAST: 1, FUTURE: 2 };
880
+ function partsOf(value, fallback) {
881
+ return parseDateTimeParts(value) ?? {
882
+ year: fallback.getFullYear(),
883
+ month: fallback.getMonth() + 1,
884
+ day: fallback.getDate(),
885
+ time: "09:00"
886
+ };
887
+ }
888
+ function monthLabels(locale) {
889
+ const format = new Intl.DateTimeFormat(locale, { month: "long", timeZone: "UTC" });
890
+ return Array.from(
891
+ { length: MONTHS_IN_YEAR },
892
+ (_, index) => format.format(new Date(Date.UTC(2026, index, 1)))
893
+ );
894
+ }
895
+ function DateTimeField({ label, value, onChange, emptyDefault }) {
896
+ const { locale } = useSchedulingConfig();
897
+ const messages = resolveSchedulingMessages(locale);
898
+ const groupId = useId();
899
+ const today = emptyDefault ?? /* @__PURE__ */ new Date();
900
+ const parts = partsOf(value, today);
901
+ const years = buildYearOptions({
902
+ year: parts.year,
903
+ today,
904
+ past: YEAR_WINDOW.PAST,
905
+ future: YEAR_WINDOW.FUTURE
906
+ });
907
+ const days = daysInMonth({ year: parts.year, month: parts.month });
908
+ const months = monthLabels(locale);
909
+ function change(patch) {
910
+ onChange(formatDateTimeParts({ ...parts, ...patch }));
911
+ }
912
+ return /* @__PURE__ */ jsxs4("div", { role: "group", "aria-labelledby": groupId, className: "flex flex-wrap items-center gap-2", children: [
913
+ /* @__PURE__ */ jsx5("span", { id: groupId, className: "sr-only", children: label }),
914
+ /* @__PURE__ */ jsx5(
915
+ "select",
916
+ {
917
+ "aria-label": `${label} \u2014 ${messages["datetime.year"]}`,
918
+ value: parts.year,
919
+ onChange: (event) => change({ year: Number(event.target.value) }),
920
+ className: FIELD_CLASS,
921
+ children: years.map((year) => /* @__PURE__ */ jsx5("option", { value: year, children: year }, year))
922
+ }
923
+ ),
924
+ /* @__PURE__ */ jsx5(
925
+ "select",
926
+ {
927
+ "aria-label": `${label} \u2014 ${messages["datetime.month"]}`,
928
+ value: parts.month,
929
+ onChange: (event) => change({ month: Number(event.target.value) }),
930
+ className: FIELD_CLASS,
931
+ children: months.map((name, index) => /* @__PURE__ */ jsx5("option", { value: index + 1, children: name }, name))
932
+ }
933
+ ),
934
+ /* @__PURE__ */ jsx5(
935
+ "select",
936
+ {
937
+ "aria-label": `${label} \u2014 ${messages["datetime.day"]}`,
938
+ value: Math.min(parts.day, days),
939
+ onChange: (event) => change({ day: Number(event.target.value) }),
940
+ className: FIELD_CLASS,
941
+ children: Array.from({ length: days }, (_, index) => index + 1).map((day) => /* @__PURE__ */ jsx5("option", { value: day, children: day }, day))
942
+ }
943
+ ),
944
+ /* @__PURE__ */ jsx5(
945
+ "input",
946
+ {
947
+ type: "time",
948
+ "aria-label": `${label} \u2014 ${messages["datetime.time"]}`,
949
+ value: parts.time,
950
+ onChange: (event) => change({ time: event.target.value }),
951
+ className: FIELD_CLASS
952
+ }
953
+ )
954
+ ] });
955
+ }
956
+
957
+ // src/components/datetimeLocal.util.ts
958
+ function getTimeZoneOffsetMs(instant, timeZone) {
959
+ const parts = new Intl.DateTimeFormat("en-US", {
960
+ timeZone,
961
+ year: "numeric",
962
+ month: "2-digit",
963
+ day: "2-digit",
964
+ hour: "2-digit",
965
+ minute: "2-digit",
966
+ second: "2-digit",
967
+ hourCycle: "h23"
968
+ }).formatToParts(instant);
969
+ const get = (type) => Number(parts.find((part) => part.type === type)?.value ?? 0);
970
+ const asUtcOfWallClock = Date.UTC(
971
+ get("year"),
972
+ get("month") - 1,
973
+ get("day"),
974
+ get("hour") % 24,
975
+ get("minute"),
976
+ get("second")
977
+ );
978
+ return asUtcOfWallClock - instant.getTime();
979
+ }
980
+ function parseDateTimeLocalInTimeZone(value, timeZone) {
981
+ const naiveUtc = /* @__PURE__ */ new Date(`${value}:00.000Z`);
982
+ const firstOffset = getTimeZoneOffsetMs(naiveUtc, timeZone);
983
+ const firstPass = new Date(naiveUtc.getTime() - firstOffset);
984
+ const secondOffset = getTimeZoneOffsetMs(firstPass, timeZone);
985
+ return new Date(naiveUtc.getTime() - secondOffset);
986
+ }
987
+ function formatDateTimeLocalInTimeZone(instant, timeZone) {
988
+ const parts = new Intl.DateTimeFormat("en-US", {
989
+ timeZone,
990
+ year: "numeric",
991
+ month: "2-digit",
992
+ day: "2-digit",
993
+ hour: "2-digit",
994
+ minute: "2-digit",
995
+ hourCycle: "h23"
996
+ }).formatToParts(instant);
997
+ const get = (type) => parts.find((part) => part.type === type)?.value ?? "00";
998
+ const hour = get("hour") === "24" ? "00" : get("hour");
999
+ return `${get("year")}-${get("month")}-${get("day")}T${hour}:${get("minute")}`;
1000
+ }
1001
+
1002
+ // src/components/AvailabilityExceptionsEditor.tsx
1003
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
829
1004
  var SELECT_CLASS = "min-h-11 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 px-2 text-sm";
830
- function AvailabilityExceptionsEditor({ resourceId }) {
1005
+ function AvailabilityExceptionsEditor({ resourceId, timezone }) {
831
1006
  const { locale } = useSchedulingConfig();
832
1007
  const messages = resolveSchedulingMessages(locale);
833
1008
  const { data, isLoading, isError: isLoadError } = useAvailabilityExceptions(resourceId);
834
1009
  const addException = useAddAvailabilityException();
835
1010
  const removeException = useRemoveAvailabilityException();
836
- const [from, setFrom] = useState3("");
837
- const [until, setUntil] = useState3("");
1011
+ const emptyValue = () => formatDateTimeLocalInTimeZone(/* @__PURE__ */ new Date(), timezone);
1012
+ const [from, setFrom] = useState3(emptyValue);
1013
+ const [until, setUntil] = useState3(emptyValue);
838
1014
  const [kind, setKind] = useState3(AVAILABILITY_EXCEPTION_KIND.BLOCK);
839
1015
  const [reason, setReason] = useState3("");
840
1016
  async function handleAdd() {
@@ -842,23 +1018,26 @@ function AvailabilityExceptionsEditor({ resourceId }) {
842
1018
  try {
843
1019
  await addException.mutateAsync({
844
1020
  resourceId,
845
- during: { start: new Date(from), end: new Date(until) },
1021
+ during: {
1022
+ start: parseDateTimeLocalInTimeZone(from, timezone),
1023
+ end: parseDateTimeLocalInTimeZone(until, timezone)
1024
+ },
846
1025
  kind,
847
1026
  ...reason ? { reason } : {}
848
1027
  });
849
- setFrom("");
850
- setUntil("");
1028
+ setFrom(emptyValue());
1029
+ setUntil(emptyValue());
851
1030
  setReason("");
852
1031
  } catch {
853
1032
  }
854
1033
  }
855
- return /* @__PURE__ */ jsxs4("section", { className: "space-y-3", children: [
856
- /* @__PURE__ */ jsx5("h3", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: messages["availability.exceptionsTitle"] }),
857
- (addException.isError || removeException.isError) && /* @__PURE__ */ jsx5("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.actionFailure"] }),
858
- isLoadError && /* @__PURE__ */ jsx5("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.loadFailure"] }),
859
- isLoading && /* @__PURE__ */ jsx5("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }),
860
- /* @__PURE__ */ jsx5("ul", { className: "space-y-2", children: (data ?? []).map((exception) => /* @__PURE__ */ jsxs4("li", { className: "flex items-center gap-2 text-sm", children: [
861
- /* @__PURE__ */ jsxs4("span", { className: "flex-1", children: [
1034
+ return /* @__PURE__ */ jsxs5("section", { className: "space-y-3", children: [
1035
+ /* @__PURE__ */ jsx6("h3", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: messages["availability.exceptionsTitle"] }),
1036
+ (addException.isError || removeException.isError) && /* @__PURE__ */ jsx6("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.actionFailure"] }),
1037
+ isLoadError && /* @__PURE__ */ jsx6("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.loadFailure"] }),
1038
+ isLoading && /* @__PURE__ */ jsx6("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }),
1039
+ /* @__PURE__ */ jsx6("ul", { className: "space-y-2", children: (data ?? []).map((exception) => /* @__PURE__ */ jsxs5("li", { className: "flex items-center gap-2 text-sm", children: [
1040
+ /* @__PURE__ */ jsxs5("span", { className: "flex-1", children: [
862
1041
  messages[`availability.exceptionKind.${exception.kind === "block" ? "blocked" : "extra"}`],
863
1042
  " \u2014",
864
1043
  " ",
@@ -867,39 +1046,35 @@ function AvailabilityExceptionsEditor({ resourceId }) {
867
1046
  exception.during.end.toLocaleString(locale),
868
1047
  exception.reason ? ` (${exception.reason})` : ""
869
1048
  ] }),
870
- /* @__PURE__ */ jsx5(
1049
+ /* @__PURE__ */ jsx6(
871
1050
  "button",
872
1051
  {
873
1052
  type: "button",
874
1053
  onClick: () => removeException.mutate({ id: exception.id, resourceId }),
875
1054
  "aria-label": messages["availability.removeException"],
876
1055
  className: "min-h-11 min-w-11 inline-flex items-center justify-center rounded-lg text-red-700 hover:bg-red-50",
877
- children: /* @__PURE__ */ jsx5(Trash22, { "aria-hidden": "true", className: "w-4 h-4" })
1056
+ children: /* @__PURE__ */ jsx6(Trash22, { "aria-hidden": "true", className: "w-4 h-4" })
878
1057
  }
879
1058
  )
880
1059
  ] }, exception.id)) }),
881
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center gap-2", children: [
882
- /* @__PURE__ */ jsx5(
883
- "input",
1060
+ /* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center gap-2", children: [
1061
+ /* @__PURE__ */ jsx6(
1062
+ DateTimeField,
884
1063
  {
885
- "aria-label": messages["availability.exceptionFrom"],
886
- type: "datetime-local",
1064
+ label: messages["availability.exceptionFrom"],
887
1065
  value: from,
888
- onChange: (event) => setFrom(event.target.value),
889
- className: SELECT_CLASS
1066
+ onChange: setFrom
890
1067
  }
891
1068
  ),
892
- /* @__PURE__ */ jsx5(
893
- "input",
1069
+ /* @__PURE__ */ jsx6(
1070
+ DateTimeField,
894
1071
  {
895
- "aria-label": messages["availability.exceptionUntil"],
896
- type: "datetime-local",
1072
+ label: messages["availability.exceptionUntil"],
897
1073
  value: until,
898
- onChange: (event) => setUntil(event.target.value),
899
- className: SELECT_CLASS
1074
+ onChange: setUntil
900
1075
  }
901
1076
  ),
902
- /* @__PURE__ */ jsxs4(
1077
+ /* @__PURE__ */ jsxs5(
903
1078
  "select",
904
1079
  {
905
1080
  "aria-label": messages["availability.exceptionKind.blocked"],
@@ -907,12 +1082,12 @@ function AvailabilityExceptionsEditor({ resourceId }) {
907
1082
  onChange: (event) => setKind(event.target.value),
908
1083
  className: SELECT_CLASS,
909
1084
  children: [
910
- /* @__PURE__ */ jsx5("option", { value: AVAILABILITY_EXCEPTION_KIND.BLOCK, children: messages["availability.exceptionKind.blocked"] }),
911
- /* @__PURE__ */ jsx5("option", { value: AVAILABILITY_EXCEPTION_KIND.EXTRA, children: messages["availability.exceptionKind.extra"] })
1085
+ /* @__PURE__ */ jsx6("option", { value: AVAILABILITY_EXCEPTION_KIND.BLOCK, children: messages["availability.exceptionKind.blocked"] }),
1086
+ /* @__PURE__ */ jsx6("option", { value: AVAILABILITY_EXCEPTION_KIND.EXTRA, children: messages["availability.exceptionKind.extra"] })
912
1087
  ]
913
1088
  }
914
1089
  ),
915
- /* @__PURE__ */ jsx5(
1090
+ /* @__PURE__ */ jsx6(
916
1091
  "input",
917
1092
  {
918
1093
  "aria-label": messages["availability.exceptionReason"],
@@ -923,7 +1098,7 @@ function AvailabilityExceptionsEditor({ resourceId }) {
923
1098
  className: SELECT_CLASS
924
1099
  }
925
1100
  ),
926
- /* @__PURE__ */ jsxs4(
1101
+ /* @__PURE__ */ jsxs5(
927
1102
  "button",
928
1103
  {
929
1104
  type: "button",
@@ -931,7 +1106,7 @@ function AvailabilityExceptionsEditor({ resourceId }) {
931
1106
  disabled: addException.isPending,
932
1107
  className: "inline-flex items-center gap-2 min-h-11 px-3 py-2 rounded-lg text-sm font-medium bg-brand-600 text-white hover:bg-brand-700 disabled:opacity-50",
933
1108
  children: [
934
- /* @__PURE__ */ jsx5(Plus2, { "aria-hidden": "true", className: "w-4 h-4" }),
1109
+ /* @__PURE__ */ jsx6(Plus2, { "aria-hidden": "true", className: "w-4 h-4" }),
935
1110
  messages["availability.addException"]
936
1111
  ]
937
1112
  }
@@ -941,25 +1116,25 @@ function AvailabilityExceptionsEditor({ resourceId }) {
941
1116
  }
942
1117
 
943
1118
  // src/components/AvailabilityEditor.tsx
944
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1119
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
945
1120
  function AvailabilityEditor({ resourceId, timezone }) {
946
1121
  const { locale } = useSchedulingConfig();
947
1122
  const messages = resolveSchedulingMessages(locale);
948
- return /* @__PURE__ */ jsxs5("div", { className: "space-y-6", children: [
949
- /* @__PURE__ */ jsxs5("p", { className: "inline-flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400", children: [
950
- /* @__PURE__ */ jsxs5("span", { className: "font-medium", children: [
1123
+ return /* @__PURE__ */ jsxs6("div", { className: "space-y-6", children: [
1124
+ /* @__PURE__ */ jsxs6("p", { className: "inline-flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400", children: [
1125
+ /* @__PURE__ */ jsxs6("span", { className: "font-medium", children: [
951
1126
  messages["availability.resourceTimezone"],
952
1127
  ":"
953
1128
  ] }),
954
1129
  timezone
955
1130
  ] }),
956
- /* @__PURE__ */ jsx6(WeeklyRulesEditor, { resourceId }),
957
- /* @__PURE__ */ jsx6(AvailabilityExceptionsEditor, { resourceId })
1131
+ /* @__PURE__ */ jsx7(WeeklyRulesEditor, { resourceId }),
1132
+ /* @__PURE__ */ jsx7(AvailabilityExceptionsEditor, { resourceId, timezone })
958
1133
  ] });
959
1134
  }
960
1135
 
961
1136
  // src/workspace/AvailabilityArea.tsx
962
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1137
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
963
1138
  function AvailabilityArea() {
964
1139
  const { locale } = useSchedulingConfig();
965
1140
  const messages = resolveSchedulingMessages(locale);
@@ -967,25 +1142,25 @@ function AvailabilityArea() {
967
1142
  const [resourceId, setResourceId] = useState4("");
968
1143
  const resources = data?.data ?? [];
969
1144
  const selectedResource = resources.find((resource) => resource.id === resourceId);
970
- return /* @__PURE__ */ jsxs6("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
971
- /* @__PURE__ */ jsxs6("label", { className: "flex items-center gap-2 text-sm", children: [
972
- /* @__PURE__ */ jsx7("span", { className: "font-medium text-gray-700 dark:text-gray-300", children: messages["agenda.resourceLabel"] }),
973
- /* @__PURE__ */ jsxs6(
1145
+ return /* @__PURE__ */ jsxs7("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
1146
+ /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-2 text-sm", children: [
1147
+ /* @__PURE__ */ jsx8("span", { className: "font-medium text-gray-700 dark:text-gray-300", children: messages["agenda.resourceLabel"] }),
1148
+ /* @__PURE__ */ jsxs7(
974
1149
  "select",
975
1150
  {
976
1151
  value: resourceId,
977
1152
  onChange: (event) => setResourceId(event.target.value),
978
1153
  className: "min-h-11 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 px-2 text-sm",
979
1154
  children: [
980
- /* @__PURE__ */ jsx7("option", { value: "", children: "\u2014" }),
981
- resources.map((resource) => /* @__PURE__ */ jsx7("option", { value: resource.id, children: resource.name }, resource.id))
1155
+ /* @__PURE__ */ jsx8("option", { value: "", children: "\u2014" }),
1156
+ resources.map((resource) => /* @__PURE__ */ jsx8("option", { value: resource.id, children: resource.name }, resource.id))
982
1157
  ]
983
1158
  }
984
1159
  )
985
1160
  ] }),
986
- isError && /* @__PURE__ */ jsx7("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.loadFailure"] }),
987
- isLoading && /* @__PURE__ */ jsx7("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }),
988
- selectedResource && /* @__PURE__ */ jsx7(
1161
+ isError && /* @__PURE__ */ jsx8("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.loadFailure"] }),
1162
+ isLoading && /* @__PURE__ */ jsx8("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }),
1163
+ selectedResource && /* @__PURE__ */ jsx8(
989
1164
  AvailabilityEditor,
990
1165
  {
991
1166
  resourceId: selectedResource.id,
@@ -998,6 +1173,7 @@ function AvailabilityArea() {
998
1173
 
999
1174
  // src/workspace/BookingsArea.tsx
1000
1175
  import { useState as useState8 } from "react";
1176
+ import { MAX_PAGE_SIZE as MAX_PAGE_SIZE3 } from "@adatechnology/scheduling-contracts";
1001
1177
 
1002
1178
  // src/components/BookingDrawer.tsx
1003
1179
  import { XCircle } from "lucide-react";
@@ -1007,7 +1183,7 @@ import { BOOKING_STATUS } from "@adatechnology/scheduling-contracts";
1007
1183
  // src/components/SidePanel.tsx
1008
1184
  import { X } from "lucide-react";
1009
1185
  import { useEffect } from "react";
1010
- import { Fragment, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1186
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1011
1187
  var BUTTON_CLASS = "inline-flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors min-h-11";
1012
1188
  function SidePanel({ title, closeLabel, onClose, headerActions, children }) {
1013
1189
  useEffect(() => {
@@ -1017,8 +1193,8 @@ function SidePanel({ title, closeLabel, onClose, headerActions, children }) {
1017
1193
  window.addEventListener("keydown", handleKeyDown);
1018
1194
  return () => window.removeEventListener("keydown", handleKeyDown);
1019
1195
  }, [onClose]);
1020
- return /* @__PURE__ */ jsxs7(Fragment, { children: [
1021
- /* @__PURE__ */ jsx8(
1196
+ return /* @__PURE__ */ jsxs8(Fragment2, { children: [
1197
+ /* @__PURE__ */ jsx9(
1022
1198
  "button",
1023
1199
  {
1024
1200
  type: "button",
@@ -1028,29 +1204,29 @@ function SidePanel({ title, closeLabel, onClose, headerActions, children }) {
1028
1204
  className: "absolute inset-0 z-10 bg-gray-900/20 wide:hidden"
1029
1205
  }
1030
1206
  ),
1031
- /* @__PURE__ */ jsxs7(
1207
+ /* @__PURE__ */ jsxs8(
1032
1208
  "section",
1033
1209
  {
1034
1210
  "aria-label": title,
1035
1211
  className: "absolute inset-y-0 right-0 z-20 flex w-full max-w-full flex-col bg-white shadow-2xl desktop:w-[28rem] dark:bg-gray-900 wide:static wide:z-auto wide:shrink-0 wide:border-l wide:border-gray-200 wide:shadow-none wide:dark:border-gray-700",
1036
1212
  children: [
1037
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 border-b border-gray-200 px-4 py-3 dark:border-gray-700", children: [
1038
- /* @__PURE__ */ jsx8("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 mr-auto", children: title }),
1213
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 border-b border-gray-200 px-4 py-3 dark:border-gray-700", children: [
1214
+ /* @__PURE__ */ jsx9("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 mr-auto", children: title }),
1039
1215
  headerActions,
1040
- /* @__PURE__ */ jsxs7(
1216
+ /* @__PURE__ */ jsxs8(
1041
1217
  "button",
1042
1218
  {
1043
1219
  type: "button",
1044
1220
  onClick: onClose,
1045
1221
  className: `${BUTTON_CLASS} text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800`,
1046
1222
  children: [
1047
- /* @__PURE__ */ jsx8(X, { "aria-hidden": "true", className: "w-4 h-4" }),
1223
+ /* @__PURE__ */ jsx9(X, { "aria-hidden": "true", className: "w-4 h-4" }),
1048
1224
  closeLabel
1049
1225
  ]
1050
1226
  }
1051
1227
  )
1052
1228
  ] }),
1053
- /* @__PURE__ */ jsx8("div", { className: "min-h-0 flex-1 overflow-y-auto p-4", children })
1229
+ /* @__PURE__ */ jsx9("div", { className: "min-h-0 flex-1 overflow-y-auto p-4", children })
1054
1230
  ]
1055
1231
  }
1056
1232
  )
@@ -1058,16 +1234,13 @@ function SidePanel({ title, closeLabel, onClose, headerActions, children }) {
1058
1234
  }
1059
1235
 
1060
1236
  // src/components/BookingDrawer.tsx
1061
- import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1237
+ import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1238
+ var BROWSER_TIME_ZONE = Intl.DateTimeFormat().resolvedOptions().timeZone;
1062
1239
  var ACTION_BUTTON_CLASS = "min-h-11 px-3 rounded-lg text-sm font-medium border border-gray-300 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800";
1063
1240
  var PRIMARY_BUTTON_CLASS = "min-h-11 px-3 rounded-lg text-sm font-medium bg-brand-600 text-white hover:bg-brand-700";
1064
1241
  var DANGER_BUTTON_CLASS = "inline-flex items-center gap-2 min-h-11 px-3 rounded-lg text-sm font-medium text-red-700 hover:bg-red-50";
1065
1242
  var INPUT_CLASS = "min-h-11 w-full px-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-sm";
1066
- function toLocalInputValue(date) {
1067
- const pad = (value) => String(value).padStart(2, "0");
1068
- return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
1069
- }
1070
- function BookingDrawer({ booking, onClose }) {
1243
+ function BookingDrawer({ booking, resourceTimezone, onClose }) {
1071
1244
  const { locale } = useSchedulingConfig();
1072
1245
  const messages = resolveSchedulingMessages(locale);
1073
1246
  const confirmBooking = useConfirmBooking();
@@ -1075,12 +1248,13 @@ function BookingDrawer({ booking, onClose }) {
1075
1248
  const markNoShow = useMarkNoShow();
1076
1249
  const cancelBooking = useCancelBooking();
1077
1250
  const rescheduleBooking = useRescheduleBooking();
1251
+ const timezone = resourceTimezone ?? BROWSER_TIME_ZONE;
1078
1252
  const [isCancelling, setIsCancelling] = useState5(false);
1079
1253
  const [cancelledBy, setCancelledBy] = useState5("");
1080
1254
  const [cancellationReason, setCancellationReason] = useState5("");
1081
1255
  const [isRescheduling, setIsRescheduling] = useState5(false);
1082
- const [start, setStart] = useState5(() => toLocalInputValue(booking.startsAt));
1083
- const [end, setEnd] = useState5(() => toLocalInputValue(booking.endsAt));
1256
+ const [start, setStart] = useState5(() => formatDateTimeLocalInTimeZone(booking.startsAt, timezone));
1257
+ const [end, setEnd] = useState5(() => formatDateTimeLocalInTimeZone(booking.endsAt, timezone));
1084
1258
  async function handleCancel() {
1085
1259
  if (!cancelledBy) return;
1086
1260
  try {
@@ -1094,42 +1268,57 @@ function BookingDrawer({ booking, onClose }) {
1094
1268
  }
1095
1269
  async function handleReschedule() {
1096
1270
  try {
1097
- await rescheduleBooking.mutateAsync({ id: booking.id, input: { during: { start: new Date(start), end: new Date(end) } } });
1271
+ await rescheduleBooking.mutateAsync({
1272
+ id: booking.id,
1273
+ input: {
1274
+ during: {
1275
+ start: parseDateTimeLocalInTimeZone(start, timezone),
1276
+ end: parseDateTimeLocalInTimeZone(end, timezone)
1277
+ }
1278
+ }
1279
+ });
1098
1280
  setIsRescheduling(false);
1099
1281
  } catch {
1100
1282
  }
1101
1283
  }
1102
1284
  const isTerminal = booking.status === BOOKING_STATUS.CANCELLED || booking.status === BOOKING_STATUS.COMPLETED || booking.status === BOOKING_STATUS.NO_SHOW;
1103
- return /* @__PURE__ */ jsx9(SidePanel, { title: messages["booking.detailTitle"], closeLabel: messages["common.close"], onClose, children: /* @__PURE__ */ jsxs8("div", { className: "space-y-4", children: [
1104
- /* @__PURE__ */ jsxs8("div", { children: [
1105
- /* @__PURE__ */ jsx9("p", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: booking.title }),
1106
- /* @__PURE__ */ jsx9("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages[`booking.status.${booking.status === "no_show" ? "noShow" : booking.status}`] }),
1107
- /* @__PURE__ */ jsxs8("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
1285
+ return /* @__PURE__ */ jsx10(SidePanel, { title: messages["booking.detailTitle"], closeLabel: messages["common.close"], onClose, children: /* @__PURE__ */ jsxs9("div", { className: "space-y-4", children: [
1286
+ /* @__PURE__ */ jsxs9("div", { children: [
1287
+ /* @__PURE__ */ jsx10("p", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: booking.title }),
1288
+ /* @__PURE__ */ jsx10("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages[`booking.status.${booking.status === "no_show" ? "noShow" : booking.status}`] }),
1289
+ /* @__PURE__ */ jsxs9("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
1108
1290
  booking.startsAt.toLocaleString(locale),
1109
1291
  " \u2192 ",
1110
1292
  booking.endsAt.toLocaleString(locale)
1111
1293
  ] })
1112
1294
  ] }),
1113
- (confirmBooking.isError || completeBooking.isError || markNoShow.isError || cancelBooking.isError || rescheduleBooking.isError) && /* @__PURE__ */ jsx9("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.actionFailure"] }),
1114
- !isTerminal && /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap gap-2", children: [
1115
- booking.status === BOOKING_STATUS.REQUESTED && /* @__PURE__ */ jsx9("button", { type: "button", onClick: () => confirmBooking.mutate(booking.id), className: PRIMARY_BUTTON_CLASS, children: messages["booking.confirm"] }),
1116
- booking.status === BOOKING_STATUS.CONFIRMED && /* @__PURE__ */ jsxs8(Fragment2, { children: [
1117
- /* @__PURE__ */ jsx9("button", { type: "button", onClick: () => completeBooking.mutate(booking.id), className: ACTION_BUTTON_CLASS, children: messages["booking.complete"] }),
1118
- /* @__PURE__ */ jsx9("button", { type: "button", onClick: () => markNoShow.mutate(booking.id), className: ACTION_BUTTON_CLASS, children: messages["booking.markNoShow"] }),
1119
- /* @__PURE__ */ jsx9("button", { type: "button", onClick: () => setIsRescheduling(true), className: ACTION_BUTTON_CLASS, children: messages["booking.reschedule"] })
1295
+ (confirmBooking.isError || completeBooking.isError || markNoShow.isError || cancelBooking.isError || rescheduleBooking.isError) && /* @__PURE__ */ jsx10("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.actionFailure"] }),
1296
+ !isTerminal && /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap gap-2", children: [
1297
+ booking.status === BOOKING_STATUS.REQUESTED && /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => confirmBooking.mutate(booking.id), className: PRIMARY_BUTTON_CLASS, children: messages["booking.confirm"] }),
1298
+ booking.status === BOOKING_STATUS.CONFIRMED && /* @__PURE__ */ jsxs9(Fragment3, { children: [
1299
+ /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => completeBooking.mutate(booking.id), className: ACTION_BUTTON_CLASS, children: messages["booking.complete"] }),
1300
+ /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => markNoShow.mutate(booking.id), className: ACTION_BUTTON_CLASS, children: messages["booking.markNoShow"] }),
1301
+ /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => setIsRescheduling(true), className: ACTION_BUTTON_CLASS, children: messages["booking.reschedule"] })
1120
1302
  ] }),
1121
- /* @__PURE__ */ jsxs8("button", { type: "button", onClick: () => setIsCancelling(true), className: DANGER_BUTTON_CLASS, children: [
1122
- /* @__PURE__ */ jsx9(XCircle, { "aria-hidden": "true", className: "w-4 h-4" }),
1303
+ /* @__PURE__ */ jsxs9("button", { type: "button", onClick: () => setIsCancelling(true), className: DANGER_BUTTON_CLASS, children: [
1304
+ /* @__PURE__ */ jsx10(XCircle, { "aria-hidden": "true", className: "w-4 h-4" }),
1123
1305
  messages["booking.cancel"]
1124
1306
  ] })
1125
1307
  ] }),
1126
- isRescheduling && /* @__PURE__ */ jsxs8("div", { className: "space-y-2 rounded-lg border border-gray-200 dark:border-gray-700 p-3", children: [
1127
- /* @__PURE__ */ jsx9("input", { type: "datetime-local", value: start, onChange: (event) => setStart(event.target.value), className: INPUT_CLASS }),
1128
- /* @__PURE__ */ jsx9("input", { type: "datetime-local", value: end, onChange: (event) => setEnd(event.target.value), className: INPUT_CLASS }),
1129
- /* @__PURE__ */ jsx9("button", { type: "button", onClick: handleReschedule, disabled: rescheduleBooking.isPending, className: PRIMARY_BUTTON_CLASS, children: messages["common.save"] })
1308
+ isRescheduling && /* @__PURE__ */ jsxs9("div", { className: "space-y-2 rounded-lg border border-gray-200 dark:border-gray-700 p-3", children: [
1309
+ /* @__PURE__ */ jsx10(
1310
+ DateTimeField,
1311
+ {
1312
+ label: messages["booking.rescheduleStart"],
1313
+ value: start,
1314
+ onChange: setStart
1315
+ }
1316
+ ),
1317
+ /* @__PURE__ */ jsx10(DateTimeField, { label: messages["booking.rescheduleEnd"], value: end, onChange: setEnd }),
1318
+ /* @__PURE__ */ jsx10("button", { type: "button", onClick: handleReschedule, disabled: rescheduleBooking.isPending, className: PRIMARY_BUTTON_CLASS, children: messages["common.save"] })
1130
1319
  ] }),
1131
- isCancelling && /* @__PURE__ */ jsxs8("div", { className: "space-y-2 rounded-lg border border-gray-200 dark:border-gray-700 p-3", children: [
1132
- /* @__PURE__ */ jsx9(
1320
+ isCancelling && /* @__PURE__ */ jsxs9("div", { className: "space-y-2 rounded-lg border border-gray-200 dark:border-gray-700 p-3", children: [
1321
+ /* @__PURE__ */ jsx10(
1133
1322
  "input",
1134
1323
  {
1135
1324
  type: "text",
@@ -1139,7 +1328,7 @@ function BookingDrawer({ booking, onClose }) {
1139
1328
  className: INPUT_CLASS
1140
1329
  }
1141
1330
  ),
1142
- /* @__PURE__ */ jsx9(
1331
+ /* @__PURE__ */ jsx10(
1143
1332
  "input",
1144
1333
  {
1145
1334
  type: "text",
@@ -1149,8 +1338,8 @@ function BookingDrawer({ booking, onClose }) {
1149
1338
  className: INPUT_CLASS
1150
1339
  }
1151
1340
  ),
1152
- /* @__PURE__ */ jsxs8("button", { type: "button", onClick: handleCancel, disabled: cancelBooking.isPending, className: DANGER_BUTTON_CLASS, children: [
1153
- /* @__PURE__ */ jsx9(XCircle, { "aria-hidden": "true", className: "w-4 h-4" }),
1341
+ /* @__PURE__ */ jsxs9("button", { type: "button", onClick: handleCancel, disabled: cancelBooking.isPending, className: DANGER_BUTTON_CLASS, children: [
1342
+ /* @__PURE__ */ jsx10(XCircle, { "aria-hidden": "true", className: "w-4 h-4" }),
1154
1343
  messages["booking.cancel"]
1155
1344
  ] })
1156
1345
  ] })
@@ -1160,18 +1349,23 @@ function BookingDrawer({ booking, onClose }) {
1160
1349
  // src/components/BookingsTable.tsx
1161
1350
  import { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, ArrowUpDown } from "lucide-react";
1162
1351
  import { useState as useState6 } from "react";
1163
- import { BOOKING_STATUS as BOOKING_STATUS2 } from "@adatechnology/scheduling-contracts";
1352
+ import { BOOKING_STATUS as BOOKING_STATUS3 } from "@adatechnology/scheduling-contracts";
1164
1353
 
1165
1354
  // src/components/bookingsTableState.util.ts
1355
+ import { BOOKING_STATUS as BOOKING_STATUS2 } from "@adatechnology/scheduling-contracts";
1166
1356
  var DEFAULT_BOOKINGS_TABLE_STATE = {
1167
1357
  sortDirection: "asc",
1168
1358
  statusFilters: [],
1169
1359
  page: 1
1170
1360
  };
1171
1361
  var SORT_COLUMNS = ["title", "status", "startsAt", "endsAt"];
1362
+ var BOOKING_STATUSES = Object.values(BOOKING_STATUS2);
1172
1363
  function isBookingSortColumn(value) {
1173
1364
  return SORT_COLUMNS.includes(value);
1174
1365
  }
1366
+ function isBookingStatus(value) {
1367
+ return BOOKING_STATUSES.includes(value);
1368
+ }
1175
1369
  function parsePage(value) {
1176
1370
  const parsed = Number(value);
1177
1371
  return Number.isInteger(parsed) && parsed > 0 ? parsed : 1;
@@ -1181,7 +1375,7 @@ function parseBookingsTableState(search) {
1181
1375
  const sortColumnParam = params.get("sortBy");
1182
1376
  const sortColumn = isBookingSortColumn(sortColumnParam) ? sortColumnParam : void 0;
1183
1377
  const sortDirection = params.get("sortDirection") === "desc" ? "desc" : "asc";
1184
- const statusFilters = params.getAll("status");
1378
+ const statusFilters = params.getAll("status").filter(isBookingStatus);
1185
1379
  const page = parsePage(params.get("page"));
1186
1380
  return { ...sortColumn ? { sortColumn } : {}, sortDirection, statusFilters, page };
1187
1381
  }
@@ -1204,13 +1398,14 @@ function filterBookingsByStatus(bookings, statusFilters) {
1204
1398
  }
1205
1399
 
1206
1400
  // src/components/BookingsTable.tsx
1207
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1208
- var ALL_STATUSES = Object.values(BOOKING_STATUS2);
1401
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1402
+ var ALL_STATUSES = Object.values(BOOKING_STATUS3);
1209
1403
  var HEADER_BUTTON_CLASS = "inline-flex items-center gap-1 text-left text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400";
1210
1404
  var CHECKBOX_CELL_CLASS = "px-3 py-2";
1211
- function nextSortDirection(column, currentColumn, currentDirection) {
1212
- if (currentColumn !== column) return "asc";
1213
- return currentDirection === "asc" ? "desc" : "asc";
1405
+ function nextSortState(column, currentColumn, currentDirection) {
1406
+ if (currentColumn !== column) return { sortColumn: column, sortDirection: "asc" };
1407
+ if (currentDirection === "asc") return { sortColumn: column, sortDirection: "desc" };
1408
+ return { sortColumn: void 0, sortDirection: "asc" };
1214
1409
  }
1215
1410
  function BookingsTable({
1216
1411
  bookings,
@@ -1228,8 +1423,7 @@ function BookingsTable({
1228
1423
  function toggleSort(column) {
1229
1424
  onStateChange?.({
1230
1425
  ...state,
1231
- sortColumn: column,
1232
- sortDirection: nextSortDirection(column, state.sortColumn, state.sortDirection)
1426
+ ...nextSortState(column, state.sortColumn, state.sortDirection)
1233
1427
  });
1234
1428
  }
1235
1429
  function toggleStatusFilter(status) {
@@ -1253,19 +1447,20 @@ function BookingsTable({
1253
1447
  setSelected(next);
1254
1448
  }
1255
1449
  function renderSortIcon(column) {
1256
- if (state.sortColumn !== column) return /* @__PURE__ */ jsx10(ArrowUpDown, { "aria-hidden": "true", className: "w-3 h-3" });
1257
- return state.sortDirection === "asc" ? /* @__PURE__ */ jsx10(ArrowUp, { "aria-hidden": "true", className: "w-3 h-3" }) : /* @__PURE__ */ jsx10(ArrowDown, { "aria-hidden": "true", className: "w-3 h-3" });
1450
+ if (state.sortColumn !== column) return /* @__PURE__ */ jsx11(ArrowUpDown, { "aria-hidden": "true", className: "w-3 h-3" });
1451
+ return state.sortDirection === "asc" ? /* @__PURE__ */ jsx11(ArrowUp, { "aria-hidden": "true", className: "w-3 h-3" }) : /* @__PURE__ */ jsx11(ArrowDown, { "aria-hidden": "true", className: "w-3 h-3" });
1258
1452
  }
1259
1453
  function renderHeader(column, labelKey) {
1260
- return /* @__PURE__ */ jsx10("th", { scope: "col", className: "px-3 py-2", children: /* @__PURE__ */ jsxs9("button", { type: "button", onClick: () => toggleSort(column), className: HEADER_BUTTON_CLASS, children: [
1454
+ const ariaSort = state.sortColumn !== column ? "none" : state.sortDirection === "asc" ? "ascending" : "descending";
1455
+ return /* @__PURE__ */ jsx11("th", { scope: "col", className: "px-3 py-2", "aria-sort": ariaSort, children: /* @__PURE__ */ jsxs10("button", { type: "button", onClick: () => toggleSort(column), className: HEADER_BUTTON_CLASS, children: [
1261
1456
  messages[labelKey],
1262
1457
  renderSortIcon(column)
1263
1458
  ] }) });
1264
1459
  }
1265
- return /* @__PURE__ */ jsxs9("div", { className: "space-y-3", children: [
1266
- /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-3", children: [
1267
- ALL_STATUSES.map((status) => /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-1.5 text-sm min-h-11", children: [
1268
- /* @__PURE__ */ jsx10(
1460
+ return /* @__PURE__ */ jsxs10("div", { className: "space-y-3", children: [
1461
+ /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center gap-3", children: [
1462
+ ALL_STATUSES.map((status) => /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-1.5 text-sm min-h-11", children: [
1463
+ /* @__PURE__ */ jsx11(
1269
1464
  "input",
1270
1465
  {
1271
1466
  type: "checkbox",
@@ -1275,7 +1470,7 @@ function BookingsTable({
1275
1470
  ),
1276
1471
  messages[`booking.status.${status === "no_show" ? "noShow" : status}`]
1277
1472
  ] }, status)),
1278
- !isBookingsTableStateDefault(state) && /* @__PURE__ */ jsx10(
1473
+ !isBookingsTableStateDefault(state) && /* @__PURE__ */ jsx11(
1279
1474
  "button",
1280
1475
  {
1281
1476
  type: "button",
@@ -1285,7 +1480,7 @@ function BookingsTable({
1285
1480
  }
1286
1481
  )
1287
1482
  ] }),
1288
- selected.size > 0 && bulkActions.length > 0 && /* @__PURE__ */ jsx10("div", { className: "flex items-center gap-2 rounded-lg bg-brand-50 dark:bg-brand-900/30 px-3 py-2", children: bulkActions.map((action) => /* @__PURE__ */ jsx10(
1483
+ selected.size > 0 && bulkActions.length > 0 && /* @__PURE__ */ jsx11("div", { className: "flex items-center gap-2 rounded-lg bg-brand-50 dark:bg-brand-900/30 px-3 py-2", children: bulkActions.map((action) => /* @__PURE__ */ jsx11(
1289
1484
  "button",
1290
1485
  {
1291
1486
  type: "button",
@@ -1295,10 +1490,10 @@ function BookingsTable({
1295
1490
  },
1296
1491
  action.key
1297
1492
  )) }),
1298
- /* @__PURE__ */ jsxs9("div", { className: "overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-700", children: [
1299
- /* @__PURE__ */ jsxs9("table", { className: "min-w-full text-sm", children: [
1300
- /* @__PURE__ */ jsx10("thead", { className: "border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsxs9("tr", { children: [
1301
- /* @__PURE__ */ jsx10("th", { scope: "col", className: CHECKBOX_CELL_CLASS, children: /* @__PURE__ */ jsx10(
1493
+ /* @__PURE__ */ jsxs10("div", { className: "overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-700", children: [
1494
+ /* @__PURE__ */ jsxs10("table", { className: "min-w-full text-sm", children: [
1495
+ /* @__PURE__ */ jsx11("thead", { className: "border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsxs10("tr", { children: [
1496
+ /* @__PURE__ */ jsx11("th", { scope: "col", className: CHECKBOX_CELL_CLASS, children: /* @__PURE__ */ jsx11(
1302
1497
  "input",
1303
1498
  {
1304
1499
  type: "checkbox",
@@ -1312,12 +1507,12 @@ function BookingsTable({
1312
1507
  renderHeader("startsAt", "booking.column.startsAt"),
1313
1508
  renderHeader("endsAt", "booking.column.endsAt")
1314
1509
  ] }) }),
1315
- /* @__PURE__ */ jsx10("tbody", { children: visibleBookings.map((booking, index) => /* @__PURE__ */ jsxs9(
1510
+ /* @__PURE__ */ jsx11("tbody", { children: visibleBookings.map((booking, index) => /* @__PURE__ */ jsxs10(
1316
1511
  "tr",
1317
1512
  {
1318
1513
  className: index % 2 === 1 ? "bg-gray-50 dark:bg-gray-800/50" : void 0,
1319
1514
  children: [
1320
- /* @__PURE__ */ jsx10("td", { className: CHECKBOX_CELL_CLASS, children: /* @__PURE__ */ jsx10(
1515
+ /* @__PURE__ */ jsx11("td", { className: CHECKBOX_CELL_CLASS, children: /* @__PURE__ */ jsx11(
1321
1516
  "input",
1322
1517
  {
1323
1518
  type: "checkbox",
@@ -1326,19 +1521,19 @@ function BookingsTable({
1326
1521
  onChange: () => toggleRowSelected(booking.id)
1327
1522
  }
1328
1523
  ) }),
1329
- /* @__PURE__ */ jsx10("td", { className: "px-3 py-2", children: /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => onRowClick?.(booking), className: "min-h-11 text-left hover:underline", children: booking.title }) }),
1330
- /* @__PURE__ */ jsx10("td", { className: "px-3 py-2", children: messages[`booking.status.${booking.status === "no_show" ? "noShow" : booking.status}`] }),
1331
- /* @__PURE__ */ jsx10("td", { className: "px-3 py-2", children: booking.startsAt.toLocaleString(locale) }),
1332
- /* @__PURE__ */ jsx10("td", { className: "px-3 py-2", children: booking.endsAt.toLocaleString(locale) })
1524
+ /* @__PURE__ */ jsx11("td", { className: "px-3 py-2", children: /* @__PURE__ */ jsx11("button", { type: "button", onClick: () => onRowClick?.(booking), className: "min-h-11 text-left hover:underline", children: booking.title }) }),
1525
+ /* @__PURE__ */ jsx11("td", { className: "px-3 py-2", children: messages[`booking.status.${booking.status === "no_show" ? "noShow" : booking.status}`] }),
1526
+ /* @__PURE__ */ jsx11("td", { className: "px-3 py-2", children: booking.startsAt.toLocaleString(locale) }),
1527
+ /* @__PURE__ */ jsx11("td", { className: "px-3 py-2", children: booking.endsAt.toLocaleString(locale) })
1333
1528
  ]
1334
1529
  },
1335
1530
  booking.id
1336
1531
  )) })
1337
1532
  ] }),
1338
- visibleBookings.length === 0 && /* @__PURE__ */ jsx10("p", { className: "px-3 py-4 text-sm text-gray-500 dark:text-gray-400", children: messages["common.empty"] })
1533
+ visibleBookings.length === 0 && /* @__PURE__ */ jsx11("p", { className: "px-3 py-4 text-sm text-gray-500 dark:text-gray-400", children: messages["common.empty"] })
1339
1534
  ] }),
1340
- pagination && pagination.totalPages > 1 && /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-end gap-3", children: [
1341
- /* @__PURE__ */ jsx10(
1535
+ pagination && pagination.totalPages > 1 && /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-end gap-3", children: [
1536
+ /* @__PURE__ */ jsx11(
1342
1537
  "button",
1343
1538
  {
1344
1539
  type: "button",
@@ -1346,15 +1541,15 @@ function BookingsTable({
1346
1541
  disabled: state.page <= 1,
1347
1542
  onClick: () => goToPage(state.page - 1),
1348
1543
  className: "min-h-11 min-w-11 inline-flex items-center justify-center rounded-lg border border-gray-300 dark:border-gray-700 disabled:opacity-50",
1349
- children: /* @__PURE__ */ jsx10(ArrowLeft, { "aria-hidden": "true", className: "w-4 h-4" })
1544
+ children: /* @__PURE__ */ jsx11(ArrowLeft, { "aria-hidden": "true", className: "w-4 h-4" })
1350
1545
  }
1351
1546
  ),
1352
- /* @__PURE__ */ jsxs9("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
1547
+ /* @__PURE__ */ jsxs10("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
1353
1548
  state.page,
1354
1549
  " / ",
1355
1550
  pagination.totalPages
1356
1551
  ] }),
1357
- /* @__PURE__ */ jsx10(
1552
+ /* @__PURE__ */ jsx11(
1358
1553
  "button",
1359
1554
  {
1360
1555
  type: "button",
@@ -1362,7 +1557,7 @@ function BookingsTable({
1362
1557
  disabled: state.page >= pagination.totalPages,
1363
1558
  onClick: () => goToPage(state.page + 1),
1364
1559
  className: "min-h-11 min-w-11 inline-flex items-center justify-center rounded-lg border border-gray-300 dark:border-gray-700 disabled:opacity-50",
1365
- children: /* @__PURE__ */ jsx10(ArrowRight, { "aria-hidden": "true", className: "w-4 h-4" })
1560
+ children: /* @__PURE__ */ jsx11(ArrowRight, { "aria-hidden": "true", className: "w-4 h-4" })
1366
1561
  }
1367
1562
  )
1368
1563
  ] })
@@ -1391,7 +1586,7 @@ function useBookingsTableState() {
1391
1586
  }
1392
1587
 
1393
1588
  // src/workspace/BookingsArea.tsx
1394
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1589
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1395
1590
  var PAGE_SIZE = 20;
1396
1591
  function BookingsArea() {
1397
1592
  const { locale } = useSchedulingConfig();
@@ -1406,14 +1601,19 @@ function BookingsArea() {
1406
1601
  sortDirection: tableState.sortColumn ? tableState.sortDirection : void 0
1407
1602
  });
1408
1603
  const confirmBooking = useConfirmBooking();
1604
+ const { data: resourcesData } = useResources({ pageSize: MAX_PAGE_SIZE3 });
1409
1605
  const [selectedBookingId, setSelectedBookingId] = useState8(void 0);
1410
1606
  const selectedBooking = data?.data.find((booking) => booking.id === selectedBookingId);
1607
+ const selectedBookingResourceTimezone = resourcesData?.data.find(
1608
+ (resource) => resource.id === selectedBooking?.resourceIds[0]
1609
+ )?.timezone;
1411
1610
  function bulkConfirm(ids) {
1412
1611
  for (const id of ids) confirmBooking.mutate(id);
1413
1612
  }
1414
- return /* @__PURE__ */ jsxs10("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
1415
- isError && /* @__PURE__ */ jsx11("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.loadFailure"] }),
1416
- isLoading ? /* @__PURE__ */ jsx11("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }) : /* @__PURE__ */ jsx11(
1613
+ return /* @__PURE__ */ jsxs11("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
1614
+ isError && /* @__PURE__ */ jsx12("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.loadFailure"] }),
1615
+ confirmBooking.isError && /* @__PURE__ */ jsx12("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.actionFailure"] }),
1616
+ isLoading ? /* @__PURE__ */ jsx12("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }) : /* @__PURE__ */ jsx12(
1417
1617
  BookingsTable,
1418
1618
  {
1419
1619
  bookings: data?.data ?? [],
@@ -1424,24 +1624,37 @@ function BookingsArea() {
1424
1624
  bulkActions: [{ key: "confirm", label: messages["booking.confirm"], onRun: bulkConfirm }]
1425
1625
  }
1426
1626
  ),
1427
- selectedBooking && /* @__PURE__ */ jsx11(BookingDrawer, { booking: selectedBooking, onClose: () => setSelectedBookingId(void 0) })
1627
+ selectedBooking && /* @__PURE__ */ jsx12(
1628
+ BookingDrawer,
1629
+ {
1630
+ booking: selectedBooking,
1631
+ resourceTimezone: selectedBookingResourceTimezone,
1632
+ onClose: () => setSelectedBookingId(void 0)
1633
+ },
1634
+ selectedBooking.id
1635
+ )
1428
1636
  ] });
1429
1637
  }
1430
1638
 
1431
1639
  // src/workspace/ResourcesArea.tsx
1432
1640
  import { Plus as Plus3, Trash2 as Trash23 } from "lucide-react";
1433
1641
  import { useState as useState10 } from "react";
1642
+ import { MAX_PAGE_SIZE as MAX_PAGE_SIZE4 } from "@adatechnology/scheduling-contracts";
1434
1643
 
1435
1644
  // src/components/ResourceForm.tsx
1436
- import { useState as useState9 } from "react";
1645
+ import { useId as useId2, useState as useState9 } from "react";
1437
1646
  import { RESOURCE_KIND } from "@adatechnology/scheduling-contracts";
1438
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1647
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1439
1648
  var INPUT_CLASS2 = "w-full min-h-11 px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500 bg-white dark:bg-gray-900";
1440
1649
  var LABEL_CLASS = "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1";
1441
1650
  var BUTTON_PRIMARY = "inline-flex items-center justify-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors min-h-11 bg-brand-600 text-white hover:bg-brand-700 disabled:opacity-50";
1442
1651
  function ResourceForm({ initialValues, onSubmit }) {
1443
1652
  const { locale } = useSchedulingConfig();
1444
1653
  const messages = resolveSchedulingMessages(locale);
1654
+ const formId = useId2();
1655
+ const nameId = `${formId}-name`;
1656
+ const kindId = `${formId}-kind`;
1657
+ const timezoneId = `${formId}-timezone`;
1445
1658
  const [name, setName] = useState9(initialValues?.name ?? "");
1446
1659
  const [kind, setKind] = useState9(initialValues?.kind ?? RESOURCE_KIND.PERSON);
1447
1660
  const [timezone, setTimezone] = useState9(initialValues?.timezone ?? "America/Sao_Paulo");
@@ -1456,13 +1669,13 @@ function ResourceForm({ initialValues, onSubmit }) {
1456
1669
  setSubmitting(false);
1457
1670
  }
1458
1671
  }
1459
- return /* @__PURE__ */ jsxs11("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1460
- /* @__PURE__ */ jsxs11("div", { children: [
1461
- /* @__PURE__ */ jsx12("label", { htmlFor: "scheduling-resource-name", className: LABEL_CLASS, children: messages["resource.name"] }),
1462
- /* @__PURE__ */ jsx12(
1672
+ return /* @__PURE__ */ jsxs12("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1673
+ /* @__PURE__ */ jsxs12("div", { children: [
1674
+ /* @__PURE__ */ jsx13("label", { htmlFor: nameId, className: LABEL_CLASS, children: messages["resource.name"] }),
1675
+ /* @__PURE__ */ jsx13(
1463
1676
  "input",
1464
1677
  {
1465
- id: "scheduling-resource-name",
1678
+ id: nameId,
1466
1679
  type: "text",
1467
1680
  required: true,
1468
1681
  value: name,
@@ -1471,29 +1684,29 @@ function ResourceForm({ initialValues, onSubmit }) {
1471
1684
  }
1472
1685
  )
1473
1686
  ] }),
1474
- /* @__PURE__ */ jsxs11("div", { children: [
1475
- /* @__PURE__ */ jsx12("label", { htmlFor: "scheduling-resource-kind", className: LABEL_CLASS, children: messages["resource.kind"] }),
1476
- /* @__PURE__ */ jsxs11(
1687
+ /* @__PURE__ */ jsxs12("div", { children: [
1688
+ /* @__PURE__ */ jsx13("label", { htmlFor: kindId, className: LABEL_CLASS, children: messages["resource.kind"] }),
1689
+ /* @__PURE__ */ jsxs12(
1477
1690
  "select",
1478
1691
  {
1479
- id: "scheduling-resource-kind",
1692
+ id: kindId,
1480
1693
  value: kind,
1481
1694
  onChange: (event) => setKind(event.target.value),
1482
1695
  className: INPUT_CLASS2,
1483
1696
  children: [
1484
- /* @__PURE__ */ jsx12("option", { value: RESOURCE_KIND.PERSON, children: messages["resource.kind.person"] }),
1485
- /* @__PURE__ */ jsx12("option", { value: RESOURCE_KIND.ROOM, children: messages["resource.kind.room"] }),
1486
- /* @__PURE__ */ jsx12("option", { value: RESOURCE_KIND.EQUIPMENT, children: messages["resource.kind.equipment"] })
1697
+ /* @__PURE__ */ jsx13("option", { value: RESOURCE_KIND.PERSON, children: messages["resource.kind.person"] }),
1698
+ /* @__PURE__ */ jsx13("option", { value: RESOURCE_KIND.ROOM, children: messages["resource.kind.room"] }),
1699
+ /* @__PURE__ */ jsx13("option", { value: RESOURCE_KIND.EQUIPMENT, children: messages["resource.kind.equipment"] })
1487
1700
  ]
1488
1701
  }
1489
1702
  )
1490
1703
  ] }),
1491
- /* @__PURE__ */ jsxs11("div", { children: [
1492
- /* @__PURE__ */ jsx12("label", { htmlFor: "scheduling-resource-timezone", className: LABEL_CLASS, children: messages["resource.timezone"] }),
1493
- /* @__PURE__ */ jsx12(
1704
+ /* @__PURE__ */ jsxs12("div", { children: [
1705
+ /* @__PURE__ */ jsx13("label", { htmlFor: timezoneId, className: LABEL_CLASS, children: messages["resource.timezone"] }),
1706
+ /* @__PURE__ */ jsx13(
1494
1707
  "input",
1495
1708
  {
1496
- id: "scheduling-resource-timezone",
1709
+ id: timezoneId,
1497
1710
  type: "text",
1498
1711
  required: true,
1499
1712
  value: timezone,
@@ -1503,47 +1716,47 @@ function ResourceForm({ initialValues, onSubmit }) {
1503
1716
  }
1504
1717
  )
1505
1718
  ] }),
1506
- initialValues && /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300 min-h-11", children: [
1507
- /* @__PURE__ */ jsx12("input", { type: "checkbox", checked: active, onChange: (event) => setActive(event.target.checked) }),
1719
+ initialValues && /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300 min-h-11", children: [
1720
+ /* @__PURE__ */ jsx13("input", { type: "checkbox", checked: active, onChange: (event) => setActive(event.target.checked) }),
1508
1721
  messages["resource.active"]
1509
1722
  ] }),
1510
- /* @__PURE__ */ jsx12("button", { type: "submit", disabled: submitting, className: BUTTON_PRIMARY, children: messages["common.save"] })
1723
+ /* @__PURE__ */ jsx13("button", { type: "submit", disabled: submitting, className: BUTTON_PRIMARY, children: messages["common.save"] })
1511
1724
  ] });
1512
1725
  }
1513
1726
 
1514
1727
  // src/components/ResourceList.tsx
1515
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1728
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1516
1729
  function ResourceList({ resources, onSelect }) {
1517
1730
  const { locale } = useSchedulingConfig();
1518
1731
  const messages = resolveSchedulingMessages(locale);
1519
1732
  if (resources.length === 0) {
1520
- return /* @__PURE__ */ jsx13("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.empty"] });
1733
+ return /* @__PURE__ */ jsx14("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.empty"] });
1521
1734
  }
1522
- return /* @__PURE__ */ jsx13("ul", { className: "divide-y divide-gray-200 dark:divide-gray-700 rounded-lg border border-gray-200 dark:border-gray-700", children: resources.map((resource, index) => /* @__PURE__ */ jsx13("li", { className: index % 2 === 1 ? "bg-gray-50 dark:bg-gray-800/50" : void 0, children: /* @__PURE__ */ jsxs12(
1735
+ return /* @__PURE__ */ jsx14("ul", { className: "divide-y divide-gray-200 dark:divide-gray-700 rounded-lg border border-gray-200 dark:border-gray-700", children: resources.map((resource, index) => /* @__PURE__ */ jsx14("li", { className: index % 2 === 1 ? "bg-gray-50 dark:bg-gray-800/50" : void 0, children: /* @__PURE__ */ jsxs13(
1523
1736
  "button",
1524
1737
  {
1525
1738
  type: "button",
1526
1739
  onClick: () => onSelect(resource),
1527
1740
  className: "flex w-full items-center gap-3 px-4 py-3 min-h-11 text-left text-sm hover:bg-gray-100 dark:hover:bg-gray-800",
1528
1741
  children: [
1529
- /* @__PURE__ */ jsx13("span", { className: "flex-1 font-medium text-gray-900 dark:text-gray-100", children: resource.name }),
1530
- /* @__PURE__ */ jsx13("span", { className: "text-gray-500 dark:text-gray-400", children: messages[`resource.kind.${resource.kind}`] }),
1531
- /* @__PURE__ */ jsx13("span", { className: "text-gray-500 dark:text-gray-400", children: resource.timezone }),
1532
- !resource.active && /* @__PURE__ */ jsx13("span", { className: "rounded-full bg-gray-200 px-2 py-0.5 text-xs text-gray-700 dark:bg-gray-700 dark:text-gray-300", children: messages["resource.inactive"] })
1742
+ /* @__PURE__ */ jsx14("span", { className: "flex-1 font-medium text-gray-900 dark:text-gray-100", children: resource.name }),
1743
+ /* @__PURE__ */ jsx14("span", { className: "text-gray-500 dark:text-gray-400", children: messages[`resource.kind.${resource.kind}`] }),
1744
+ /* @__PURE__ */ jsx14("span", { className: "text-gray-500 dark:text-gray-400", children: resource.timezone }),
1745
+ !resource.active && /* @__PURE__ */ jsx14("span", { className: "rounded-full bg-gray-200 px-2 py-0.5 text-xs text-gray-700 dark:bg-gray-700 dark:text-gray-300", children: messages["resource.inactive"] })
1533
1746
  ]
1534
1747
  }
1535
1748
  ) }, resource.id)) });
1536
1749
  }
1537
1750
 
1538
1751
  // src/workspace/ResourcesArea.tsx
1539
- import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1752
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
1540
1753
  var BUTTON_CLASS2 = "inline-flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors min-h-11";
1541
1754
  var BUTTON_PRIMARY2 = `${BUTTON_CLASS2} bg-brand-600 text-white hover:bg-brand-700`;
1542
1755
  var BUTTON_DANGER = `${BUTTON_CLASS2} text-red-700 hover:bg-red-50`;
1543
1756
  function ResourcesArea() {
1544
1757
  const { locale } = useSchedulingConfig();
1545
1758
  const messages = resolveSchedulingMessages(locale);
1546
- const { data, isLoading, isError } = useResources();
1759
+ const { data, isLoading, isError } = useResources({ pageSize: MAX_PAGE_SIZE4 });
1547
1760
  const createResource = useCreateResource();
1548
1761
  const updateResource = useUpdateResource();
1549
1762
  const deleteResource = useDeleteResource();
@@ -1561,21 +1774,21 @@ function ResourcesArea() {
1561
1774
  } catch {
1562
1775
  }
1563
1776
  }
1564
- return /* @__PURE__ */ jsxs13("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
1565
- /* @__PURE__ */ jsx14("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxs13("button", { type: "button", onClick: () => setDraft(null), className: `${BUTTON_PRIMARY2} ml-auto`, children: [
1566
- /* @__PURE__ */ jsx14(Plus3, { "aria-hidden": "true", className: "w-4 h-4" }),
1777
+ return /* @__PURE__ */ jsxs14("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
1778
+ /* @__PURE__ */ jsx15("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxs14("button", { type: "button", onClick: () => setDraft(null), className: `${BUTTON_PRIMARY2} ml-auto`, children: [
1779
+ /* @__PURE__ */ jsx15(Plus3, { "aria-hidden": "true", className: "w-4 h-4" }),
1567
1780
  messages["resource.newResource"]
1568
1781
  ] }) }),
1569
- isError && /* @__PURE__ */ jsx14("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.loadFailure"] }),
1570
- (createResource.isError || updateResource.isError || deleteResource.isError) && /* @__PURE__ */ jsx14("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.actionFailure"] }),
1571
- isLoading ? /* @__PURE__ */ jsx14("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }) : /* @__PURE__ */ jsx14(ResourceList, { resources: data?.data ?? [], onSelect: setDraft }),
1572
- isDraftOpen && /* @__PURE__ */ jsx14(
1782
+ isError && /* @__PURE__ */ jsx15("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.loadFailure"] }),
1783
+ (createResource.isError || updateResource.isError || deleteResource.isError) && /* @__PURE__ */ jsx15("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.actionFailure"] }),
1784
+ isLoading ? /* @__PURE__ */ jsx15("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }) : /* @__PURE__ */ jsx15(ResourceList, { resources: data?.data ?? [], onSelect: setDraft }),
1785
+ isDraftOpen && /* @__PURE__ */ jsx15(
1573
1786
  SidePanel,
1574
1787
  {
1575
1788
  title: isEditing ? messages["resource.editTitle"] : messages["resource.createTitle"],
1576
1789
  closeLabel: messages["common.close"],
1577
1790
  onClose: () => setDraft(void 0),
1578
- headerActions: isEditing ? /* @__PURE__ */ jsxs13(
1791
+ headerActions: isEditing ? /* @__PURE__ */ jsxs14(
1579
1792
  "button",
1580
1793
  {
1581
1794
  type: "button",
@@ -1585,12 +1798,12 @@ function ResourcesArea() {
1585
1798
  },
1586
1799
  className: BUTTON_DANGER,
1587
1800
  children: [
1588
- /* @__PURE__ */ jsx14(Trash23, { "aria-hidden": "true", className: "w-4 h-4" }),
1801
+ /* @__PURE__ */ jsx15(Trash23, { "aria-hidden": "true", className: "w-4 h-4" }),
1589
1802
  messages["common.remove"]
1590
1803
  ]
1591
1804
  }
1592
1805
  ) : void 0,
1593
- children: /* @__PURE__ */ jsx14(
1806
+ children: /* @__PURE__ */ jsx15(
1594
1807
  ResourceForm,
1595
1808
  {
1596
1809
  ...draft ? { initialValues: draft } : {},
@@ -1606,10 +1819,11 @@ function ResourcesArea() {
1606
1819
  // src/workspace/ServicesArea.tsx
1607
1820
  import { Plus as Plus4, Trash2 as Trash24 } from "lucide-react";
1608
1821
  import { useState as useState12 } from "react";
1822
+ import { MAX_PAGE_SIZE as MAX_PAGE_SIZE5 } from "@adatechnology/scheduling-contracts";
1609
1823
 
1610
1824
  // src/components/ServiceForm.tsx
1611
1825
  import { useState as useState11 } from "react";
1612
- import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
1826
+ import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
1613
1827
  var INPUT_CLASS3 = "w-full min-h-11 px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500 bg-white dark:bg-gray-900";
1614
1828
  var LABEL_CLASS2 = "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1";
1615
1829
  var BUTTON_PRIMARY3 = "inline-flex items-center justify-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors min-h-11 bg-brand-600 text-white hover:bg-brand-700 disabled:opacity-50";
@@ -1631,10 +1845,10 @@ function ServiceForm({ initialValues, onSubmit }) {
1631
1845
  setSubmitting(false);
1632
1846
  }
1633
1847
  }
1634
- return /* @__PURE__ */ jsxs14("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1635
- /* @__PURE__ */ jsxs14("div", { children: [
1636
- /* @__PURE__ */ jsx15("label", { htmlFor: "scheduling-service-name", className: LABEL_CLASS2, children: messages["service.name"] }),
1637
- /* @__PURE__ */ jsx15(
1848
+ return /* @__PURE__ */ jsxs15("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1849
+ /* @__PURE__ */ jsxs15("div", { children: [
1850
+ /* @__PURE__ */ jsx16("label", { htmlFor: "scheduling-service-name", className: LABEL_CLASS2, children: messages["service.name"] }),
1851
+ /* @__PURE__ */ jsx16(
1638
1852
  "input",
1639
1853
  {
1640
1854
  id: "scheduling-service-name",
@@ -1646,9 +1860,9 @@ function ServiceForm({ initialValues, onSubmit }) {
1646
1860
  }
1647
1861
  )
1648
1862
  ] }),
1649
- /* @__PURE__ */ jsxs14("div", { children: [
1650
- /* @__PURE__ */ jsx15("label", { htmlFor: "scheduling-service-duration", className: LABEL_CLASS2, children: messages["service.durationMinutes"] }),
1651
- /* @__PURE__ */ jsx15(
1863
+ /* @__PURE__ */ jsxs15("div", { children: [
1864
+ /* @__PURE__ */ jsx16("label", { htmlFor: "scheduling-service-duration", className: LABEL_CLASS2, children: messages["service.durationMinutes"] }),
1865
+ /* @__PURE__ */ jsx16(
1652
1866
  "input",
1653
1867
  {
1654
1868
  id: "scheduling-service-duration",
@@ -1661,10 +1875,10 @@ function ServiceForm({ initialValues, onSubmit }) {
1661
1875
  }
1662
1876
  )
1663
1877
  ] }),
1664
- /* @__PURE__ */ jsxs14("div", { className: "grid grid-cols-2 gap-3", children: [
1665
- /* @__PURE__ */ jsxs14("div", { children: [
1666
- /* @__PURE__ */ jsx15("label", { htmlFor: "scheduling-service-buffer-before", className: LABEL_CLASS2, children: messages["service.bufferBeforeMinutes"] }),
1667
- /* @__PURE__ */ jsx15(
1878
+ /* @__PURE__ */ jsxs15("div", { className: "grid grid-cols-2 gap-3", children: [
1879
+ /* @__PURE__ */ jsxs15("div", { children: [
1880
+ /* @__PURE__ */ jsx16("label", { htmlFor: "scheduling-service-buffer-before", className: LABEL_CLASS2, children: messages["service.bufferBeforeMinutes"] }),
1881
+ /* @__PURE__ */ jsx16(
1668
1882
  "input",
1669
1883
  {
1670
1884
  id: "scheduling-service-buffer-before",
@@ -1676,9 +1890,9 @@ function ServiceForm({ initialValues, onSubmit }) {
1676
1890
  }
1677
1891
  )
1678
1892
  ] }),
1679
- /* @__PURE__ */ jsxs14("div", { children: [
1680
- /* @__PURE__ */ jsx15("label", { htmlFor: "scheduling-service-buffer-after", className: LABEL_CLASS2, children: messages["service.bufferAfterMinutes"] }),
1681
- /* @__PURE__ */ jsx15(
1893
+ /* @__PURE__ */ jsxs15("div", { children: [
1894
+ /* @__PURE__ */ jsx16("label", { htmlFor: "scheduling-service-buffer-after", className: LABEL_CLASS2, children: messages["service.bufferAfterMinutes"] }),
1895
+ /* @__PURE__ */ jsx16(
1682
1896
  "input",
1683
1897
  {
1684
1898
  id: "scheduling-service-buffer-after",
@@ -1691,49 +1905,49 @@ function ServiceForm({ initialValues, onSubmit }) {
1691
1905
  )
1692
1906
  ] })
1693
1907
  ] }),
1694
- initialValues && /* @__PURE__ */ jsxs14("label", { className: "flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300 min-h-11", children: [
1695
- /* @__PURE__ */ jsx15("input", { type: "checkbox", checked: active, onChange: (event) => setActive(event.target.checked) }),
1908
+ initialValues && /* @__PURE__ */ jsxs15("label", { className: "flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300 min-h-11", children: [
1909
+ /* @__PURE__ */ jsx16("input", { type: "checkbox", checked: active, onChange: (event) => setActive(event.target.checked) }),
1696
1910
  messages["service.active"]
1697
1911
  ] }),
1698
- /* @__PURE__ */ jsx15("button", { type: "submit", disabled: submitting, className: BUTTON_PRIMARY3, children: messages["common.save"] })
1912
+ /* @__PURE__ */ jsx16("button", { type: "submit", disabled: submitting, className: BUTTON_PRIMARY3, children: messages["common.save"] })
1699
1913
  ] });
1700
1914
  }
1701
1915
 
1702
1916
  // src/components/ServiceList.tsx
1703
- import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
1917
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
1704
1918
  function ServiceList({ services, onSelect }) {
1705
1919
  const { locale } = useSchedulingConfig();
1706
1920
  const messages = resolveSchedulingMessages(locale);
1707
1921
  if (services.length === 0) {
1708
- return /* @__PURE__ */ jsx16("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.empty"] });
1922
+ return /* @__PURE__ */ jsx17("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.empty"] });
1709
1923
  }
1710
- return /* @__PURE__ */ jsx16("ul", { className: "divide-y divide-gray-200 dark:divide-gray-700 rounded-lg border border-gray-200 dark:border-gray-700", children: services.map((service, index) => /* @__PURE__ */ jsx16("li", { className: index % 2 === 1 ? "bg-gray-50 dark:bg-gray-800/50" : void 0, children: /* @__PURE__ */ jsxs15(
1924
+ return /* @__PURE__ */ jsx17("ul", { className: "divide-y divide-gray-200 dark:divide-gray-700 rounded-lg border border-gray-200 dark:border-gray-700", children: services.map((service, index) => /* @__PURE__ */ jsx17("li", { className: index % 2 === 1 ? "bg-gray-50 dark:bg-gray-800/50" : void 0, children: /* @__PURE__ */ jsxs16(
1711
1925
  "button",
1712
1926
  {
1713
1927
  type: "button",
1714
1928
  onClick: () => onSelect(service),
1715
1929
  className: "flex w-full items-center gap-3 px-4 py-3 min-h-11 text-left text-sm hover:bg-gray-100 dark:hover:bg-gray-800",
1716
1930
  children: [
1717
- /* @__PURE__ */ jsx16("span", { className: "flex-1 font-medium text-gray-900 dark:text-gray-100", children: service.name }),
1718
- /* @__PURE__ */ jsxs15("span", { className: "text-gray-500 dark:text-gray-400", children: [
1931
+ /* @__PURE__ */ jsx17("span", { className: "flex-1 font-medium text-gray-900 dark:text-gray-100", children: service.name }),
1932
+ /* @__PURE__ */ jsxs16("span", { className: "text-gray-500 dark:text-gray-400", children: [
1719
1933
  service.durationMinutes,
1720
1934
  " min"
1721
1935
  ] }),
1722
- !service.active && /* @__PURE__ */ jsx16("span", { className: "rounded-full bg-gray-200 px-2 py-0.5 text-xs text-gray-700 dark:bg-gray-700 dark:text-gray-300", children: messages["service.inactive"] })
1936
+ !service.active && /* @__PURE__ */ jsx17("span", { className: "rounded-full bg-gray-200 px-2 py-0.5 text-xs text-gray-700 dark:bg-gray-700 dark:text-gray-300", children: messages["service.inactive"] })
1723
1937
  ]
1724
1938
  }
1725
1939
  ) }, service.id)) });
1726
1940
  }
1727
1941
 
1728
1942
  // src/workspace/ServicesArea.tsx
1729
- import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
1943
+ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
1730
1944
  var BUTTON_CLASS3 = "inline-flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors min-h-11";
1731
1945
  var BUTTON_PRIMARY4 = `${BUTTON_CLASS3} bg-brand-600 text-white hover:bg-brand-700`;
1732
1946
  var BUTTON_DANGER2 = `${BUTTON_CLASS3} text-red-700 hover:bg-red-50`;
1733
1947
  function ServicesArea() {
1734
1948
  const { locale } = useSchedulingConfig();
1735
1949
  const messages = resolveSchedulingMessages(locale);
1736
- const { data, isLoading, isError } = useServices();
1950
+ const { data, isLoading, isError } = useServices({ pageSize: MAX_PAGE_SIZE5 });
1737
1951
  const createService = useCreateService();
1738
1952
  const updateService = useUpdateService();
1739
1953
  const deleteService = useDeleteService();
@@ -1751,21 +1965,21 @@ function ServicesArea() {
1751
1965
  } catch {
1752
1966
  }
1753
1967
  }
1754
- return /* @__PURE__ */ jsxs16("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
1755
- /* @__PURE__ */ jsx17("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxs16("button", { type: "button", onClick: () => setDraft(null), className: `${BUTTON_PRIMARY4} ml-auto`, children: [
1756
- /* @__PURE__ */ jsx17(Plus4, { "aria-hidden": "true", className: "w-4 h-4" }),
1968
+ return /* @__PURE__ */ jsxs17("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
1969
+ /* @__PURE__ */ jsx18("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxs17("button", { type: "button", onClick: () => setDraft(null), className: `${BUTTON_PRIMARY4} ml-auto`, children: [
1970
+ /* @__PURE__ */ jsx18(Plus4, { "aria-hidden": "true", className: "w-4 h-4" }),
1757
1971
  messages["service.newService"]
1758
1972
  ] }) }),
1759
- isError && /* @__PURE__ */ jsx17("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.loadFailure"] }),
1760
- (createService.isError || updateService.isError || deleteService.isError) && /* @__PURE__ */ jsx17("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.actionFailure"] }),
1761
- isLoading ? /* @__PURE__ */ jsx17("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }) : /* @__PURE__ */ jsx17(ServiceList, { services: data?.data ?? [], onSelect: setDraft }),
1762
- isDraftOpen && /* @__PURE__ */ jsx17(
1973
+ isError && /* @__PURE__ */ jsx18("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.loadFailure"] }),
1974
+ (createService.isError || updateService.isError || deleteService.isError) && /* @__PURE__ */ jsx18("p", { role: "alert", className: "text-sm text-red-700 bg-red-50 rounded-lg px-3 py-2", children: messages["common.actionFailure"] }),
1975
+ isLoading ? /* @__PURE__ */ jsx18("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }) : /* @__PURE__ */ jsx18(ServiceList, { services: data?.data ?? [], onSelect: setDraft }),
1976
+ isDraftOpen && /* @__PURE__ */ jsx18(
1763
1977
  SidePanel,
1764
1978
  {
1765
1979
  title: isEditing ? messages["service.editTitle"] : messages["service.createTitle"],
1766
1980
  closeLabel: messages["common.close"],
1767
1981
  onClose: () => setDraft(void 0),
1768
- headerActions: isEditing ? /* @__PURE__ */ jsxs16(
1982
+ headerActions: isEditing ? /* @__PURE__ */ jsxs17(
1769
1983
  "button",
1770
1984
  {
1771
1985
  type: "button",
@@ -1775,12 +1989,12 @@ function ServicesArea() {
1775
1989
  },
1776
1990
  className: BUTTON_DANGER2,
1777
1991
  children: [
1778
- /* @__PURE__ */ jsx17(Trash24, { "aria-hidden": "true", className: "w-4 h-4" }),
1992
+ /* @__PURE__ */ jsx18(Trash24, { "aria-hidden": "true", className: "w-4 h-4" }),
1779
1993
  messages["common.remove"]
1780
1994
  ]
1781
1995
  }
1782
1996
  ) : void 0,
1783
- children: /* @__PURE__ */ jsx17(
1997
+ children: /* @__PURE__ */ jsx18(
1784
1998
  ServiceForm,
1785
1999
  {
1786
2000
  ...draft ? { initialValues: draft } : {},
@@ -1810,7 +2024,7 @@ function isSchedulingWorkspaceArea(value) {
1810
2024
  }
1811
2025
 
1812
2026
  // src/workspace/WorkspaceAreaNav.tsx
1813
- import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
2027
+ import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
1814
2028
  var ITEM_BASE = "flex items-center gap-2 px-3 py-2 -mb-px border-b-2 text-sm font-medium transition-colors min-h-11";
1815
2029
  var ITEM_ACTIVE = "border-brand-600 text-brand-700 dark:text-brand-400";
1816
2030
  var ITEM_IDLE = "border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100";
@@ -1829,9 +2043,9 @@ function WorkspaceAreaNav({ area, labels, onSelect }) {
1829
2043
  [SCHEDULING_WORKSPACE_AREA.SERVICES, labels.servicesTab],
1830
2044
  [SCHEDULING_WORKSPACE_AREA.AVAILABILITY, labels.availabilityTab]
1831
2045
  ];
1832
- return /* @__PURE__ */ jsx18("nav", { "aria-label": labels.areaNav, className: "flex gap-1 px-4 border-b border-gray-200 dark:border-gray-700 overflow-x-auto", children: items.map(([value, label]) => {
2046
+ return /* @__PURE__ */ jsx19("nav", { "aria-label": labels.areaNav, className: "flex gap-1 px-4 border-b border-gray-200 dark:border-gray-700 overflow-x-auto", children: items.map(([value, label]) => {
1833
2047
  const Icon = AREA_ICON[value];
1834
- return /* @__PURE__ */ jsxs17(
2048
+ return /* @__PURE__ */ jsxs18(
1835
2049
  "button",
1836
2050
  {
1837
2051
  type: "button",
@@ -1839,7 +2053,7 @@ function WorkspaceAreaNav({ area, labels, onSelect }) {
1839
2053
  "aria-current": value === area ? "page" : void 0,
1840
2054
  className: `${ITEM_BASE} ${value === area ? ITEM_ACTIVE : ITEM_IDLE} whitespace-nowrap`,
1841
2055
  children: [
1842
- /* @__PURE__ */ jsx18(Icon, { "aria-hidden": "true", className: "w-4 h-4 shrink-0" }),
2056
+ /* @__PURE__ */ jsx19(Icon, { "aria-hidden": "true", className: "w-4 h-4 shrink-0" }),
1843
2057
  label
1844
2058
  ]
1845
2059
  },
@@ -1849,7 +2063,7 @@ function WorkspaceAreaNav({ area, labels, onSelect }) {
1849
2063
  }
1850
2064
 
1851
2065
  // src/workspace/SchedulingWorkspace.tsx
1852
- import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
2066
+ import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
1853
2067
  var AREA_COMPONENT = {
1854
2068
  [SCHEDULING_WORKSPACE_AREA.AGENDA]: AgendaArea,
1855
2069
  [SCHEDULING_WORKSPACE_AREA.BOOKINGS]: BookingsArea,
@@ -1871,13 +2085,13 @@ function SchedulingWorkspace({
1871
2085
  setInternalArea(next);
1872
2086
  onAreaChange?.(next);
1873
2087
  }
1874
- return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col h-full", children: [
1875
- /* @__PURE__ */ jsxs18("header", { className: "flex flex-wrap items-center gap-3 px-4 py-3", children: [
1876
- /* @__PURE__ */ jsx19("h1", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100 mr-auto", children: labels.title }),
2088
+ return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col h-full", children: [
2089
+ /* @__PURE__ */ jsxs19("header", { className: "flex flex-wrap items-center gap-3 px-4 py-3", children: [
2090
+ /* @__PURE__ */ jsx20("h1", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100 mr-auto", children: labels.title }),
1877
2091
  renderHeaderActions?.()
1878
2092
  ] }),
1879
- /* @__PURE__ */ jsx19(WorkspaceAreaNav, { area, labels, onSelect: handleSelectArea }),
1880
- /* @__PURE__ */ jsx19("div", { className: "relative flex flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx19(AreaComponent, {}) })
2093
+ /* @__PURE__ */ jsx20(WorkspaceAreaNav, { area, labels, onSelect: handleSelectArea }),
2094
+ /* @__PURE__ */ jsx20("div", { className: "relative flex flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx20(AreaComponent, {}) })
1881
2095
  ] });
1882
2096
  }
1883
2097
  export {