@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.
- package/dist/index.js +2 -1
- package/dist/tours/ToursAdminRoot.d.ts.map +1 -1
- package/dist/tours/ToursAdminRoot.js +23 -20
- package/dist/tours/ToursAdminRoot.js.map +1 -1
- package/dist/tours/ToursUserRoot.d.ts.map +1 -1
- package/dist/tours/ToursUserRoot.js +25 -22
- package/dist/tours/ToursUserRoot.js.map +1 -1
- package/dist/tours/hooks/useMediaLibrary.js +3 -3
- package/dist/tours/hooks/useTourBuilder.js +10 -10
- package/dist/tours/hooks/useTourLifecycle.js +3 -3
- package/dist/tours/i18n.d.ts +5 -1
- package/dist/tours/i18n.d.ts.map +1 -1
- package/dist/tours/i18n.js +4 -0
- package/dist/tours/i18n.js.map +1 -1
- package/dist/tours/index.d.ts +1 -0
- package/dist/tours/index.d.ts.map +1 -1
- package/dist/tours/index.js +1 -0
- package/dist/tours/pages/AnalyticsDashboardPage.d.ts.map +1 -1
- package/dist/tours/pages/AnalyticsDashboardPage.js +5 -5
- package/dist/tours/pages/AnalyticsDashboardPage.js.map +1 -1
- package/dist/tours/pages/MediaLibraryPage.d.ts.map +1 -1
- package/dist/tours/pages/MediaLibraryPage.js +97 -96
- package/dist/tours/pages/MediaLibraryPage.js.map +1 -1
- package/dist/tours/pages/SchedulerPage.d.ts.map +1 -1
- package/dist/tours/pages/SchedulerPage.js +129 -126
- package/dist/tours/pages/SchedulerPage.js.map +1 -1
- package/dist/tours/pages/StepEditorPage.d.ts.map +1 -1
- package/dist/tours/pages/StepEditorPage.js +133 -128
- package/dist/tours/pages/StepEditorPage.js.map +1 -1
- package/dist/tours/pages/SystemAnalyticsPage.d.ts.map +1 -1
- package/dist/tours/pages/SystemAnalyticsPage.js +3 -3
- package/dist/tours/pages/SystemAnalyticsPage.js.map +1 -1
- package/dist/tours/pages/TemplateLibraryPage.d.ts.map +1 -1
- package/dist/tours/pages/TemplateLibraryPage.js +97 -94
- package/dist/tours/pages/TemplateLibraryPage.js.map +1 -1
- package/dist/tours/pages/TourBuilderPage.d.ts.map +1 -1
- package/dist/tours/pages/TourBuilderPage.js +232 -230
- package/dist/tours/pages/TourBuilderPage.js.map +1 -1
- package/dist/tours/pages/TourPreviewPage.d.ts.map +1 -1
- package/dist/tours/pages/TourPreviewPage.js +20 -18
- package/dist/tours/pages/TourPreviewPage.js.map +1 -1
- package/dist/tours/pages/ToursListPage.js +14 -14
- package/dist/tours/pages/ToursListPage.js.map +1 -1
- package/dist/tours/store/toursStore.d.ts +1 -0
- package/dist/tours/store/toursStore.d.ts.map +1 -1
- package/dist/tours/store/toursStore.js +14 -0
- package/dist/tours/store/toursStore.js.map +1 -1
- package/dist/tours/telemetry.d.ts +9 -0
- package/dist/tours/telemetry.d.ts.map +1 -0
- package/dist/tours/telemetry.js +19 -0
- package/dist/tours/telemetry.js.map +1 -0
- 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 {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
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:
|
|
14
|
-
let n =
|
|
14
|
+
function y() {
|
|
15
|
+
let { t: y } = _(), b = o((e, t) => {
|
|
16
|
+
let n = y(e);
|
|
15
17
|
return n === e ? t : n;
|
|
16
|
-
}, [
|
|
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
|
-
}), [
|
|
23
|
-
variables: { tourId:
|
|
24
|
-
skip: !
|
|
25
|
-
}),
|
|
26
|
-
if (e.preventDefault(),
|
|
27
|
-
|
|
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 =
|
|
30
|
-
await
|
|
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:
|
|
33
|
-
startDate: new Date(
|
|
34
|
-
endDate:
|
|
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:
|
|
38
|
+
timezone: k.timezone
|
|
37
39
|
} },
|
|
38
40
|
refetchQueries: ["GetTourSchedules"]
|
|
39
|
-
}),
|
|
40
|
-
} catch
|
|
41
|
-
|
|
41
|
+
}), S(`${w}/${x}/edit`);
|
|
42
|
+
} catch {
|
|
43
|
+
a(T, "schedule.create", C);
|
|
42
44
|
} finally {
|
|
43
|
-
|
|
45
|
+
M(!1);
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
+
}, L = () => {
|
|
49
|
+
S(`${w}/${x}/edit`);
|
|
48
50
|
};
|
|
49
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
53
|
-
className: "flex items-center gap-4",
|
|
54
|
-
children: [/* @__PURE__ */
|
|
55
|
-
onClick:
|
|
56
|
-
className: "p-2 hover:bg-accent rounded-md",
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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:
|
|
66
|
+
children: b("tourScheduler.subtitle", "Configure when this tour should be activated")
|
|
64
67
|
})] })]
|
|
65
68
|
}),
|
|
66
|
-
|
|
67
|
-
className: "border border-border rounded-md p-6 bg-card",
|
|
68
|
-
children: [/* @__PURE__ */
|
|
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:
|
|
71
|
-
}), /* @__PURE__ */
|
|
73
|
+
children: b("tourScheduler.existingSchedules", "Existing Schedules")
|
|
74
|
+
}), /* @__PURE__ */ p("div", {
|
|
72
75
|
className: "space-y-2",
|
|
73
|
-
children:
|
|
74
|
-
className: "flex items-center justify-between p-3 border border-border rounded-md",
|
|
75
|
-
children: [/* @__PURE__ */
|
|
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()}` : ` — ${
|
|
78
|
-
}), /* @__PURE__ */
|
|
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 ||
|
|
84
|
+
e.recurrenceRule || b("tourScheduler.oneTime", "One-time"),
|
|
82
85
|
" ·",
|
|
83
86
|
" ",
|
|
84
87
|
e.timezone,
|
|
85
|
-
e.isActive ? ` · ${
|
|
88
|
+
e.isActive ? ` · ${b("tourScheduler.active", "Active")}` : ` · ${b("tourScheduler.inactive", "Inactive")}`
|
|
86
89
|
]
|
|
87
|
-
})] }), /* @__PURE__ */
|
|
90
|
+
})] }), /* @__PURE__ */ m("div", {
|
|
88
91
|
className: "text-xs text-muted-foreground",
|
|
89
92
|
children: [
|
|
90
|
-
|
|
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__ */
|
|
99
|
-
onSubmit:
|
|
101
|
+
/* @__PURE__ */ m("form", {
|
|
102
|
+
onSubmit: I,
|
|
100
103
|
className: "space-y-6",
|
|
101
104
|
children: [
|
|
102
|
-
/* @__PURE__ */
|
|
103
|
-
className: "border border-border rounded-md p-6 bg-card",
|
|
104
|
-
children: [/* @__PURE__ */
|
|
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__ */
|
|
107
|
-
}), /* @__PURE__ */
|
|
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__ */
|
|
112
|
+
children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
|
|
110
113
|
className: "block text-sm font-medium mb-2",
|
|
111
|
-
children:
|
|
112
|
-
}), /* @__PURE__ */
|
|
114
|
+
children: b("tourScheduler.labelStartDate", "Start Date *")
|
|
115
|
+
}), /* @__PURE__ */ p("input", {
|
|
113
116
|
type: "datetime-local",
|
|
114
|
-
value:
|
|
115
|
-
onChange: (e) =>
|
|
116
|
-
...
|
|
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__ */
|
|
124
|
+
})] }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
|
|
122
125
|
className: "block text-sm font-medium mb-2",
|
|
123
|
-
children:
|
|
124
|
-
}), /* @__PURE__ */
|
|
126
|
+
children: b("tourScheduler.labelEndDate", "End Date (Optional)")
|
|
127
|
+
}), /* @__PURE__ */ p("input", {
|
|
125
128
|
type: "datetime-local",
|
|
126
|
-
value:
|
|
127
|
-
onChange: (e) =>
|
|
128
|
-
...
|
|
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__ */
|
|
136
|
-
className: "border border-border rounded-md p-6 bg-card",
|
|
137
|
-
children: [/* @__PURE__ */
|
|
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__ */
|
|
140
|
-
}), /* @__PURE__ */
|
|
142
|
+
children: [/* @__PURE__ */ p(d, { size: 20 }), b("tourScheduler.sectionRecurrence", "Recurrence")]
|
|
143
|
+
}), /* @__PURE__ */ m("div", {
|
|
141
144
|
className: "space-y-4",
|
|
142
|
-
children: [/* @__PURE__ */
|
|
145
|
+
children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
|
|
143
146
|
className: "block text-sm font-medium mb-2",
|
|
144
|
-
children:
|
|
145
|
-
}), /* @__PURE__ */
|
|
146
|
-
value:
|
|
147
|
-
onChange: (e) =>
|
|
148
|
-
...
|
|
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__ */
|
|
156
|
+
/* @__PURE__ */ p("option", {
|
|
154
157
|
value: "DAILY",
|
|
155
|
-
children:
|
|
158
|
+
children: b("tourScheduler.recurrenceDaily", "Daily")
|
|
156
159
|
}),
|
|
157
|
-
/* @__PURE__ */
|
|
160
|
+
/* @__PURE__ */ p("option", {
|
|
158
161
|
value: "WEEKLY",
|
|
159
|
-
children:
|
|
162
|
+
children: b("tourScheduler.recurrenceWeekly", "Weekly")
|
|
160
163
|
}),
|
|
161
|
-
/* @__PURE__ */
|
|
164
|
+
/* @__PURE__ */ p("option", {
|
|
162
165
|
value: "MONTHLY",
|
|
163
|
-
children:
|
|
166
|
+
children: b("tourScheduler.recurrenceMonthly", "Monthly")
|
|
164
167
|
}),
|
|
165
|
-
/* @__PURE__ */
|
|
168
|
+
/* @__PURE__ */ p("option", {
|
|
166
169
|
value: "CUSTOM",
|
|
167
|
-
children:
|
|
170
|
+
children: b("tourScheduler.recurrenceCustom", "Custom")
|
|
168
171
|
})
|
|
169
172
|
]
|
|
170
|
-
})] }), /* @__PURE__ */
|
|
173
|
+
})] }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
|
|
171
174
|
className: "block text-sm font-medium mb-2",
|
|
172
|
-
children:
|
|
173
|
-
}), /* @__PURE__ */
|
|
175
|
+
children: b("tourScheduler.labelTimezone", "Timezone")
|
|
176
|
+
}), /* @__PURE__ */ p("input", {
|
|
174
177
|
type: "text",
|
|
175
|
-
value:
|
|
176
|
-
onChange: (e) =>
|
|
177
|
-
...
|
|
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__ */
|
|
186
|
-
className: "border border-border rounded-md p-6 bg-card",
|
|
187
|
-
children: /* @__PURE__ */
|
|
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__ */
|
|
192
|
+
children: [/* @__PURE__ */ p("input", {
|
|
190
193
|
type: "checkbox",
|
|
191
|
-
checked:
|
|
192
|
-
onChange: (e) =>
|
|
193
|
-
...
|
|
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__ */
|
|
200
|
+
}), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("div", {
|
|
198
201
|
className: "font-medium",
|
|
199
|
-
children:
|
|
200
|
-
}), /* @__PURE__ */
|
|
202
|
+
children: b("tourScheduler.statusActiveLabel", "Active")
|
|
203
|
+
}), /* @__PURE__ */ p("div", {
|
|
201
204
|
className: "text-sm text-muted-foreground",
|
|
202
|
-
children:
|
|
205
|
+
children: b("tourScheduler.statusActiveDescription", "Enable this schedule immediately after creation")
|
|
203
206
|
})] })]
|
|
204
207
|
})
|
|
205
208
|
}),
|
|
206
|
-
/* @__PURE__ */
|
|
207
|
-
className: "flex gap-3",
|
|
208
|
-
children: [/* @__PURE__ */
|
|
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:
|
|
211
|
-
className: "flex-1 px-4 py-2 border border-border rounded-md hover:bg-accent",
|
|
212
|
-
children:
|
|
213
|
-
}), /* @__PURE__ */
|
|
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__ */
|
|
218
|
+
children: /* @__PURE__ */ m("button", {
|
|
216
219
|
type: "submit",
|
|
217
|
-
disabled:
|
|
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
|
|
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 {
|
|
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":"
|
|
1
|
+
{"version":3,"file":"StepEditorPage.d.ts","sourceRoot":"","sources":["../../../src/tours/pages/StepEditorPage.tsx"],"names":[],"mappings":"AA0BA;;;;GAIG;AACH,wBAAgB,cAAc,4CAkoB7B"}
|