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

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,174 @@ 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 [from, setFrom] = useState3(() => formatDateTimeLocalInTimeZone(/* @__PURE__ */ new Date(), timezone));
1012
+ const [until, setUntil] = useState3(() => formatDateTimeLocalInTimeZone(/* @__PURE__ */ new Date(), timezone));
838
1013
  const [kind, setKind] = useState3(AVAILABILITY_EXCEPTION_KIND.BLOCK);
839
1014
  const [reason, setReason] = useState3("");
840
1015
  async function handleAdd() {
@@ -842,7 +1017,10 @@ function AvailabilityExceptionsEditor({ resourceId }) {
842
1017
  try {
843
1018
  await addException.mutateAsync({
844
1019
  resourceId,
845
- during: { start: new Date(from), end: new Date(until) },
1020
+ during: {
1021
+ start: parseDateTimeLocalInTimeZone(from, timezone),
1022
+ end: parseDateTimeLocalInTimeZone(until, timezone)
1023
+ },
846
1024
  kind,
847
1025
  ...reason ? { reason } : {}
848
1026
  });
@@ -852,13 +1030,13 @@ function AvailabilityExceptionsEditor({ resourceId }) {
852
1030
  } catch {
853
1031
  }
854
1032
  }
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: [
1033
+ return /* @__PURE__ */ jsxs5("section", { className: "space-y-3", children: [
1034
+ /* @__PURE__ */ jsx6("h3", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: messages["availability.exceptionsTitle"] }),
1035
+ (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"] }),
1036
+ 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"] }),
1037
+ isLoading && /* @__PURE__ */ jsx6("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }),
1038
+ /* @__PURE__ */ jsx6("ul", { className: "space-y-2", children: (data ?? []).map((exception) => /* @__PURE__ */ jsxs5("li", { className: "flex items-center gap-2 text-sm", children: [
1039
+ /* @__PURE__ */ jsxs5("span", { className: "flex-1", children: [
862
1040
  messages[`availability.exceptionKind.${exception.kind === "block" ? "blocked" : "extra"}`],
863
1041
  " \u2014",
864
1042
  " ",
@@ -867,39 +1045,35 @@ function AvailabilityExceptionsEditor({ resourceId }) {
867
1045
  exception.during.end.toLocaleString(locale),
868
1046
  exception.reason ? ` (${exception.reason})` : ""
869
1047
  ] }),
870
- /* @__PURE__ */ jsx5(
1048
+ /* @__PURE__ */ jsx6(
871
1049
  "button",
872
1050
  {
873
1051
  type: "button",
874
1052
  onClick: () => removeException.mutate({ id: exception.id, resourceId }),
875
1053
  "aria-label": messages["availability.removeException"],
876
1054
  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" })
1055
+ children: /* @__PURE__ */ jsx6(Trash22, { "aria-hidden": "true", className: "w-4 h-4" })
878
1056
  }
879
1057
  )
880
1058
  ] }, exception.id)) }),
881
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center gap-2", children: [
882
- /* @__PURE__ */ jsx5(
883
- "input",
1059
+ /* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center gap-2", children: [
1060
+ /* @__PURE__ */ jsx6(
1061
+ DateTimeField,
884
1062
  {
885
- "aria-label": messages["availability.exceptionFrom"],
886
- type: "datetime-local",
1063
+ label: messages["availability.exceptionFrom"],
887
1064
  value: from,
888
- onChange: (event) => setFrom(event.target.value),
889
- className: SELECT_CLASS
1065
+ onChange: setFrom
890
1066
  }
891
1067
  ),
892
- /* @__PURE__ */ jsx5(
893
- "input",
1068
+ /* @__PURE__ */ jsx6(
1069
+ DateTimeField,
894
1070
  {
895
- "aria-label": messages["availability.exceptionUntil"],
896
- type: "datetime-local",
1071
+ label: messages["availability.exceptionUntil"],
897
1072
  value: until,
898
- onChange: (event) => setUntil(event.target.value),
899
- className: SELECT_CLASS
1073
+ onChange: setUntil
900
1074
  }
901
1075
  ),
902
- /* @__PURE__ */ jsxs4(
1076
+ /* @__PURE__ */ jsxs5(
903
1077
  "select",
904
1078
  {
905
1079
  "aria-label": messages["availability.exceptionKind.blocked"],
@@ -907,12 +1081,12 @@ function AvailabilityExceptionsEditor({ resourceId }) {
907
1081
  onChange: (event) => setKind(event.target.value),
908
1082
  className: SELECT_CLASS,
909
1083
  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"] })
1084
+ /* @__PURE__ */ jsx6("option", { value: AVAILABILITY_EXCEPTION_KIND.BLOCK, children: messages["availability.exceptionKind.blocked"] }),
1085
+ /* @__PURE__ */ jsx6("option", { value: AVAILABILITY_EXCEPTION_KIND.EXTRA, children: messages["availability.exceptionKind.extra"] })
912
1086
  ]
913
1087
  }
914
1088
  ),
915
- /* @__PURE__ */ jsx5(
1089
+ /* @__PURE__ */ jsx6(
916
1090
  "input",
917
1091
  {
918
1092
  "aria-label": messages["availability.exceptionReason"],
@@ -923,7 +1097,7 @@ function AvailabilityExceptionsEditor({ resourceId }) {
923
1097
  className: SELECT_CLASS
924
1098
  }
925
1099
  ),
926
- /* @__PURE__ */ jsxs4(
1100
+ /* @__PURE__ */ jsxs5(
927
1101
  "button",
928
1102
  {
929
1103
  type: "button",
@@ -931,7 +1105,7 @@ function AvailabilityExceptionsEditor({ resourceId }) {
931
1105
  disabled: addException.isPending,
932
1106
  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
1107
  children: [
934
- /* @__PURE__ */ jsx5(Plus2, { "aria-hidden": "true", className: "w-4 h-4" }),
1108
+ /* @__PURE__ */ jsx6(Plus2, { "aria-hidden": "true", className: "w-4 h-4" }),
935
1109
  messages["availability.addException"]
936
1110
  ]
937
1111
  }
@@ -941,25 +1115,25 @@ function AvailabilityExceptionsEditor({ resourceId }) {
941
1115
  }
942
1116
 
943
1117
  // src/components/AvailabilityEditor.tsx
944
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1118
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
945
1119
  function AvailabilityEditor({ resourceId, timezone }) {
946
1120
  const { locale } = useSchedulingConfig();
947
1121
  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: [
1122
+ return /* @__PURE__ */ jsxs6("div", { className: "space-y-6", children: [
1123
+ /* @__PURE__ */ jsxs6("p", { className: "inline-flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400", children: [
1124
+ /* @__PURE__ */ jsxs6("span", { className: "font-medium", children: [
951
1125
  messages["availability.resourceTimezone"],
952
1126
  ":"
953
1127
  ] }),
954
1128
  timezone
955
1129
  ] }),
956
- /* @__PURE__ */ jsx6(WeeklyRulesEditor, { resourceId }),
957
- /* @__PURE__ */ jsx6(AvailabilityExceptionsEditor, { resourceId })
1130
+ /* @__PURE__ */ jsx7(WeeklyRulesEditor, { resourceId }),
1131
+ /* @__PURE__ */ jsx7(AvailabilityExceptionsEditor, { resourceId, timezone })
958
1132
  ] });
959
1133
  }
960
1134
 
961
1135
  // src/workspace/AvailabilityArea.tsx
962
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1136
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
963
1137
  function AvailabilityArea() {
964
1138
  const { locale } = useSchedulingConfig();
965
1139
  const messages = resolveSchedulingMessages(locale);
@@ -967,25 +1141,25 @@ function AvailabilityArea() {
967
1141
  const [resourceId, setResourceId] = useState4("");
968
1142
  const resources = data?.data ?? [];
969
1143
  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(
1144
+ return /* @__PURE__ */ jsxs7("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
1145
+ /* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-2 text-sm", children: [
1146
+ /* @__PURE__ */ jsx8("span", { className: "font-medium text-gray-700 dark:text-gray-300", children: messages["agenda.resourceLabel"] }),
1147
+ /* @__PURE__ */ jsxs7(
974
1148
  "select",
975
1149
  {
976
1150
  value: resourceId,
977
1151
  onChange: (event) => setResourceId(event.target.value),
978
1152
  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
1153
  children: [
980
- /* @__PURE__ */ jsx7("option", { value: "", children: "\u2014" }),
981
- resources.map((resource) => /* @__PURE__ */ jsx7("option", { value: resource.id, children: resource.name }, resource.id))
1154
+ /* @__PURE__ */ jsx8("option", { value: "", children: "\u2014" }),
1155
+ resources.map((resource) => /* @__PURE__ */ jsx8("option", { value: resource.id, children: resource.name }, resource.id))
982
1156
  ]
983
1157
  }
984
1158
  )
985
1159
  ] }),
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(
1160
+ 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"] }),
1161
+ isLoading && /* @__PURE__ */ jsx8("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }),
1162
+ selectedResource && /* @__PURE__ */ jsx8(
989
1163
  AvailabilityEditor,
990
1164
  {
991
1165
  resourceId: selectedResource.id,
@@ -998,6 +1172,7 @@ function AvailabilityArea() {
998
1172
 
999
1173
  // src/workspace/BookingsArea.tsx
1000
1174
  import { useState as useState8 } from "react";
1175
+ import { MAX_PAGE_SIZE as MAX_PAGE_SIZE3 } from "@adatechnology/scheduling-contracts";
1001
1176
 
1002
1177
  // src/components/BookingDrawer.tsx
1003
1178
  import { XCircle } from "lucide-react";
@@ -1007,7 +1182,7 @@ import { BOOKING_STATUS } from "@adatechnology/scheduling-contracts";
1007
1182
  // src/components/SidePanel.tsx
1008
1183
  import { X } from "lucide-react";
1009
1184
  import { useEffect } from "react";
1010
- import { Fragment, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1185
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1011
1186
  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
1187
  function SidePanel({ title, closeLabel, onClose, headerActions, children }) {
1013
1188
  useEffect(() => {
@@ -1017,8 +1192,8 @@ function SidePanel({ title, closeLabel, onClose, headerActions, children }) {
1017
1192
  window.addEventListener("keydown", handleKeyDown);
1018
1193
  return () => window.removeEventListener("keydown", handleKeyDown);
1019
1194
  }, [onClose]);
1020
- return /* @__PURE__ */ jsxs7(Fragment, { children: [
1021
- /* @__PURE__ */ jsx8(
1195
+ return /* @__PURE__ */ jsxs8(Fragment2, { children: [
1196
+ /* @__PURE__ */ jsx9(
1022
1197
  "button",
1023
1198
  {
1024
1199
  type: "button",
@@ -1028,29 +1203,29 @@ function SidePanel({ title, closeLabel, onClose, headerActions, children }) {
1028
1203
  className: "absolute inset-0 z-10 bg-gray-900/20 wide:hidden"
1029
1204
  }
1030
1205
  ),
1031
- /* @__PURE__ */ jsxs7(
1206
+ /* @__PURE__ */ jsxs8(
1032
1207
  "section",
1033
1208
  {
1034
1209
  "aria-label": title,
1035
1210
  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
1211
  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 }),
1212
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 border-b border-gray-200 px-4 py-3 dark:border-gray-700", children: [
1213
+ /* @__PURE__ */ jsx9("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 mr-auto", children: title }),
1039
1214
  headerActions,
1040
- /* @__PURE__ */ jsxs7(
1215
+ /* @__PURE__ */ jsxs8(
1041
1216
  "button",
1042
1217
  {
1043
1218
  type: "button",
1044
1219
  onClick: onClose,
1045
1220
  className: `${BUTTON_CLASS} text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800`,
1046
1221
  children: [
1047
- /* @__PURE__ */ jsx8(X, { "aria-hidden": "true", className: "w-4 h-4" }),
1222
+ /* @__PURE__ */ jsx9(X, { "aria-hidden": "true", className: "w-4 h-4" }),
1048
1223
  closeLabel
1049
1224
  ]
1050
1225
  }
1051
1226
  )
1052
1227
  ] }),
1053
- /* @__PURE__ */ jsx8("div", { className: "min-h-0 flex-1 overflow-y-auto p-4", children })
1228
+ /* @__PURE__ */ jsx9("div", { className: "min-h-0 flex-1 overflow-y-auto p-4", children })
1054
1229
  ]
1055
1230
  }
1056
1231
  )
@@ -1058,16 +1233,13 @@ function SidePanel({ title, closeLabel, onClose, headerActions, children }) {
1058
1233
  }
1059
1234
 
1060
1235
  // src/components/BookingDrawer.tsx
1061
- import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1236
+ import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1237
+ var BROWSER_TIME_ZONE = Intl.DateTimeFormat().resolvedOptions().timeZone;
1062
1238
  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
1239
  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
1240
  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
1241
  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 }) {
1242
+ function BookingDrawer({ booking, resourceTimezone, onClose }) {
1071
1243
  const { locale } = useSchedulingConfig();
1072
1244
  const messages = resolveSchedulingMessages(locale);
1073
1245
  const confirmBooking = useConfirmBooking();
@@ -1075,12 +1247,13 @@ function BookingDrawer({ booking, onClose }) {
1075
1247
  const markNoShow = useMarkNoShow();
1076
1248
  const cancelBooking = useCancelBooking();
1077
1249
  const rescheduleBooking = useRescheduleBooking();
1250
+ const timezone = resourceTimezone ?? BROWSER_TIME_ZONE;
1078
1251
  const [isCancelling, setIsCancelling] = useState5(false);
1079
1252
  const [cancelledBy, setCancelledBy] = useState5("");
1080
1253
  const [cancellationReason, setCancellationReason] = useState5("");
1081
1254
  const [isRescheduling, setIsRescheduling] = useState5(false);
1082
- const [start, setStart] = useState5(() => toLocalInputValue(booking.startsAt));
1083
- const [end, setEnd] = useState5(() => toLocalInputValue(booking.endsAt));
1255
+ const [start, setStart] = useState5(() => formatDateTimeLocalInTimeZone(booking.startsAt, timezone));
1256
+ const [end, setEnd] = useState5(() => formatDateTimeLocalInTimeZone(booking.endsAt, timezone));
1084
1257
  async function handleCancel() {
1085
1258
  if (!cancelledBy) return;
1086
1259
  try {
@@ -1094,42 +1267,57 @@ function BookingDrawer({ booking, onClose }) {
1094
1267
  }
1095
1268
  async function handleReschedule() {
1096
1269
  try {
1097
- await rescheduleBooking.mutateAsync({ id: booking.id, input: { during: { start: new Date(start), end: new Date(end) } } });
1270
+ await rescheduleBooking.mutateAsync({
1271
+ id: booking.id,
1272
+ input: {
1273
+ during: {
1274
+ start: parseDateTimeLocalInTimeZone(start, timezone),
1275
+ end: parseDateTimeLocalInTimeZone(end, timezone)
1276
+ }
1277
+ }
1278
+ });
1098
1279
  setIsRescheduling(false);
1099
1280
  } catch {
1100
1281
  }
1101
1282
  }
1102
1283
  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: [
1284
+ return /* @__PURE__ */ jsx10(SidePanel, { title: messages["booking.detailTitle"], closeLabel: messages["common.close"], onClose, children: /* @__PURE__ */ jsxs9("div", { className: "space-y-4", children: [
1285
+ /* @__PURE__ */ jsxs9("div", { children: [
1286
+ /* @__PURE__ */ jsx10("p", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: booking.title }),
1287
+ /* @__PURE__ */ jsx10("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages[`booking.status.${booking.status === "no_show" ? "noShow" : booking.status}`] }),
1288
+ /* @__PURE__ */ jsxs9("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
1108
1289
  booking.startsAt.toLocaleString(locale),
1109
1290
  " \u2192 ",
1110
1291
  booking.endsAt.toLocaleString(locale)
1111
1292
  ] })
1112
1293
  ] }),
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"] })
1294
+ (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"] }),
1295
+ !isTerminal && /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap gap-2", children: [
1296
+ booking.status === BOOKING_STATUS.REQUESTED && /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => confirmBooking.mutate(booking.id), className: PRIMARY_BUTTON_CLASS, children: messages["booking.confirm"] }),
1297
+ booking.status === BOOKING_STATUS.CONFIRMED && /* @__PURE__ */ jsxs9(Fragment3, { children: [
1298
+ /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => completeBooking.mutate(booking.id), className: ACTION_BUTTON_CLASS, children: messages["booking.complete"] }),
1299
+ /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => markNoShow.mutate(booking.id), className: ACTION_BUTTON_CLASS, children: messages["booking.markNoShow"] }),
1300
+ /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => setIsRescheduling(true), className: ACTION_BUTTON_CLASS, children: messages["booking.reschedule"] })
1120
1301
  ] }),
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" }),
1302
+ /* @__PURE__ */ jsxs9("button", { type: "button", onClick: () => setIsCancelling(true), className: DANGER_BUTTON_CLASS, children: [
1303
+ /* @__PURE__ */ jsx10(XCircle, { "aria-hidden": "true", className: "w-4 h-4" }),
1123
1304
  messages["booking.cancel"]
1124
1305
  ] })
1125
1306
  ] }),
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"] })
1307
+ isRescheduling && /* @__PURE__ */ jsxs9("div", { className: "space-y-2 rounded-lg border border-gray-200 dark:border-gray-700 p-3", children: [
1308
+ /* @__PURE__ */ jsx10(
1309
+ DateTimeField,
1310
+ {
1311
+ label: messages["booking.rescheduleStart"],
1312
+ value: start,
1313
+ onChange: setStart
1314
+ }
1315
+ ),
1316
+ /* @__PURE__ */ jsx10(DateTimeField, { label: messages["booking.rescheduleEnd"], value: end, onChange: setEnd }),
1317
+ /* @__PURE__ */ jsx10("button", { type: "button", onClick: handleReschedule, disabled: rescheduleBooking.isPending, className: PRIMARY_BUTTON_CLASS, children: messages["common.save"] })
1130
1318
  ] }),
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(
1319
+ isCancelling && /* @__PURE__ */ jsxs9("div", { className: "space-y-2 rounded-lg border border-gray-200 dark:border-gray-700 p-3", children: [
1320
+ /* @__PURE__ */ jsx10(
1133
1321
  "input",
1134
1322
  {
1135
1323
  type: "text",
@@ -1139,7 +1327,7 @@ function BookingDrawer({ booking, onClose }) {
1139
1327
  className: INPUT_CLASS
1140
1328
  }
1141
1329
  ),
1142
- /* @__PURE__ */ jsx9(
1330
+ /* @__PURE__ */ jsx10(
1143
1331
  "input",
1144
1332
  {
1145
1333
  type: "text",
@@ -1149,8 +1337,8 @@ function BookingDrawer({ booking, onClose }) {
1149
1337
  className: INPUT_CLASS
1150
1338
  }
1151
1339
  ),
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" }),
1340
+ /* @__PURE__ */ jsxs9("button", { type: "button", onClick: handleCancel, disabled: cancelBooking.isPending, className: DANGER_BUTTON_CLASS, children: [
1341
+ /* @__PURE__ */ jsx10(XCircle, { "aria-hidden": "true", className: "w-4 h-4" }),
1154
1342
  messages["booking.cancel"]
1155
1343
  ] })
1156
1344
  ] })
@@ -1160,18 +1348,23 @@ function BookingDrawer({ booking, onClose }) {
1160
1348
  // src/components/BookingsTable.tsx
1161
1349
  import { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, ArrowUpDown } from "lucide-react";
1162
1350
  import { useState as useState6 } from "react";
1163
- import { BOOKING_STATUS as BOOKING_STATUS2 } from "@adatechnology/scheduling-contracts";
1351
+ import { BOOKING_STATUS as BOOKING_STATUS3 } from "@adatechnology/scheduling-contracts";
1164
1352
 
1165
1353
  // src/components/bookingsTableState.util.ts
1354
+ import { BOOKING_STATUS as BOOKING_STATUS2 } from "@adatechnology/scheduling-contracts";
1166
1355
  var DEFAULT_BOOKINGS_TABLE_STATE = {
1167
1356
  sortDirection: "asc",
1168
1357
  statusFilters: [],
1169
1358
  page: 1
1170
1359
  };
1171
1360
  var SORT_COLUMNS = ["title", "status", "startsAt", "endsAt"];
1361
+ var BOOKING_STATUSES = Object.values(BOOKING_STATUS2);
1172
1362
  function isBookingSortColumn(value) {
1173
1363
  return SORT_COLUMNS.includes(value);
1174
1364
  }
1365
+ function isBookingStatus(value) {
1366
+ return BOOKING_STATUSES.includes(value);
1367
+ }
1175
1368
  function parsePage(value) {
1176
1369
  const parsed = Number(value);
1177
1370
  return Number.isInteger(parsed) && parsed > 0 ? parsed : 1;
@@ -1181,7 +1374,7 @@ function parseBookingsTableState(search) {
1181
1374
  const sortColumnParam = params.get("sortBy");
1182
1375
  const sortColumn = isBookingSortColumn(sortColumnParam) ? sortColumnParam : void 0;
1183
1376
  const sortDirection = params.get("sortDirection") === "desc" ? "desc" : "asc";
1184
- const statusFilters = params.getAll("status");
1377
+ const statusFilters = params.getAll("status").filter(isBookingStatus);
1185
1378
  const page = parsePage(params.get("page"));
1186
1379
  return { ...sortColumn ? { sortColumn } : {}, sortDirection, statusFilters, page };
1187
1380
  }
@@ -1204,13 +1397,14 @@ function filterBookingsByStatus(bookings, statusFilters) {
1204
1397
  }
1205
1398
 
1206
1399
  // src/components/BookingsTable.tsx
1207
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1208
- var ALL_STATUSES = Object.values(BOOKING_STATUS2);
1400
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1401
+ var ALL_STATUSES = Object.values(BOOKING_STATUS3);
1209
1402
  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
1403
  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";
1404
+ function nextSortState(column, currentColumn, currentDirection) {
1405
+ if (currentColumn !== column) return { sortColumn: column, sortDirection: "asc" };
1406
+ if (currentDirection === "asc") return { sortColumn: column, sortDirection: "desc" };
1407
+ return { sortColumn: void 0, sortDirection: "asc" };
1214
1408
  }
1215
1409
  function BookingsTable({
1216
1410
  bookings,
@@ -1228,8 +1422,7 @@ function BookingsTable({
1228
1422
  function toggleSort(column) {
1229
1423
  onStateChange?.({
1230
1424
  ...state,
1231
- sortColumn: column,
1232
- sortDirection: nextSortDirection(column, state.sortColumn, state.sortDirection)
1425
+ ...nextSortState(column, state.sortColumn, state.sortDirection)
1233
1426
  });
1234
1427
  }
1235
1428
  function toggleStatusFilter(status) {
@@ -1253,19 +1446,20 @@ function BookingsTable({
1253
1446
  setSelected(next);
1254
1447
  }
1255
1448
  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" });
1449
+ if (state.sortColumn !== column) return /* @__PURE__ */ jsx11(ArrowUpDown, { "aria-hidden": "true", className: "w-3 h-3" });
1450
+ 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
1451
  }
1259
1452
  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: [
1453
+ const ariaSort = state.sortColumn !== column ? "none" : state.sortDirection === "asc" ? "ascending" : "descending";
1454
+ 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
1455
  messages[labelKey],
1262
1456
  renderSortIcon(column)
1263
1457
  ] }) });
1264
1458
  }
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(
1459
+ return /* @__PURE__ */ jsxs10("div", { className: "space-y-3", children: [
1460
+ /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center gap-3", children: [
1461
+ ALL_STATUSES.map((status) => /* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-1.5 text-sm min-h-11", children: [
1462
+ /* @__PURE__ */ jsx11(
1269
1463
  "input",
1270
1464
  {
1271
1465
  type: "checkbox",
@@ -1275,7 +1469,7 @@ function BookingsTable({
1275
1469
  ),
1276
1470
  messages[`booking.status.${status === "no_show" ? "noShow" : status}`]
1277
1471
  ] }, status)),
1278
- !isBookingsTableStateDefault(state) && /* @__PURE__ */ jsx10(
1472
+ !isBookingsTableStateDefault(state) && /* @__PURE__ */ jsx11(
1279
1473
  "button",
1280
1474
  {
1281
1475
  type: "button",
@@ -1285,7 +1479,7 @@ function BookingsTable({
1285
1479
  }
1286
1480
  )
1287
1481
  ] }),
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(
1482
+ 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
1483
  "button",
1290
1484
  {
1291
1485
  type: "button",
@@ -1295,10 +1489,10 @@ function BookingsTable({
1295
1489
  },
1296
1490
  action.key
1297
1491
  )) }),
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(
1492
+ /* @__PURE__ */ jsxs10("div", { className: "overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-700", children: [
1493
+ /* @__PURE__ */ jsxs10("table", { className: "min-w-full text-sm", children: [
1494
+ /* @__PURE__ */ jsx11("thead", { className: "border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsxs10("tr", { children: [
1495
+ /* @__PURE__ */ jsx11("th", { scope: "col", className: CHECKBOX_CELL_CLASS, children: /* @__PURE__ */ jsx11(
1302
1496
  "input",
1303
1497
  {
1304
1498
  type: "checkbox",
@@ -1312,12 +1506,12 @@ function BookingsTable({
1312
1506
  renderHeader("startsAt", "booking.column.startsAt"),
1313
1507
  renderHeader("endsAt", "booking.column.endsAt")
1314
1508
  ] }) }),
1315
- /* @__PURE__ */ jsx10("tbody", { children: visibleBookings.map((booking, index) => /* @__PURE__ */ jsxs9(
1509
+ /* @__PURE__ */ jsx11("tbody", { children: visibleBookings.map((booking, index) => /* @__PURE__ */ jsxs10(
1316
1510
  "tr",
1317
1511
  {
1318
1512
  className: index % 2 === 1 ? "bg-gray-50 dark:bg-gray-800/50" : void 0,
1319
1513
  children: [
1320
- /* @__PURE__ */ jsx10("td", { className: CHECKBOX_CELL_CLASS, children: /* @__PURE__ */ jsx10(
1514
+ /* @__PURE__ */ jsx11("td", { className: CHECKBOX_CELL_CLASS, children: /* @__PURE__ */ jsx11(
1321
1515
  "input",
1322
1516
  {
1323
1517
  type: "checkbox",
@@ -1326,19 +1520,19 @@ function BookingsTable({
1326
1520
  onChange: () => toggleRowSelected(booking.id)
1327
1521
  }
1328
1522
  ) }),
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) })
1523
+ /* @__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 }) }),
1524
+ /* @__PURE__ */ jsx11("td", { className: "px-3 py-2", children: messages[`booking.status.${booking.status === "no_show" ? "noShow" : booking.status}`] }),
1525
+ /* @__PURE__ */ jsx11("td", { className: "px-3 py-2", children: booking.startsAt.toLocaleString(locale) }),
1526
+ /* @__PURE__ */ jsx11("td", { className: "px-3 py-2", children: booking.endsAt.toLocaleString(locale) })
1333
1527
  ]
1334
1528
  },
1335
1529
  booking.id
1336
1530
  )) })
1337
1531
  ] }),
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"] })
1532
+ 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
1533
  ] }),
1340
- pagination && pagination.totalPages > 1 && /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-end gap-3", children: [
1341
- /* @__PURE__ */ jsx10(
1534
+ pagination && pagination.totalPages > 1 && /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-end gap-3", children: [
1535
+ /* @__PURE__ */ jsx11(
1342
1536
  "button",
1343
1537
  {
1344
1538
  type: "button",
@@ -1346,15 +1540,15 @@ function BookingsTable({
1346
1540
  disabled: state.page <= 1,
1347
1541
  onClick: () => goToPage(state.page - 1),
1348
1542
  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" })
1543
+ children: /* @__PURE__ */ jsx11(ArrowLeft, { "aria-hidden": "true", className: "w-4 h-4" })
1350
1544
  }
1351
1545
  ),
1352
- /* @__PURE__ */ jsxs9("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
1546
+ /* @__PURE__ */ jsxs10("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
1353
1547
  state.page,
1354
1548
  " / ",
1355
1549
  pagination.totalPages
1356
1550
  ] }),
1357
- /* @__PURE__ */ jsx10(
1551
+ /* @__PURE__ */ jsx11(
1358
1552
  "button",
1359
1553
  {
1360
1554
  type: "button",
@@ -1362,7 +1556,7 @@ function BookingsTable({
1362
1556
  disabled: state.page >= pagination.totalPages,
1363
1557
  onClick: () => goToPage(state.page + 1),
1364
1558
  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" })
1559
+ children: /* @__PURE__ */ jsx11(ArrowRight, { "aria-hidden": "true", className: "w-4 h-4" })
1366
1560
  }
1367
1561
  )
1368
1562
  ] })
@@ -1391,7 +1585,7 @@ function useBookingsTableState() {
1391
1585
  }
1392
1586
 
1393
1587
  // src/workspace/BookingsArea.tsx
1394
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1588
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1395
1589
  var PAGE_SIZE = 20;
1396
1590
  function BookingsArea() {
1397
1591
  const { locale } = useSchedulingConfig();
@@ -1406,14 +1600,19 @@ function BookingsArea() {
1406
1600
  sortDirection: tableState.sortColumn ? tableState.sortDirection : void 0
1407
1601
  });
1408
1602
  const confirmBooking = useConfirmBooking();
1603
+ const { data: resourcesData } = useResources({ pageSize: MAX_PAGE_SIZE3 });
1409
1604
  const [selectedBookingId, setSelectedBookingId] = useState8(void 0);
1410
1605
  const selectedBooking = data?.data.find((booking) => booking.id === selectedBookingId);
1606
+ const selectedBookingResourceTimezone = resourcesData?.data.find(
1607
+ (resource) => resource.id === selectedBooking?.resourceIds[0]
1608
+ )?.timezone;
1411
1609
  function bulkConfirm(ids) {
1412
1610
  for (const id of ids) confirmBooking.mutate(id);
1413
1611
  }
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(
1612
+ return /* @__PURE__ */ jsxs11("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
1613
+ 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"] }),
1614
+ 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"] }),
1615
+ isLoading ? /* @__PURE__ */ jsx12("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.loading"] }) : /* @__PURE__ */ jsx12(
1417
1616
  BookingsTable,
1418
1617
  {
1419
1618
  bookings: data?.data ?? [],
@@ -1424,24 +1623,37 @@ function BookingsArea() {
1424
1623
  bulkActions: [{ key: "confirm", label: messages["booking.confirm"], onRun: bulkConfirm }]
1425
1624
  }
1426
1625
  ),
1427
- selectedBooking && /* @__PURE__ */ jsx11(BookingDrawer, { booking: selectedBooking, onClose: () => setSelectedBookingId(void 0) })
1626
+ selectedBooking && /* @__PURE__ */ jsx12(
1627
+ BookingDrawer,
1628
+ {
1629
+ booking: selectedBooking,
1630
+ resourceTimezone: selectedBookingResourceTimezone,
1631
+ onClose: () => setSelectedBookingId(void 0)
1632
+ },
1633
+ selectedBooking.id
1634
+ )
1428
1635
  ] });
1429
1636
  }
1430
1637
 
1431
1638
  // src/workspace/ResourcesArea.tsx
1432
1639
  import { Plus as Plus3, Trash2 as Trash23 } from "lucide-react";
1433
1640
  import { useState as useState10 } from "react";
1641
+ import { MAX_PAGE_SIZE as MAX_PAGE_SIZE4 } from "@adatechnology/scheduling-contracts";
1434
1642
 
1435
1643
  // src/components/ResourceForm.tsx
1436
- import { useState as useState9 } from "react";
1644
+ import { useId as useId2, useState as useState9 } from "react";
1437
1645
  import { RESOURCE_KIND } from "@adatechnology/scheduling-contracts";
1438
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1646
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1439
1647
  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
1648
  var LABEL_CLASS = "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1";
1441
1649
  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
1650
  function ResourceForm({ initialValues, onSubmit }) {
1443
1651
  const { locale } = useSchedulingConfig();
1444
1652
  const messages = resolveSchedulingMessages(locale);
1653
+ const formId = useId2();
1654
+ const nameId = `${formId}-name`;
1655
+ const kindId = `${formId}-kind`;
1656
+ const timezoneId = `${formId}-timezone`;
1445
1657
  const [name, setName] = useState9(initialValues?.name ?? "");
1446
1658
  const [kind, setKind] = useState9(initialValues?.kind ?? RESOURCE_KIND.PERSON);
1447
1659
  const [timezone, setTimezone] = useState9(initialValues?.timezone ?? "America/Sao_Paulo");
@@ -1456,13 +1668,13 @@ function ResourceForm({ initialValues, onSubmit }) {
1456
1668
  setSubmitting(false);
1457
1669
  }
1458
1670
  }
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(
1671
+ return /* @__PURE__ */ jsxs12("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1672
+ /* @__PURE__ */ jsxs12("div", { children: [
1673
+ /* @__PURE__ */ jsx13("label", { htmlFor: nameId, className: LABEL_CLASS, children: messages["resource.name"] }),
1674
+ /* @__PURE__ */ jsx13(
1463
1675
  "input",
1464
1676
  {
1465
- id: "scheduling-resource-name",
1677
+ id: nameId,
1466
1678
  type: "text",
1467
1679
  required: true,
1468
1680
  value: name,
@@ -1471,29 +1683,29 @@ function ResourceForm({ initialValues, onSubmit }) {
1471
1683
  }
1472
1684
  )
1473
1685
  ] }),
1474
- /* @__PURE__ */ jsxs11("div", { children: [
1475
- /* @__PURE__ */ jsx12("label", { htmlFor: "scheduling-resource-kind", className: LABEL_CLASS, children: messages["resource.kind"] }),
1476
- /* @__PURE__ */ jsxs11(
1686
+ /* @__PURE__ */ jsxs12("div", { children: [
1687
+ /* @__PURE__ */ jsx13("label", { htmlFor: kindId, className: LABEL_CLASS, children: messages["resource.kind"] }),
1688
+ /* @__PURE__ */ jsxs12(
1477
1689
  "select",
1478
1690
  {
1479
- id: "scheduling-resource-kind",
1691
+ id: kindId,
1480
1692
  value: kind,
1481
1693
  onChange: (event) => setKind(event.target.value),
1482
1694
  className: INPUT_CLASS2,
1483
1695
  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"] })
1696
+ /* @__PURE__ */ jsx13("option", { value: RESOURCE_KIND.PERSON, children: messages["resource.kind.person"] }),
1697
+ /* @__PURE__ */ jsx13("option", { value: RESOURCE_KIND.ROOM, children: messages["resource.kind.room"] }),
1698
+ /* @__PURE__ */ jsx13("option", { value: RESOURCE_KIND.EQUIPMENT, children: messages["resource.kind.equipment"] })
1487
1699
  ]
1488
1700
  }
1489
1701
  )
1490
1702
  ] }),
1491
- /* @__PURE__ */ jsxs11("div", { children: [
1492
- /* @__PURE__ */ jsx12("label", { htmlFor: "scheduling-resource-timezone", className: LABEL_CLASS, children: messages["resource.timezone"] }),
1493
- /* @__PURE__ */ jsx12(
1703
+ /* @__PURE__ */ jsxs12("div", { children: [
1704
+ /* @__PURE__ */ jsx13("label", { htmlFor: timezoneId, className: LABEL_CLASS, children: messages["resource.timezone"] }),
1705
+ /* @__PURE__ */ jsx13(
1494
1706
  "input",
1495
1707
  {
1496
- id: "scheduling-resource-timezone",
1708
+ id: timezoneId,
1497
1709
  type: "text",
1498
1710
  required: true,
1499
1711
  value: timezone,
@@ -1503,47 +1715,47 @@ function ResourceForm({ initialValues, onSubmit }) {
1503
1715
  }
1504
1716
  )
1505
1717
  ] }),
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) }),
1718
+ initialValues && /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300 min-h-11", children: [
1719
+ /* @__PURE__ */ jsx13("input", { type: "checkbox", checked: active, onChange: (event) => setActive(event.target.checked) }),
1508
1720
  messages["resource.active"]
1509
1721
  ] }),
1510
- /* @__PURE__ */ jsx12("button", { type: "submit", disabled: submitting, className: BUTTON_PRIMARY, children: messages["common.save"] })
1722
+ /* @__PURE__ */ jsx13("button", { type: "submit", disabled: submitting, className: BUTTON_PRIMARY, children: messages["common.save"] })
1511
1723
  ] });
1512
1724
  }
1513
1725
 
1514
1726
  // src/components/ResourceList.tsx
1515
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1727
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1516
1728
  function ResourceList({ resources, onSelect }) {
1517
1729
  const { locale } = useSchedulingConfig();
1518
1730
  const messages = resolveSchedulingMessages(locale);
1519
1731
  if (resources.length === 0) {
1520
- return /* @__PURE__ */ jsx13("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.empty"] });
1732
+ return /* @__PURE__ */ jsx14("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.empty"] });
1521
1733
  }
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(
1734
+ 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
1735
  "button",
1524
1736
  {
1525
1737
  type: "button",
1526
1738
  onClick: () => onSelect(resource),
1527
1739
  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
1740
  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"] })
1741
+ /* @__PURE__ */ jsx14("span", { className: "flex-1 font-medium text-gray-900 dark:text-gray-100", children: resource.name }),
1742
+ /* @__PURE__ */ jsx14("span", { className: "text-gray-500 dark:text-gray-400", children: messages[`resource.kind.${resource.kind}`] }),
1743
+ /* @__PURE__ */ jsx14("span", { className: "text-gray-500 dark:text-gray-400", children: resource.timezone }),
1744
+ !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
1745
  ]
1534
1746
  }
1535
1747
  ) }, resource.id)) });
1536
1748
  }
1537
1749
 
1538
1750
  // src/workspace/ResourcesArea.tsx
1539
- import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1751
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
1540
1752
  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
1753
  var BUTTON_PRIMARY2 = `${BUTTON_CLASS2} bg-brand-600 text-white hover:bg-brand-700`;
1542
1754
  var BUTTON_DANGER = `${BUTTON_CLASS2} text-red-700 hover:bg-red-50`;
1543
1755
  function ResourcesArea() {
1544
1756
  const { locale } = useSchedulingConfig();
1545
1757
  const messages = resolveSchedulingMessages(locale);
1546
- const { data, isLoading, isError } = useResources();
1758
+ const { data, isLoading, isError } = useResources({ pageSize: MAX_PAGE_SIZE4 });
1547
1759
  const createResource = useCreateResource();
1548
1760
  const updateResource = useUpdateResource();
1549
1761
  const deleteResource = useDeleteResource();
@@ -1561,21 +1773,21 @@ function ResourcesArea() {
1561
1773
  } catch {
1562
1774
  }
1563
1775
  }
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" }),
1776
+ return /* @__PURE__ */ jsxs14("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
1777
+ /* @__PURE__ */ jsx15("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxs14("button", { type: "button", onClick: () => setDraft(null), className: `${BUTTON_PRIMARY2} ml-auto`, children: [
1778
+ /* @__PURE__ */ jsx15(Plus3, { "aria-hidden": "true", className: "w-4 h-4" }),
1567
1779
  messages["resource.newResource"]
1568
1780
  ] }) }),
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(
1781
+ 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"] }),
1782
+ (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"] }),
1783
+ 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 }),
1784
+ isDraftOpen && /* @__PURE__ */ jsx15(
1573
1785
  SidePanel,
1574
1786
  {
1575
1787
  title: isEditing ? messages["resource.editTitle"] : messages["resource.createTitle"],
1576
1788
  closeLabel: messages["common.close"],
1577
1789
  onClose: () => setDraft(void 0),
1578
- headerActions: isEditing ? /* @__PURE__ */ jsxs13(
1790
+ headerActions: isEditing ? /* @__PURE__ */ jsxs14(
1579
1791
  "button",
1580
1792
  {
1581
1793
  type: "button",
@@ -1585,12 +1797,12 @@ function ResourcesArea() {
1585
1797
  },
1586
1798
  className: BUTTON_DANGER,
1587
1799
  children: [
1588
- /* @__PURE__ */ jsx14(Trash23, { "aria-hidden": "true", className: "w-4 h-4" }),
1800
+ /* @__PURE__ */ jsx15(Trash23, { "aria-hidden": "true", className: "w-4 h-4" }),
1589
1801
  messages["common.remove"]
1590
1802
  ]
1591
1803
  }
1592
1804
  ) : void 0,
1593
- children: /* @__PURE__ */ jsx14(
1805
+ children: /* @__PURE__ */ jsx15(
1594
1806
  ResourceForm,
1595
1807
  {
1596
1808
  ...draft ? { initialValues: draft } : {},
@@ -1606,10 +1818,11 @@ function ResourcesArea() {
1606
1818
  // src/workspace/ServicesArea.tsx
1607
1819
  import { Plus as Plus4, Trash2 as Trash24 } from "lucide-react";
1608
1820
  import { useState as useState12 } from "react";
1821
+ import { MAX_PAGE_SIZE as MAX_PAGE_SIZE5 } from "@adatechnology/scheduling-contracts";
1609
1822
 
1610
1823
  // src/components/ServiceForm.tsx
1611
1824
  import { useState as useState11 } from "react";
1612
- import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
1825
+ import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
1613
1826
  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
1827
  var LABEL_CLASS2 = "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1";
1615
1828
  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 +1844,10 @@ function ServiceForm({ initialValues, onSubmit }) {
1631
1844
  setSubmitting(false);
1632
1845
  }
1633
1846
  }
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(
1847
+ return /* @__PURE__ */ jsxs15("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1848
+ /* @__PURE__ */ jsxs15("div", { children: [
1849
+ /* @__PURE__ */ jsx16("label", { htmlFor: "scheduling-service-name", className: LABEL_CLASS2, children: messages["service.name"] }),
1850
+ /* @__PURE__ */ jsx16(
1638
1851
  "input",
1639
1852
  {
1640
1853
  id: "scheduling-service-name",
@@ -1646,9 +1859,9 @@ function ServiceForm({ initialValues, onSubmit }) {
1646
1859
  }
1647
1860
  )
1648
1861
  ] }),
1649
- /* @__PURE__ */ jsxs14("div", { children: [
1650
- /* @__PURE__ */ jsx15("label", { htmlFor: "scheduling-service-duration", className: LABEL_CLASS2, children: messages["service.durationMinutes"] }),
1651
- /* @__PURE__ */ jsx15(
1862
+ /* @__PURE__ */ jsxs15("div", { children: [
1863
+ /* @__PURE__ */ jsx16("label", { htmlFor: "scheduling-service-duration", className: LABEL_CLASS2, children: messages["service.durationMinutes"] }),
1864
+ /* @__PURE__ */ jsx16(
1652
1865
  "input",
1653
1866
  {
1654
1867
  id: "scheduling-service-duration",
@@ -1661,10 +1874,10 @@ function ServiceForm({ initialValues, onSubmit }) {
1661
1874
  }
1662
1875
  )
1663
1876
  ] }),
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(
1877
+ /* @__PURE__ */ jsxs15("div", { className: "grid grid-cols-2 gap-3", children: [
1878
+ /* @__PURE__ */ jsxs15("div", { children: [
1879
+ /* @__PURE__ */ jsx16("label", { htmlFor: "scheduling-service-buffer-before", className: LABEL_CLASS2, children: messages["service.bufferBeforeMinutes"] }),
1880
+ /* @__PURE__ */ jsx16(
1668
1881
  "input",
1669
1882
  {
1670
1883
  id: "scheduling-service-buffer-before",
@@ -1676,9 +1889,9 @@ function ServiceForm({ initialValues, onSubmit }) {
1676
1889
  }
1677
1890
  )
1678
1891
  ] }),
1679
- /* @__PURE__ */ jsxs14("div", { children: [
1680
- /* @__PURE__ */ jsx15("label", { htmlFor: "scheduling-service-buffer-after", className: LABEL_CLASS2, children: messages["service.bufferAfterMinutes"] }),
1681
- /* @__PURE__ */ jsx15(
1892
+ /* @__PURE__ */ jsxs15("div", { children: [
1893
+ /* @__PURE__ */ jsx16("label", { htmlFor: "scheduling-service-buffer-after", className: LABEL_CLASS2, children: messages["service.bufferAfterMinutes"] }),
1894
+ /* @__PURE__ */ jsx16(
1682
1895
  "input",
1683
1896
  {
1684
1897
  id: "scheduling-service-buffer-after",
@@ -1691,49 +1904,49 @@ function ServiceForm({ initialValues, onSubmit }) {
1691
1904
  )
1692
1905
  ] })
1693
1906
  ] }),
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) }),
1907
+ initialValues && /* @__PURE__ */ jsxs15("label", { className: "flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300 min-h-11", children: [
1908
+ /* @__PURE__ */ jsx16("input", { type: "checkbox", checked: active, onChange: (event) => setActive(event.target.checked) }),
1696
1909
  messages["service.active"]
1697
1910
  ] }),
1698
- /* @__PURE__ */ jsx15("button", { type: "submit", disabled: submitting, className: BUTTON_PRIMARY3, children: messages["common.save"] })
1911
+ /* @__PURE__ */ jsx16("button", { type: "submit", disabled: submitting, className: BUTTON_PRIMARY3, children: messages["common.save"] })
1699
1912
  ] });
1700
1913
  }
1701
1914
 
1702
1915
  // src/components/ServiceList.tsx
1703
- import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
1916
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
1704
1917
  function ServiceList({ services, onSelect }) {
1705
1918
  const { locale } = useSchedulingConfig();
1706
1919
  const messages = resolveSchedulingMessages(locale);
1707
1920
  if (services.length === 0) {
1708
- return /* @__PURE__ */ jsx16("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.empty"] });
1921
+ return /* @__PURE__ */ jsx17("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: messages["common.empty"] });
1709
1922
  }
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(
1923
+ 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
1924
  "button",
1712
1925
  {
1713
1926
  type: "button",
1714
1927
  onClick: () => onSelect(service),
1715
1928
  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
1929
  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: [
1930
+ /* @__PURE__ */ jsx17("span", { className: "flex-1 font-medium text-gray-900 dark:text-gray-100", children: service.name }),
1931
+ /* @__PURE__ */ jsxs16("span", { className: "text-gray-500 dark:text-gray-400", children: [
1719
1932
  service.durationMinutes,
1720
1933
  " min"
1721
1934
  ] }),
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"] })
1935
+ !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
1936
  ]
1724
1937
  }
1725
1938
  ) }, service.id)) });
1726
1939
  }
1727
1940
 
1728
1941
  // src/workspace/ServicesArea.tsx
1729
- import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
1942
+ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
1730
1943
  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
1944
  var BUTTON_PRIMARY4 = `${BUTTON_CLASS3} bg-brand-600 text-white hover:bg-brand-700`;
1732
1945
  var BUTTON_DANGER2 = `${BUTTON_CLASS3} text-red-700 hover:bg-red-50`;
1733
1946
  function ServicesArea() {
1734
1947
  const { locale } = useSchedulingConfig();
1735
1948
  const messages = resolveSchedulingMessages(locale);
1736
- const { data, isLoading, isError } = useServices();
1949
+ const { data, isLoading, isError } = useServices({ pageSize: MAX_PAGE_SIZE5 });
1737
1950
  const createService = useCreateService();
1738
1951
  const updateService = useUpdateService();
1739
1952
  const deleteService = useDeleteService();
@@ -1751,21 +1964,21 @@ function ServicesArea() {
1751
1964
  } catch {
1752
1965
  }
1753
1966
  }
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" }),
1967
+ return /* @__PURE__ */ jsxs17("div", { className: "flex flex-1 min-h-0 min-w-0 flex-col p-4 space-y-4", children: [
1968
+ /* @__PURE__ */ jsx18("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxs17("button", { type: "button", onClick: () => setDraft(null), className: `${BUTTON_PRIMARY4} ml-auto`, children: [
1969
+ /* @__PURE__ */ jsx18(Plus4, { "aria-hidden": "true", className: "w-4 h-4" }),
1757
1970
  messages["service.newService"]
1758
1971
  ] }) }),
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(
1972
+ 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"] }),
1973
+ (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"] }),
1974
+ 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 }),
1975
+ isDraftOpen && /* @__PURE__ */ jsx18(
1763
1976
  SidePanel,
1764
1977
  {
1765
1978
  title: isEditing ? messages["service.editTitle"] : messages["service.createTitle"],
1766
1979
  closeLabel: messages["common.close"],
1767
1980
  onClose: () => setDraft(void 0),
1768
- headerActions: isEditing ? /* @__PURE__ */ jsxs16(
1981
+ headerActions: isEditing ? /* @__PURE__ */ jsxs17(
1769
1982
  "button",
1770
1983
  {
1771
1984
  type: "button",
@@ -1775,12 +1988,12 @@ function ServicesArea() {
1775
1988
  },
1776
1989
  className: BUTTON_DANGER2,
1777
1990
  children: [
1778
- /* @__PURE__ */ jsx17(Trash24, { "aria-hidden": "true", className: "w-4 h-4" }),
1991
+ /* @__PURE__ */ jsx18(Trash24, { "aria-hidden": "true", className: "w-4 h-4" }),
1779
1992
  messages["common.remove"]
1780
1993
  ]
1781
1994
  }
1782
1995
  ) : void 0,
1783
- children: /* @__PURE__ */ jsx17(
1996
+ children: /* @__PURE__ */ jsx18(
1784
1997
  ServiceForm,
1785
1998
  {
1786
1999
  ...draft ? { initialValues: draft } : {},
@@ -1810,7 +2023,7 @@ function isSchedulingWorkspaceArea(value) {
1810
2023
  }
1811
2024
 
1812
2025
  // src/workspace/WorkspaceAreaNav.tsx
1813
- import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
2026
+ import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
1814
2027
  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
2028
  var ITEM_ACTIVE = "border-brand-600 text-brand-700 dark:text-brand-400";
1816
2029
  var ITEM_IDLE = "border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100";
@@ -1829,9 +2042,9 @@ function WorkspaceAreaNav({ area, labels, onSelect }) {
1829
2042
  [SCHEDULING_WORKSPACE_AREA.SERVICES, labels.servicesTab],
1830
2043
  [SCHEDULING_WORKSPACE_AREA.AVAILABILITY, labels.availabilityTab]
1831
2044
  ];
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]) => {
2045
+ 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
2046
  const Icon = AREA_ICON[value];
1834
- return /* @__PURE__ */ jsxs17(
2047
+ return /* @__PURE__ */ jsxs18(
1835
2048
  "button",
1836
2049
  {
1837
2050
  type: "button",
@@ -1839,7 +2052,7 @@ function WorkspaceAreaNav({ area, labels, onSelect }) {
1839
2052
  "aria-current": value === area ? "page" : void 0,
1840
2053
  className: `${ITEM_BASE} ${value === area ? ITEM_ACTIVE : ITEM_IDLE} whitespace-nowrap`,
1841
2054
  children: [
1842
- /* @__PURE__ */ jsx18(Icon, { "aria-hidden": "true", className: "w-4 h-4 shrink-0" }),
2055
+ /* @__PURE__ */ jsx19(Icon, { "aria-hidden": "true", className: "w-4 h-4 shrink-0" }),
1843
2056
  label
1844
2057
  ]
1845
2058
  },
@@ -1849,7 +2062,7 @@ function WorkspaceAreaNav({ area, labels, onSelect }) {
1849
2062
  }
1850
2063
 
1851
2064
  // src/workspace/SchedulingWorkspace.tsx
1852
- import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
2065
+ import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
1853
2066
  var AREA_COMPONENT = {
1854
2067
  [SCHEDULING_WORKSPACE_AREA.AGENDA]: AgendaArea,
1855
2068
  [SCHEDULING_WORKSPACE_AREA.BOOKINGS]: BookingsArea,
@@ -1871,13 +2084,13 @@ function SchedulingWorkspace({
1871
2084
  setInternalArea(next);
1872
2085
  onAreaChange?.(next);
1873
2086
  }
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 }),
2087
+ return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col h-full", children: [
2088
+ /* @__PURE__ */ jsxs19("header", { className: "flex flex-wrap items-center gap-3 px-4 py-3", children: [
2089
+ /* @__PURE__ */ jsx20("h1", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100 mr-auto", children: labels.title }),
1877
2090
  renderHeaderActions?.()
1878
2091
  ] }),
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, {}) })
2092
+ /* @__PURE__ */ jsx20(WorkspaceAreaNav, { area, labels, onSelect: handleSelectArea }),
2093
+ /* @__PURE__ */ jsx20("div", { className: "relative flex flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx20(AreaComponent, {}) })
1881
2094
  ] });
1882
2095
  }
1883
2096
  export {