@burdenoff/microfe-tours 2026.519.1 → 2026.523.1

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.
Files changed (52) hide show
  1. package/dist/index.js +2 -1
  2. package/dist/tours/ToursAdminRoot.d.ts.map +1 -1
  3. package/dist/tours/ToursAdminRoot.js +23 -20
  4. package/dist/tours/ToursAdminRoot.js.map +1 -1
  5. package/dist/tours/ToursUserRoot.d.ts.map +1 -1
  6. package/dist/tours/ToursUserRoot.js +25 -22
  7. package/dist/tours/ToursUserRoot.js.map +1 -1
  8. package/dist/tours/hooks/useMediaLibrary.js +3 -3
  9. package/dist/tours/hooks/useTourBuilder.js +10 -10
  10. package/dist/tours/hooks/useTourLifecycle.js +3 -3
  11. package/dist/tours/i18n.d.ts +5 -1
  12. package/dist/tours/i18n.d.ts.map +1 -1
  13. package/dist/tours/i18n.js +4 -0
  14. package/dist/tours/i18n.js.map +1 -1
  15. package/dist/tours/index.d.ts +1 -0
  16. package/dist/tours/index.d.ts.map +1 -1
  17. package/dist/tours/index.js +1 -0
  18. package/dist/tours/pages/AnalyticsDashboardPage.d.ts.map +1 -1
  19. package/dist/tours/pages/AnalyticsDashboardPage.js +5 -5
  20. package/dist/tours/pages/AnalyticsDashboardPage.js.map +1 -1
  21. package/dist/tours/pages/MediaLibraryPage.d.ts.map +1 -1
  22. package/dist/tours/pages/MediaLibraryPage.js +97 -96
  23. package/dist/tours/pages/MediaLibraryPage.js.map +1 -1
  24. package/dist/tours/pages/SchedulerPage.d.ts.map +1 -1
  25. package/dist/tours/pages/SchedulerPage.js +129 -126
  26. package/dist/tours/pages/SchedulerPage.js.map +1 -1
  27. package/dist/tours/pages/StepEditorPage.d.ts.map +1 -1
  28. package/dist/tours/pages/StepEditorPage.js +133 -128
  29. package/dist/tours/pages/StepEditorPage.js.map +1 -1
  30. package/dist/tours/pages/SystemAnalyticsPage.d.ts.map +1 -1
  31. package/dist/tours/pages/SystemAnalyticsPage.js +3 -3
  32. package/dist/tours/pages/SystemAnalyticsPage.js.map +1 -1
  33. package/dist/tours/pages/TemplateLibraryPage.d.ts.map +1 -1
  34. package/dist/tours/pages/TemplateLibraryPage.js +97 -94
  35. package/dist/tours/pages/TemplateLibraryPage.js.map +1 -1
  36. package/dist/tours/pages/TourBuilderPage.d.ts.map +1 -1
  37. package/dist/tours/pages/TourBuilderPage.js +232 -230
  38. package/dist/tours/pages/TourBuilderPage.js.map +1 -1
  39. package/dist/tours/pages/TourPreviewPage.d.ts.map +1 -1
  40. package/dist/tours/pages/TourPreviewPage.js +20 -18
  41. package/dist/tours/pages/TourPreviewPage.js.map +1 -1
  42. package/dist/tours/pages/ToursListPage.js +14 -14
  43. package/dist/tours/pages/ToursListPage.js.map +1 -1
  44. package/dist/tours/store/toursStore.d.ts +1 -0
  45. package/dist/tours/store/toursStore.d.ts.map +1 -1
  46. package/dist/tours/store/toursStore.js +14 -0
  47. package/dist/tours/store/toursStore.js.map +1 -1
  48. package/dist/tours/telemetry.d.ts +9 -0
  49. package/dist/tours/telemetry.d.ts.map +1 -0
  50. package/dist/tours/telemetry.js +19 -0
  51. package/dist/tours/telemetry.js.map +1 -0
  52. package/package.json +1 -1
@@ -2,92 +2,95 @@ import { useToursContext as e } from "../providers/ToursProvider.js";
2
2
  import { useCreateTourScheduleMutation as t, useGetTourSchedulesQuery as n } from "../../generated/global-operations.js";
3
3
  import { useToursPermissionAccess as r } from "../hooks/useToursPermissionAccess.js";
4
4
  import { TOUR_PERMISSIONS as i } from "../../constants/permissions.js";
5
- import { useCallback as a, useState as o } from "react";
6
- import { PermissionGate as s } from "@burdenoff/fe-libs/shared/components";
7
- import { ArrowLeft as c, Calendar as l, Clock as u, Save as d } from "lucide-react";
8
- import { jsx as f, jsxs as p } from "react/jsx-runtime";
9
- import { useNavigate as m, useParams as h } from "react-router-dom";
10
- import { useI18n as g } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
+ import { emitToursApiFailed as a } from "../telemetry.js";
6
+ import { useCallback as o, useState as s } from "react";
7
+ import { PermissionGate as c } from "@burdenoff/fe-libs/shared/components";
8
+ import { ArrowLeft as l, Calendar as u, Clock as d, Save as f } from "lucide-react";
9
+ import { jsx as p, jsxs as m } from "react/jsx-runtime";
10
+ import { useNavigate as h, useParams as g } from "react-router-dom";
11
+ import { useI18n as _ } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
12
+ import { useEventBus as v } from "@burdenoff/fe-libs/shared/events";
11
13
  //#region src/tours/pages/SchedulerPage.tsx
12
- function _() {
13
- let { t: _ } = g(), v = a((e, t) => {
14
- let n = _(e);
14
+ function y() {
15
+ let { t: y } = _(), b = o((e, t) => {
16
+ let n = y(e);
15
17
  return n === e ? t : n;
16
- }, [_]), { tourId: y } = h(), b = m(), { basePath: x = "/" } = e(), { hasPermission: S } = r(), C = S(i.TOUR_SCHEDULE_CREATE), w = S(i.TOUR_SCHEDULE_LIST), [T, E] = o({
18
+ }, [y]), { tourId: x } = g(), S = h(), C = e(), { basePath: w = "/" } = C, T = v(), { hasPermission: E } = r(), D = E(i.TOUR_SCHEDULE_CREATE), O = E(i.TOUR_SCHEDULE_LIST), [k, A] = s({
17
19
  startDate: "",
18
20
  endDate: "",
19
21
  recurrencePattern: "DAILY",
20
22
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
21
23
  isActive: !0
22
- }), [D, O] = o(!1), [k] = t(), { data: A } = n({
23
- variables: { tourId: y },
24
- skip: !y || !w
25
- }), j = A?.tourSchedules ?? [], M = async (e) => {
26
- if (e.preventDefault(), y) {
27
- O(!0);
24
+ }), [j, M] = s(!1), [N] = t(), { data: P } = n({
25
+ variables: { tourId: x },
26
+ skip: !x || !O
27
+ }), F = P?.tourSchedules ?? [], I = async (e) => {
28
+ if (e.preventDefault(), x) {
29
+ M(!0);
28
30
  try {
29
- let e = T.recurrencePattern === "DAILY" ? "FREQ=DAILY" : T.recurrencePattern === "WEEKLY" ? "FREQ=WEEKLY" : T.recurrencePattern === "MONTHLY" ? "FREQ=MONTHLY" : void 0;
30
- await k({
31
+ let e = k.recurrencePattern === "DAILY" ? "FREQ=DAILY" : k.recurrencePattern === "WEEKLY" ? "FREQ=WEEKLY" : k.recurrencePattern === "MONTHLY" ? "FREQ=MONTHLY" : void 0;
32
+ await N({
31
33
  variables: { input: {
32
- tourId: y,
33
- startDate: new Date(T.startDate).toISOString(),
34
- endDate: T.endDate ? new Date(T.endDate).toISOString() : void 0,
34
+ tourId: x,
35
+ startDate: new Date(k.startDate).toISOString(),
36
+ endDate: k.endDate ? new Date(k.endDate).toISOString() : void 0,
35
37
  recurrenceRule: e,
36
- timezone: T.timezone
38
+ timezone: k.timezone
37
39
  } },
38
40
  refetchQueries: ["GetTourSchedules"]
39
- }), b(`${x}/${y}/edit`);
40
- } catch (e) {
41
- console.error("Failed to create schedule:", e);
41
+ }), S(`${w}/${x}/edit`);
42
+ } catch {
43
+ a(T, "schedule.create", C);
42
44
  } finally {
43
- O(!1);
45
+ M(!1);
44
46
  }
45
47
  }
46
- }, N = () => {
47
- b(`${x}/${y}/edit`);
48
+ }, L = () => {
49
+ S(`${w}/${x}/edit`);
48
50
  };
49
- return /* @__PURE__ */ p("div", {
50
- className: "space-y-6 p-6 max-w-3xl mx-auto",
51
+ return /* @__PURE__ */ m("div", {
52
+ className: "space-y-4 sm:space-y-6 p-3 sm:p-6 max-w-3xl mx-auto",
51
53
  children: [
52
- /* @__PURE__ */ p("div", {
53
- className: "flex items-center gap-4",
54
- children: [/* @__PURE__ */ f("button", {
55
- onClick: N,
56
- className: "p-2 hover:bg-accent rounded-md",
57
- children: /* @__PURE__ */ f(c, { size: 20 })
58
- }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h1", {
59
- className: "text-2xl font-bold",
60
- children: v("tourScheduler.title", "Schedule Tour")
61
- }), /* @__PURE__ */ f("p", {
54
+ /* @__PURE__ */ m("div", {
55
+ className: "flex items-center gap-3 sm:gap-4",
56
+ children: [/* @__PURE__ */ p("button", {
57
+ onClick: L,
58
+ className: "p-2 min-h-[44px] min-w-[44px] hover:bg-accent rounded-md",
59
+ "aria-label": b("tourScheduler.goBack", "Go back"),
60
+ children: /* @__PURE__ */ p(l, { size: 20 })
61
+ }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h1", {
62
+ className: "text-xl sm:text-2xl font-bold",
63
+ children: b("tourScheduler.title", "Schedule Tour")
64
+ }), /* @__PURE__ */ p("p", {
62
65
  className: "text-sm text-muted-foreground",
63
- children: v("tourScheduler.subtitle", "Configure when this tour should be activated")
66
+ children: b("tourScheduler.subtitle", "Configure when this tour should be activated")
64
67
  })] })]
65
68
  }),
66
- j.length > 0 && /* @__PURE__ */ p("div", {
67
- className: "border border-border rounded-md p-6 bg-card",
68
- children: [/* @__PURE__ */ f("h2", {
69
+ F.length > 0 && /* @__PURE__ */ m("div", {
70
+ className: "border border-border rounded-md p-4 sm:p-6 bg-card",
71
+ children: [/* @__PURE__ */ p("h2", {
69
72
  className: "text-lg font-semibold mb-4",
70
- children: v("tourScheduler.existingSchedules", "Existing Schedules")
71
- }), /* @__PURE__ */ f("div", {
73
+ children: b("tourScheduler.existingSchedules", "Existing Schedules")
74
+ }), /* @__PURE__ */ p("div", {
72
75
  className: "space-y-2",
73
- children: j.map((e) => /* @__PURE__ */ p("div", {
74
- className: "flex items-center justify-between p-3 border border-border rounded-md",
75
- children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ p("div", {
76
+ children: F.map((e) => /* @__PURE__ */ m("div", {
77
+ className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between p-3 border border-border rounded-md",
78
+ children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ m("div", {
76
79
  className: "text-sm font-medium",
77
- children: [new Date(e.startDate).toLocaleDateString(), e.endDate ? ` — ${new Date(e.endDate).toLocaleDateString()}` : ` — ${v("tourScheduler.noEndDate", "No end date")}`]
78
- }), /* @__PURE__ */ p("div", {
80
+ children: [new Date(e.startDate).toLocaleDateString(), e.endDate ? ` — ${new Date(e.endDate).toLocaleDateString()}` : ` — ${b("tourScheduler.noEndDate", "No end date")}`]
81
+ }), /* @__PURE__ */ m("div", {
79
82
  className: "text-xs text-muted-foreground",
80
83
  children: [
81
- e.recurrenceRule || v("tourScheduler.oneTime", "One-time"),
84
+ e.recurrenceRule || b("tourScheduler.oneTime", "One-time"),
82
85
  " ·",
83
86
  " ",
84
87
  e.timezone,
85
- e.isActive ? ` · ${v("tourScheduler.active", "Active")}` : ` · ${v("tourScheduler.inactive", "Inactive")}`
88
+ e.isActive ? ` · ${b("tourScheduler.active", "Active")}` : ` · ${b("tourScheduler.inactive", "Inactive")}`
86
89
  ]
87
- })] }), /* @__PURE__ */ p("div", {
90
+ })] }), /* @__PURE__ */ m("div", {
88
91
  className: "text-xs text-muted-foreground",
89
92
  children: [
90
- v("tourScheduler.runs", "Runs"),
93
+ b("tourScheduler.runs", "Runs"),
91
94
  ": ",
92
95
  e.executionCount
93
96
  ]
@@ -95,128 +98,128 @@ function _() {
95
98
  }, e.id))
96
99
  })]
97
100
  }),
98
- /* @__PURE__ */ p("form", {
99
- onSubmit: M,
101
+ /* @__PURE__ */ m("form", {
102
+ onSubmit: I,
100
103
  className: "space-y-6",
101
104
  children: [
102
- /* @__PURE__ */ p("div", {
103
- className: "border border-border rounded-md p-6 bg-card",
104
- children: [/* @__PURE__ */ p("h2", {
105
+ /* @__PURE__ */ m("div", {
106
+ className: "border border-border rounded-md p-4 sm:p-6 bg-card",
107
+ children: [/* @__PURE__ */ m("h2", {
105
108
  className: "text-lg font-semibold mb-4 flex items-center gap-2",
106
- children: [/* @__PURE__ */ f(l, { size: 20 }), v("tourScheduler.sectionDateRange", "Date Range")]
107
- }), /* @__PURE__ */ p("div", {
109
+ children: [/* @__PURE__ */ p(u, { size: 20 }), b("tourScheduler.sectionDateRange", "Date Range")]
110
+ }), /* @__PURE__ */ m("div", {
108
111
  className: "space-y-4",
109
- children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
112
+ children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
110
113
  className: "block text-sm font-medium mb-2",
111
- children: v("tourScheduler.labelStartDate", "Start Date *")
112
- }), /* @__PURE__ */ f("input", {
114
+ children: b("tourScheduler.labelStartDate", "Start Date *")
115
+ }), /* @__PURE__ */ p("input", {
113
116
  type: "datetime-local",
114
- value: T.startDate,
115
- onChange: (e) => E({
116
- ...T,
117
+ value: k.startDate,
118
+ onChange: (e) => A({
119
+ ...k,
117
120
  startDate: e.target.value
118
121
  }),
119
- className: "w-full px-3 py-2 border border-border rounded-md bg-background",
122
+ className: "w-full px-3 py-2 min-h-[44px] border border-border rounded-md bg-background",
120
123
  required: !0
121
- })] }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
124
+ })] }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
122
125
  className: "block text-sm font-medium mb-2",
123
- children: v("tourScheduler.labelEndDate", "End Date (Optional)")
124
- }), /* @__PURE__ */ f("input", {
126
+ children: b("tourScheduler.labelEndDate", "End Date (Optional)")
127
+ }), /* @__PURE__ */ p("input", {
125
128
  type: "datetime-local",
126
- value: T.endDate,
127
- onChange: (e) => E({
128
- ...T,
129
+ value: k.endDate,
130
+ onChange: (e) => A({
131
+ ...k,
129
132
  endDate: e.target.value
130
133
  }),
131
- className: "w-full px-3 py-2 border border-border rounded-md bg-background"
134
+ className: "w-full px-3 py-2 min-h-[44px] border border-border rounded-md bg-background"
132
135
  })] })]
133
136
  })]
134
137
  }),
135
- /* @__PURE__ */ p("div", {
136
- className: "border border-border rounded-md p-6 bg-card",
137
- children: [/* @__PURE__ */ p("h2", {
138
+ /* @__PURE__ */ m("div", {
139
+ className: "border border-border rounded-md p-4 sm:p-6 bg-card",
140
+ children: [/* @__PURE__ */ m("h2", {
138
141
  className: "text-lg font-semibold mb-4 flex items-center gap-2",
139
- children: [/* @__PURE__ */ f(u, { size: 20 }), v("tourScheduler.sectionRecurrence", "Recurrence")]
140
- }), /* @__PURE__ */ p("div", {
142
+ children: [/* @__PURE__ */ p(d, { size: 20 }), b("tourScheduler.sectionRecurrence", "Recurrence")]
143
+ }), /* @__PURE__ */ m("div", {
141
144
  className: "space-y-4",
142
- children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
145
+ children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
143
146
  className: "block text-sm font-medium mb-2",
144
- children: v("tourScheduler.labelRecurrencePattern", "Recurrence Pattern")
145
- }), /* @__PURE__ */ p("select", {
146
- value: T.recurrencePattern,
147
- onChange: (e) => E({
148
- ...T,
147
+ children: b("tourScheduler.labelRecurrencePattern", "Recurrence Pattern")
148
+ }), /* @__PURE__ */ m("select", {
149
+ value: k.recurrencePattern,
150
+ onChange: (e) => A({
151
+ ...k,
149
152
  recurrencePattern: e.target.value
150
153
  }),
151
- className: "w-full px-3 py-2 border border-border rounded-md bg-background",
154
+ className: "w-full px-3 py-2 min-h-[44px] border border-border rounded-md bg-background",
152
155
  children: [
153
- /* @__PURE__ */ f("option", {
156
+ /* @__PURE__ */ p("option", {
154
157
  value: "DAILY",
155
- children: v("tourScheduler.recurrenceDaily", "Daily")
158
+ children: b("tourScheduler.recurrenceDaily", "Daily")
156
159
  }),
157
- /* @__PURE__ */ f("option", {
160
+ /* @__PURE__ */ p("option", {
158
161
  value: "WEEKLY",
159
- children: v("tourScheduler.recurrenceWeekly", "Weekly")
162
+ children: b("tourScheduler.recurrenceWeekly", "Weekly")
160
163
  }),
161
- /* @__PURE__ */ f("option", {
164
+ /* @__PURE__ */ p("option", {
162
165
  value: "MONTHLY",
163
- children: v("tourScheduler.recurrenceMonthly", "Monthly")
166
+ children: b("tourScheduler.recurrenceMonthly", "Monthly")
164
167
  }),
165
- /* @__PURE__ */ f("option", {
168
+ /* @__PURE__ */ p("option", {
166
169
  value: "CUSTOM",
167
- children: v("tourScheduler.recurrenceCustom", "Custom")
170
+ children: b("tourScheduler.recurrenceCustom", "Custom")
168
171
  })
169
172
  ]
170
- })] }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
173
+ })] }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
171
174
  className: "block text-sm font-medium mb-2",
172
- children: v("tourScheduler.labelTimezone", "Timezone")
173
- }), /* @__PURE__ */ f("input", {
175
+ children: b("tourScheduler.labelTimezone", "Timezone")
176
+ }), /* @__PURE__ */ p("input", {
174
177
  type: "text",
175
- value: T.timezone,
176
- onChange: (e) => E({
177
- ...T,
178
+ value: k.timezone,
179
+ onChange: (e) => A({
180
+ ...k,
178
181
  timezone: e.target.value
179
182
  }),
180
- className: "w-full px-3 py-2 border border-border rounded-md bg-background",
183
+ className: "w-full px-3 py-2 min-h-[44px] border border-border rounded-md bg-background",
181
184
  readOnly: !0
182
185
  })] })]
183
186
  })]
184
187
  }),
185
- /* @__PURE__ */ f("div", {
186
- className: "border border-border rounded-md p-6 bg-card",
187
- children: /* @__PURE__ */ p("label", {
188
+ /* @__PURE__ */ p("div", {
189
+ className: "border border-border rounded-md p-4 sm:p-6 bg-card",
190
+ children: /* @__PURE__ */ m("label", {
188
191
  className: "flex items-center gap-3 cursor-pointer",
189
- children: [/* @__PURE__ */ f("input", {
192
+ children: [/* @__PURE__ */ p("input", {
190
193
  type: "checkbox",
191
- checked: T.isActive,
192
- onChange: (e) => E({
193
- ...T,
194
+ checked: k.isActive,
195
+ onChange: (e) => A({
196
+ ...k,
194
197
  isActive: e.target.checked
195
198
  }),
196
199
  className: "w-5 h-5 rounded"
197
- }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("div", {
200
+ }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("div", {
198
201
  className: "font-medium",
199
- children: v("tourScheduler.statusActiveLabel", "Active")
200
- }), /* @__PURE__ */ f("div", {
202
+ children: b("tourScheduler.statusActiveLabel", "Active")
203
+ }), /* @__PURE__ */ p("div", {
201
204
  className: "text-sm text-muted-foreground",
202
- children: v("tourScheduler.statusActiveDescription", "Enable this schedule immediately after creation")
205
+ children: b("tourScheduler.statusActiveDescription", "Enable this schedule immediately after creation")
203
206
  })] })]
204
207
  })
205
208
  }),
206
- /* @__PURE__ */ p("div", {
207
- className: "flex gap-3",
208
- children: [/* @__PURE__ */ f("button", {
209
+ /* @__PURE__ */ m("div", {
210
+ className: "flex flex-col sm:flex-row gap-3",
211
+ children: [/* @__PURE__ */ p("button", {
209
212
  type: "button",
210
- onClick: N,
211
- className: "flex-1 px-4 py-2 border border-border rounded-md hover:bg-accent",
212
- children: v("tourScheduler.cancel", "Cancel")
213
- }), /* @__PURE__ */ f(s, {
213
+ onClick: L,
214
+ className: "flex-1 px-4 py-2 min-h-[44px] border border-border rounded-md hover:bg-accent",
215
+ children: b("tourScheduler.cancel", "Cancel")
216
+ }), /* @__PURE__ */ p(c, {
214
217
  permission: i.TOUR_SCHEDULE_CREATE,
215
- children: /* @__PURE__ */ p("button", {
218
+ children: /* @__PURE__ */ m("button", {
216
219
  type: "submit",
217
- disabled: D || !C,
218
- className: "flex-1 px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 disabled:opacity-50 flex items-center justify-center gap-2",
219
- children: [/* @__PURE__ */ f(d, { size: 20 }), D ? v("tourScheduler.creating", "Creating...") : v("tourScheduler.createSchedule", "Create Schedule")]
220
+ disabled: j || !D,
221
+ className: "flex-1 px-4 py-2 min-h-[44px] bg-primary text-primary-foreground rounded-md hover:bg-primary/90 disabled:opacity-50 flex items-center justify-center gap-2",
222
+ children: [/* @__PURE__ */ p(f, { size: 20 }), j ? b("tourScheduler.creating", "Creating...") : b("tourScheduler.createSchedule", "Create Schedule")]
220
223
  })
221
224
  })]
222
225
  })
@@ -226,6 +229,6 @@ function _() {
226
229
  });
227
230
  }
228
231
  //#endregion
229
- export { _ as SchedulerPage };
232
+ export { y as SchedulerPage };
230
233
 
231
234
  //# sourceMappingURL=SchedulerPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SchedulerPage.js","names":[],"sources":["../../../src/tours/pages/SchedulerPage.tsx"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Calendar, Clock, ArrowLeft, Save } from 'lucide-react';\nimport { PermissionGate } from '@burdenoff/fe-libs/shared/components';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport { useToursContext } from '../providers/ToursProvider';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport type { RecurrencePattern } from '../types';\nimport { useCreateTourScheduleMutation } from '../../generated/global-operations';\nimport { useGetTourSchedulesQuery } from '../../generated/global-operations';\n\n/**\n * Tour scheduler page\n * Configure tour scheduling and recurrence\n */\nexport function SchedulerPage() {\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n },\n [t]\n );\n const { tourId } = useParams();\n const navigate = useNavigate();\n const { basePath = '/' } = useToursContext();\n const { hasPermission } = useToursPermissionAccess();\n const canCreateSchedule = hasPermission(TOUR_PERMISSIONS.TOUR_SCHEDULE_CREATE);\n const canListSchedules = hasPermission(TOUR_PERMISSIONS.TOUR_SCHEDULE_LIST);\n\n const [scheduleData, setScheduleData] = useState({\n startDate: '',\n endDate: '',\n recurrencePattern: 'DAILY' as RecurrencePattern,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n isActive: true,\n });\n\n const [saving, setSaving] = useState(false);\n\n const [createSchedule] = useCreateTourScheduleMutation();\n const { data: schedulesData } = useGetTourSchedulesQuery({\n variables: { tourId: tourId! },\n skip: !tourId || !canListSchedules,\n });\n const existingSchedules = schedulesData?.tourSchedules ?? [];\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!tourId) return;\n setSaving(true);\n try {\n // Convert recurrence pattern to RFC 5545 recurrence rule\n const recurrenceRule =\n scheduleData.recurrencePattern === 'DAILY'\n ? 'FREQ=DAILY'\n : scheduleData.recurrencePattern === 'WEEKLY'\n ? 'FREQ=WEEKLY'\n : scheduleData.recurrencePattern === 'MONTHLY'\n ? 'FREQ=MONTHLY'\n : undefined;\n\n await createSchedule({\n variables: {\n input: {\n tourId,\n startDate: new Date(scheduleData.startDate).toISOString(),\n endDate: scheduleData.endDate\n ? new Date(scheduleData.endDate).toISOString()\n : undefined,\n recurrenceRule,\n timezone: scheduleData.timezone,\n },\n },\n refetchQueries: ['GetTourSchedules'],\n });\n navigate(`${basePath}/${tourId}/edit`);\n } catch (error) {\n console.error('Failed to create schedule:', error);\n } finally {\n setSaving(false);\n }\n };\n\n const handleBack = () => {\n navigate(`${basePath}/${tourId}/edit`);\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-3xl mx-auto\">\n {/* Header */}\n <div className=\"flex items-center gap-4\">\n <button onClick={handleBack} className=\"p-2 hover:bg-accent rounded-md\">\n <ArrowLeft size={20} />\n </button>\n <div>\n <h1 className=\"text-2xl font-bold\">{tr('tourScheduler.title', 'Schedule Tour')}</h1>\n <p className=\"text-sm text-muted-foreground\">\n {tr('tourScheduler.subtitle', 'Configure when this tour should be activated')}\n </p>\n </div>\n </div>\n\n {/* Existing Schedules */}\n {existingSchedules.length > 0 && (\n <div className=\"border border-border rounded-md p-6 bg-card\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {tr('tourScheduler.existingSchedules', 'Existing Schedules')}\n </h2>\n <div className=\"space-y-2\">\n {existingSchedules.map((schedule: (typeof existingSchedules)[number]) => (\n <div\n key={schedule.id}\n className=\"flex items-center justify-between p-3 border border-border rounded-md\"\n >\n <div>\n <div className=\"text-sm font-medium\">\n {new Date(schedule.startDate).toLocaleDateString()}\n {schedule.endDate\n ? ` — ${new Date(schedule.endDate).toLocaleDateString()}`\n : ` — ${tr('tourScheduler.noEndDate', 'No end date')}`}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {schedule.recurrenceRule || tr('tourScheduler.oneTime', 'One-time')} ·{' '}\n {schedule.timezone}\n {schedule.isActive\n ? ` · ${tr('tourScheduler.active', 'Active')}`\n : ` · ${tr('tourScheduler.inactive', 'Inactive')}`}\n </div>\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {tr('tourScheduler.runs', 'Runs')}: {schedule.executionCount}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Form */}\n <form onSubmit={handleSubmit} className=\"space-y-6\">\n {/* Date Range */}\n <div className=\"border border-border rounded-md p-6 bg-card\">\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\n <Calendar size={20} />\n {tr('tourScheduler.sectionDateRange', 'Date Range')}\n </h2>\n\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('tourScheduler.labelStartDate', 'Start Date *')}\n </label>\n <input\n type=\"datetime-local\"\n value={scheduleData.startDate}\n onChange={(e) => setScheduleData({ ...scheduleData, startDate: e.target.value })}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background\"\n required\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('tourScheduler.labelEndDate', 'End Date (Optional)')}\n </label>\n <input\n type=\"datetime-local\"\n value={scheduleData.endDate}\n onChange={(e) => setScheduleData({ ...scheduleData, endDate: e.target.value })}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background\"\n />\n </div>\n </div>\n </div>\n\n {/* Recurrence */}\n <div className=\"border border-border rounded-md p-6 bg-card\">\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\n <Clock size={20} />\n {tr('tourScheduler.sectionRecurrence', 'Recurrence')}\n </h2>\n\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('tourScheduler.labelRecurrencePattern', 'Recurrence Pattern')}\n </label>\n <select\n value={scheduleData.recurrencePattern}\n onChange={(e) =>\n setScheduleData({\n ...scheduleData,\n recurrencePattern: e.target.value as RecurrencePattern,\n })\n }\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background\"\n >\n <option value=\"DAILY\">{tr('tourScheduler.recurrenceDaily', 'Daily')}</option>\n <option value=\"WEEKLY\">{tr('tourScheduler.recurrenceWeekly', 'Weekly')}</option>\n <option value=\"MONTHLY\">{tr('tourScheduler.recurrenceMonthly', 'Monthly')}</option>\n <option value=\"CUSTOM\">{tr('tourScheduler.recurrenceCustom', 'Custom')}</option>\n </select>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('tourScheduler.labelTimezone', 'Timezone')}\n </label>\n <input\n type=\"text\"\n value={scheduleData.timezone}\n onChange={(e) => setScheduleData({ ...scheduleData, timezone: e.target.value })}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background\"\n readOnly\n />\n </div>\n </div>\n </div>\n\n {/* Status */}\n <div className=\"border border-border rounded-md p-6 bg-card\">\n <label className=\"flex items-center gap-3 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={scheduleData.isActive}\n onChange={(e) => setScheduleData({ ...scheduleData, isActive: e.target.checked })}\n className=\"w-5 h-5 rounded\"\n />\n <div>\n <div className=\"font-medium\">{tr('tourScheduler.statusActiveLabel', 'Active')}</div>\n <div className=\"text-sm text-muted-foreground\">\n {tr(\n 'tourScheduler.statusActiveDescription',\n 'Enable this schedule immediately after creation'\n )}\n </div>\n </div>\n </label>\n </div>\n\n {/* Actions */}\n <div className=\"flex gap-3\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"flex-1 px-4 py-2 border border-border rounded-md hover:bg-accent\"\n >\n {tr('tourScheduler.cancel', 'Cancel')}\n </button>\n <PermissionGate permission={TOUR_PERMISSIONS.TOUR_SCHEDULE_CREATE}>\n <button\n type=\"submit\"\n disabled={saving || !canCreateSchedule}\n className=\"flex-1 px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 disabled:opacity-50 flex items-center justify-center gap-2\"\n >\n <Save size={20} />\n {saving\n ? tr('tourScheduler.creating', 'Creating...')\n : tr('tourScheduler.createSchedule', 'Create Schedule')}\n </button>\n </PermissionGate>\n </div>\n </form>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SchedulerPage.js","names":[],"sources":["../../../src/tours/pages/SchedulerPage.tsx"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Calendar, Clock, ArrowLeft, Save } from 'lucide-react';\nimport { PermissionGate } from '@burdenoff/fe-libs/shared/components';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport { useToursContext } from '../providers/ToursProvider';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport type { RecurrencePattern } from '../types';\nimport { emitToursApiFailed } from '../telemetry';\nimport { useCreateTourScheduleMutation } from '../../generated/global-operations';\nimport { useGetTourSchedulesQuery } from '../../generated/global-operations';\n\n/**\n * Tour scheduler page\n * Configure tour scheduling and recurrence\n */\nexport function SchedulerPage() {\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n },\n [t]\n );\n const { tourId } = useParams();\n const navigate = useNavigate();\n const toursContext = useToursContext();\n const { basePath = '/' } = toursContext;\n const eventBus = useEventBus();\n const { hasPermission } = useToursPermissionAccess();\n const canCreateSchedule = hasPermission(TOUR_PERMISSIONS.TOUR_SCHEDULE_CREATE);\n const canListSchedules = hasPermission(TOUR_PERMISSIONS.TOUR_SCHEDULE_LIST);\n\n const [scheduleData, setScheduleData] = useState({\n startDate: '',\n endDate: '',\n recurrencePattern: 'DAILY' as RecurrencePattern,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n isActive: true,\n });\n\n const [saving, setSaving] = useState(false);\n\n const [createSchedule] = useCreateTourScheduleMutation();\n const { data: schedulesData } = useGetTourSchedulesQuery({\n variables: { tourId: tourId! },\n skip: !tourId || !canListSchedules,\n });\n const existingSchedules = schedulesData?.tourSchedules ?? [];\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!tourId) return;\n setSaving(true);\n try {\n // Convert recurrence pattern to RFC 5545 recurrence rule\n const recurrenceRule =\n scheduleData.recurrencePattern === 'DAILY'\n ? 'FREQ=DAILY'\n : scheduleData.recurrencePattern === 'WEEKLY'\n ? 'FREQ=WEEKLY'\n : scheduleData.recurrencePattern === 'MONTHLY'\n ? 'FREQ=MONTHLY'\n : undefined;\n\n await createSchedule({\n variables: {\n input: {\n tourId,\n startDate: new Date(scheduleData.startDate).toISOString(),\n endDate: scheduleData.endDate\n ? new Date(scheduleData.endDate).toISOString()\n : undefined,\n recurrenceRule,\n timezone: scheduleData.timezone,\n },\n },\n refetchQueries: ['GetTourSchedules'],\n });\n navigate(`${basePath}/${tourId}/edit`);\n } catch {\n emitToursApiFailed(eventBus, 'schedule.create', toursContext);\n } finally {\n setSaving(false);\n }\n };\n\n const handleBack = () => {\n navigate(`${basePath}/${tourId}/edit`);\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6 max-w-3xl mx-auto\">\n {/* Header */}\n <div className=\"flex items-center gap-3 sm:gap-4\">\n <button\n onClick={handleBack}\n className=\"p-2 min-h-[44px] min-w-[44px] hover:bg-accent rounded-md\"\n aria-label={tr('tourScheduler.goBack', 'Go back')}\n >\n <ArrowLeft size={20} />\n </button>\n <div>\n <h1 className=\"text-xl sm:text-2xl font-bold\">\n {tr('tourScheduler.title', 'Schedule Tour')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {tr('tourScheduler.subtitle', 'Configure when this tour should be activated')}\n </p>\n </div>\n </div>\n\n {/* Existing Schedules */}\n {existingSchedules.length > 0 && (\n <div className=\"border border-border rounded-md p-4 sm:p-6 bg-card\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {tr('tourScheduler.existingSchedules', 'Existing Schedules')}\n </h2>\n <div className=\"space-y-2\">\n {existingSchedules.map((schedule: (typeof existingSchedules)[number]) => (\n <div\n key={schedule.id}\n className=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between p-3 border border-border rounded-md\"\n >\n <div>\n <div className=\"text-sm font-medium\">\n {new Date(schedule.startDate).toLocaleDateString()}\n {schedule.endDate\n ? ` — ${new Date(schedule.endDate).toLocaleDateString()}`\n : ` — ${tr('tourScheduler.noEndDate', 'No end date')}`}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {schedule.recurrenceRule || tr('tourScheduler.oneTime', 'One-time')} ·{' '}\n {schedule.timezone}\n {schedule.isActive\n ? ` · ${tr('tourScheduler.active', 'Active')}`\n : ` · ${tr('tourScheduler.inactive', 'Inactive')}`}\n </div>\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {tr('tourScheduler.runs', 'Runs')}: {schedule.executionCount}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Form */}\n <form onSubmit={handleSubmit} className=\"space-y-6\">\n {/* Date Range */}\n <div className=\"border border-border rounded-md p-4 sm:p-6 bg-card\">\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\n <Calendar size={20} />\n {tr('tourScheduler.sectionDateRange', 'Date Range')}\n </h2>\n\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('tourScheduler.labelStartDate', 'Start Date *')}\n </label>\n <input\n type=\"datetime-local\"\n value={scheduleData.startDate}\n onChange={(e) => setScheduleData({ ...scheduleData, startDate: e.target.value })}\n className=\"w-full px-3 py-2 min-h-[44px] border border-border rounded-md bg-background\"\n required\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('tourScheduler.labelEndDate', 'End Date (Optional)')}\n </label>\n <input\n type=\"datetime-local\"\n value={scheduleData.endDate}\n onChange={(e) => setScheduleData({ ...scheduleData, endDate: e.target.value })}\n className=\"w-full px-3 py-2 min-h-[44px] border border-border rounded-md bg-background\"\n />\n </div>\n </div>\n </div>\n\n {/* Recurrence */}\n <div className=\"border border-border rounded-md p-4 sm:p-6 bg-card\">\n <h2 className=\"text-lg font-semibold mb-4 flex items-center gap-2\">\n <Clock size={20} />\n {tr('tourScheduler.sectionRecurrence', 'Recurrence')}\n </h2>\n\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('tourScheduler.labelRecurrencePattern', 'Recurrence Pattern')}\n </label>\n <select\n value={scheduleData.recurrencePattern}\n onChange={(e) =>\n setScheduleData({\n ...scheduleData,\n recurrencePattern: e.target.value as RecurrencePattern,\n })\n }\n className=\"w-full px-3 py-2 min-h-[44px] border border-border rounded-md bg-background\"\n >\n <option value=\"DAILY\">{tr('tourScheduler.recurrenceDaily', 'Daily')}</option>\n <option value=\"WEEKLY\">{tr('tourScheduler.recurrenceWeekly', 'Weekly')}</option>\n <option value=\"MONTHLY\">{tr('tourScheduler.recurrenceMonthly', 'Monthly')}</option>\n <option value=\"CUSTOM\">{tr('tourScheduler.recurrenceCustom', 'Custom')}</option>\n </select>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('tourScheduler.labelTimezone', 'Timezone')}\n </label>\n <input\n type=\"text\"\n value={scheduleData.timezone}\n onChange={(e) => setScheduleData({ ...scheduleData, timezone: e.target.value })}\n className=\"w-full px-3 py-2 min-h-[44px] border border-border rounded-md bg-background\"\n readOnly\n />\n </div>\n </div>\n </div>\n\n {/* Status */}\n <div className=\"border border-border rounded-md p-4 sm:p-6 bg-card\">\n <label className=\"flex items-center gap-3 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={scheduleData.isActive}\n onChange={(e) => setScheduleData({ ...scheduleData, isActive: e.target.checked })}\n className=\"w-5 h-5 rounded\"\n />\n <div>\n <div className=\"font-medium\">{tr('tourScheduler.statusActiveLabel', 'Active')}</div>\n <div className=\"text-sm text-muted-foreground\">\n {tr(\n 'tourScheduler.statusActiveDescription',\n 'Enable this schedule immediately after creation'\n )}\n </div>\n </div>\n </label>\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-col sm:flex-row gap-3\">\n <button\n type=\"button\"\n onClick={handleBack}\n className=\"flex-1 px-4 py-2 min-h-[44px] border border-border rounded-md hover:bg-accent\"\n >\n {tr('tourScheduler.cancel', 'Cancel')}\n </button>\n <PermissionGate permission={TOUR_PERMISSIONS.TOUR_SCHEDULE_CREATE}>\n <button\n type=\"submit\"\n disabled={saving || !canCreateSchedule}\n className=\"flex-1 px-4 py-2 min-h-[44px] bg-primary text-primary-foreground rounded-md hover:bg-primary/90 disabled:opacity-50 flex items-center justify-center gap-2\"\n >\n <Save size={20} />\n {saving\n ? tr('tourScheduler.creating', 'Creating...')\n : tr('tourScheduler.createSchedule', 'Create Schedule')}\n </button>\n </PermissionGate>\n </div>\n </form>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"StepEditorPage.d.ts","sourceRoot":"","sources":["../../../src/tours/pages/StepEditorPage.tsx"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,wBAAgB,cAAc,4CA6nB7B"}
1
+ {"version":3,"file":"StepEditorPage.d.ts","sourceRoot":"","sources":["../../../src/tours/pages/StepEditorPage.tsx"],"names":[],"mappings":"AA0BA;;;;GAIG;AACH,wBAAgB,cAAc,4CAkoB7B"}