@burdenoff/microfe-tours 2026.625.1 → 2026.626.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/tours/i18n.js +19 -1
- package/dist/tours/i18n.js.map +1 -1
- package/dist/tours/pages/AnalyticsDashboardPage.js +43 -41
- package/dist/tours/pages/AnalyticsDashboardPage.js.map +1 -1
- package/dist/tours/pages/MediaLibraryPage.js +66 -59
- package/dist/tours/pages/MediaLibraryPage.js.map +1 -1
- package/dist/tours/pages/MyToursPage.js +76 -57
- package/dist/tours/pages/MyToursPage.js.map +1 -1
- package/dist/tours/pages/MyToursProgressPage.js +81 -74
- package/dist/tours/pages/MyToursProgressPage.js.map +1 -1
- package/dist/tours/pages/SchedulerPage.js +78 -78
- package/dist/tours/pages/SchedulerPage.js.map +1 -1
- package/dist/tours/pages/StepEditorPage.js +570 -575
- package/dist/tours/pages/StepEditorPage.js.map +1 -1
- package/dist/tours/pages/SystemAnalyticsPage.js +128 -118
- package/dist/tours/pages/SystemAnalyticsPage.js.map +1 -1
- package/dist/tours/pages/TemplateLibraryPage.js +54 -65
- package/dist/tours/pages/TemplateLibraryPage.js.map +1 -1
- package/dist/tours/pages/TourBuilderPage.js +307 -272
- package/dist/tours/pages/TourBuilderPage.js.map +1 -1
- package/dist/tours/pages/TourPreviewPage.js +114 -122
- package/dist/tours/pages/TourPreviewPage.js.map +1 -1
- package/dist/tours/pages/ToursListPage.js +130 -122
- package/dist/tours/pages/ToursListPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -12,96 +12,100 @@ import { PermissionGate as h } from "@burdenoff/fe-libs/shared/components";
|
|
|
12
12
|
import { Eye as g, Grid as _, List as v, ListOrdered as y, Plus as b, Search as x, Settings as S } from "lucide-react";
|
|
13
13
|
import { jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
14
14
|
import { useNavigate as T } from "react-router-dom";
|
|
15
|
-
import {
|
|
15
|
+
import { AuroraBackground as E, Button as D, CTAOverflowMenu as O, GlassCard as k, GradientText as A, IllustratedEmptyState as j, PagePurpose as ee } from "@burdenoff/fe-libs/ui";
|
|
16
16
|
//#region src/tours/pages/ToursListPage.tsx
|
|
17
|
-
function
|
|
18
|
-
let { tr:
|
|
17
|
+
function M() {
|
|
18
|
+
let { tr: M } = s(), N = T(), { basePath: P = "/" } = e(), { viewMode: F, tourFilter: I, toursListRevision: L, setViewMode: R, updateTourFilter: z, notifyToursListChanged: B } = t(), { hasPermission: V, isLoading: H } = a(), U = V(o.TOUR_UPDATE), W = V(o.TOUR_STEP_UPDATE), G = V(o.TOUR_READ), K = V(o.TOUR_DELETE), q = V(o.TOUR_PUBLISH), J = V(o.TOUR_ARCHIVE), Y = V(o.TOUR_DUPLICATE), { tours: X, loading: te, fetchTours: Z } = r(), { publishTour: Q, unpublishTour: ne, archiveTour: re, duplicateTour: ie } = i(), [ae] = n(), [oe, se] = m(""), [ce, le] = m("all");
|
|
19
19
|
p(() => {
|
|
20
|
-
|
|
20
|
+
H || Z({ ...I });
|
|
21
21
|
}, [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
Z,
|
|
23
|
+
I,
|
|
24
|
+
L,
|
|
25
|
+
H
|
|
26
26
|
]);
|
|
27
|
-
let
|
|
28
|
-
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
},
|
|
27
|
+
let ue = (e) => {
|
|
28
|
+
se(e), z({ search: e });
|
|
29
|
+
}, de = (e) => {
|
|
30
|
+
le(e), z({ status: e });
|
|
31
|
+
}, $ = () => {
|
|
32
|
+
N(P.endsWith("/") ? `${P}new` : `${P}/new`);
|
|
33
|
+
}, fe = (e) => {
|
|
34
34
|
switch (e) {
|
|
35
|
-
case "DRAFT": return
|
|
36
|
-
case "PUBLISHED": return
|
|
37
|
-
case "ARCHIVED": return
|
|
38
|
-
case "SCHEDULED": return
|
|
35
|
+
case "DRAFT": return M("toursList.statusDraft");
|
|
36
|
+
case "PUBLISHED": return M("toursList.statusPublished");
|
|
37
|
+
case "ARCHIVED": return M("toursList.statusArchived");
|
|
38
|
+
case "SCHEDULED": return M("toursList.statusScheduled");
|
|
39
39
|
}
|
|
40
|
-
},
|
|
40
|
+
}, pe = async (e) => {
|
|
41
41
|
u("light");
|
|
42
42
|
try {
|
|
43
|
-
await
|
|
43
|
+
await Q(e), d("success");
|
|
44
44
|
} catch {
|
|
45
|
-
d("error"), c() ? f(
|
|
45
|
+
d("error"), c() ? f(M("toursList.errorPublish")) : alert(M("toursList.errorPublish"));
|
|
46
46
|
}
|
|
47
|
-
},
|
|
47
|
+
}, me = async (e) => {
|
|
48
48
|
u("light");
|
|
49
49
|
try {
|
|
50
|
-
await
|
|
50
|
+
await ne(e), d("success");
|
|
51
51
|
} catch {
|
|
52
|
-
d("error"), c() ? f(
|
|
52
|
+
d("error"), c() ? f(M("toursList.errorUnpublish")) : alert(M("toursList.errorUnpublish"));
|
|
53
53
|
}
|
|
54
|
-
},
|
|
54
|
+
}, he = async (e) => {
|
|
55
55
|
u("light");
|
|
56
56
|
try {
|
|
57
|
-
await
|
|
57
|
+
await re(e), d("success");
|
|
58
58
|
} catch {
|
|
59
|
-
d("error"), c() ? f(
|
|
59
|
+
d("error"), c() ? f(M("toursList.errorArchive")) : alert(M("toursList.errorArchive"));
|
|
60
60
|
}
|
|
61
|
-
},
|
|
61
|
+
}, ge = async (e) => {
|
|
62
62
|
u("light");
|
|
63
63
|
try {
|
|
64
|
-
await
|
|
64
|
+
await ie(e), d("success");
|
|
65
65
|
} catch {
|
|
66
|
-
d("error"), c() ? f(
|
|
66
|
+
d("error"), c() ? f(M("toursList.errorDuplicate")) : alert(M("toursList.errorDuplicate"));
|
|
67
67
|
}
|
|
68
|
-
},
|
|
68
|
+
}, _e = async (e) => {
|
|
69
69
|
u("medium");
|
|
70
|
-
let t =
|
|
71
|
-
title:
|
|
70
|
+
let t = M("toursList.confirmDelete"), n = await l({
|
|
71
|
+
title: M("toursList.actionDelete"),
|
|
72
72
|
message: t,
|
|
73
|
-
okButtonTitle:
|
|
73
|
+
okButtonTitle: M("toursList.actionDelete")
|
|
74
74
|
});
|
|
75
75
|
if (n === null ? window.confirm(t) : n) try {
|
|
76
|
-
await
|
|
76
|
+
await ae({ variables: { id: e } }), B(), d("success");
|
|
77
77
|
} catch {
|
|
78
|
-
d("error"), c() ? f(
|
|
78
|
+
d("error"), c() ? f(M("toursList.errorDelete")) : alert(M("toursList.errorDelete"));
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
81
|
return /* @__PURE__ */ w("div", {
|
|
82
82
|
className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
|
|
83
83
|
children: [
|
|
84
84
|
/* @__PURE__ */ w("div", {
|
|
85
|
-
className: "
|
|
86
|
-
children: [/* @__PURE__ */ w("div", {
|
|
87
|
-
className: "flex-1
|
|
88
|
-
children: [/* @__PURE__ */
|
|
89
|
-
className: "
|
|
90
|
-
children:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
className: "relative overflow-hidden rounded-xl",
|
|
86
|
+
children: [/* @__PURE__ */ C(E, { intensity: "subtle" }), /* @__PURE__ */ w("div", {
|
|
87
|
+
className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 p-1 sm:p-2",
|
|
88
|
+
children: [/* @__PURE__ */ w("div", {
|
|
89
|
+
className: "flex-1 min-w-0",
|
|
90
|
+
children: [/* @__PURE__ */ C("h1", {
|
|
91
|
+
className: "text-xl sm:text-2xl font-bold text-text-primary",
|
|
92
|
+
children: /* @__PURE__ */ C(A, { children: M("toursList.title") })
|
|
93
|
+
}), /* @__PURE__ */ C("p", {
|
|
94
|
+
className: "text-sm sm:text-base text-text-secondary",
|
|
95
|
+
children: M("toursList.subtitle")
|
|
96
|
+
})]
|
|
97
|
+
}), /* @__PURE__ */ C(h, {
|
|
98
|
+
permission: o.TOUR_CREATE,
|
|
99
|
+
children: /* @__PURE__ */ w(D, {
|
|
100
|
+
type: "button",
|
|
101
|
+
onClick: $,
|
|
102
|
+
className: "w-full sm:w-auto min-h-[44px]",
|
|
103
|
+
children: [/* @__PURE__ */ C(b, { size: 20 }), M("toursList.createTour")]
|
|
104
|
+
})
|
|
94
105
|
})]
|
|
95
|
-
}), /* @__PURE__ */ C(h, {
|
|
96
|
-
permission: o.TOUR_CREATE,
|
|
97
|
-
children: /* @__PURE__ */ w(E, {
|
|
98
|
-
type: "button",
|
|
99
|
-
onClick: se,
|
|
100
|
-
className: "w-full sm:w-auto min-h-[44px]",
|
|
101
|
-
children: [/* @__PURE__ */ C(b, { size: 20 }), k("toursList.createTour")]
|
|
102
|
-
})
|
|
103
106
|
})]
|
|
104
107
|
}),
|
|
108
|
+
/* @__PURE__ */ C(ee, { children: M("toursList.purpose") }),
|
|
105
109
|
/* @__PURE__ */ w("div", {
|
|
106
110
|
className: "flex flex-col sm:flex-row gap-3 sm:gap-4",
|
|
107
111
|
children: [/* @__PURE__ */ w("div", {
|
|
@@ -111,88 +115,88 @@ function k() {
|
|
|
111
115
|
size: 20
|
|
112
116
|
}), /* @__PURE__ */ C("input", {
|
|
113
117
|
type: "text",
|
|
114
|
-
placeholder:
|
|
115
|
-
value:
|
|
116
|
-
onChange: (e) =>
|
|
118
|
+
placeholder: M("toursList.searchPlaceholder"),
|
|
119
|
+
value: oe,
|
|
120
|
+
onChange: (e) => ue(e.target.value),
|
|
117
121
|
className: "w-full pl-[3.25rem] pr-4 py-2 min-h-[44px] border border-border-subtle rounded-md bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
118
|
-
"aria-label":
|
|
122
|
+
"aria-label": M("toursList.searchPlaceholder")
|
|
119
123
|
})]
|
|
120
124
|
}), /* @__PURE__ */ w("div", {
|
|
121
125
|
className: "flex gap-2",
|
|
122
126
|
children: [/* @__PURE__ */ w("select", {
|
|
123
|
-
value:
|
|
124
|
-
onChange: (e) =>
|
|
127
|
+
value: ce,
|
|
128
|
+
onChange: (e) => de(e.target.value),
|
|
125
129
|
className: "px-4 py-2 min-h-[44px] border border-border-subtle rounded-md bg-bg-surface text-text-primary",
|
|
126
|
-
"aria-label":
|
|
130
|
+
"aria-label": M("toursList.statusAll"),
|
|
127
131
|
children: [
|
|
128
132
|
/* @__PURE__ */ C("option", {
|
|
129
133
|
value: "all",
|
|
130
|
-
children:
|
|
134
|
+
children: M("toursList.statusAll")
|
|
131
135
|
}),
|
|
132
136
|
/* @__PURE__ */ C("option", {
|
|
133
137
|
value: "DRAFT",
|
|
134
|
-
children:
|
|
138
|
+
children: M("toursList.statusDraft")
|
|
135
139
|
}),
|
|
136
140
|
/* @__PURE__ */ C("option", {
|
|
137
141
|
value: "PUBLISHED",
|
|
138
|
-
children:
|
|
142
|
+
children: M("toursList.statusPublished")
|
|
139
143
|
}),
|
|
140
144
|
/* @__PURE__ */ C("option", {
|
|
141
145
|
value: "ARCHIVED",
|
|
142
|
-
children:
|
|
146
|
+
children: M("toursList.statusArchived")
|
|
143
147
|
}),
|
|
144
148
|
/* @__PURE__ */ C("option", {
|
|
145
149
|
value: "SCHEDULED",
|
|
146
|
-
children:
|
|
150
|
+
children: M("toursList.statusScheduled")
|
|
147
151
|
})
|
|
148
152
|
]
|
|
149
153
|
}), /* @__PURE__ */ w("div", {
|
|
150
154
|
className: "flex border border-border-subtle rounded-md overflow-hidden",
|
|
151
155
|
children: [/* @__PURE__ */ C("button", {
|
|
152
156
|
type: "button",
|
|
153
|
-
onClick: () =>
|
|
154
|
-
className: `px-3 py-2 min-h-[44px] ${
|
|
155
|
-
"aria-label":
|
|
156
|
-
title:
|
|
157
|
+
onClick: () => R("grid"),
|
|
158
|
+
className: `px-3 py-2 min-h-[44px] ${F === "grid" ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-surface text-text-primary hover:bg-accent"}`,
|
|
159
|
+
"aria-label": M("toursList.gridView"),
|
|
160
|
+
title: M("toursList.gridView"),
|
|
157
161
|
children: /* @__PURE__ */ C(_, { size: 20 })
|
|
158
162
|
}), /* @__PURE__ */ C("button", {
|
|
159
163
|
type: "button",
|
|
160
|
-
onClick: () =>
|
|
161
|
-
className: `px-3 py-2 min-h-[44px] ${
|
|
162
|
-
"aria-label":
|
|
163
|
-
title:
|
|
164
|
+
onClick: () => R("list"),
|
|
165
|
+
className: `px-3 py-2 min-h-[44px] ${F === "list" ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-surface text-text-primary hover:bg-accent"}`,
|
|
166
|
+
"aria-label": M("toursList.listView"),
|
|
167
|
+
title: M("toursList.listView"),
|
|
164
168
|
children: /* @__PURE__ */ C(v, { size: 20 })
|
|
165
169
|
})]
|
|
166
170
|
})]
|
|
167
171
|
})]
|
|
168
172
|
}),
|
|
169
|
-
|
|
173
|
+
te ? /* @__PURE__ */ C("div", {
|
|
170
174
|
className: "text-center py-12",
|
|
171
175
|
children: /* @__PURE__ */ C("p", {
|
|
172
176
|
className: "text-sm sm:text-base text-text-secondary",
|
|
173
|
-
children:
|
|
177
|
+
children: M("toursList.loading")
|
|
174
178
|
})
|
|
175
|
-
}) :
|
|
176
|
-
className:
|
|
177
|
-
children:
|
|
178
|
-
let t = e.status, n = t === "DRAFT" &&
|
|
179
|
+
}) : X.length > 0 ? /* @__PURE__ */ C("div", {
|
|
180
|
+
className: F === "grid" ? "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4" : "space-y-3",
|
|
181
|
+
children: X.map((e) => {
|
|
182
|
+
let t = e.status, n = t === "DRAFT" && q, r = t === "PUBLISHED" && q, i = t !== "ARCHIVED" && J, a = [];
|
|
179
183
|
return n && a.push({
|
|
180
|
-
label:
|
|
181
|
-
onSelect: () => void
|
|
184
|
+
label: M("toursList.actionPublish"),
|
|
185
|
+
onSelect: () => void pe(e.id)
|
|
182
186
|
}), r && a.push({
|
|
183
|
-
label:
|
|
184
|
-
onSelect: () => void
|
|
185
|
-
}),
|
|
186
|
-
label:
|
|
187
|
-
onSelect: () => void
|
|
187
|
+
label: M("toursList.actionUnpublish"),
|
|
188
|
+
onSelect: () => void me(e.id)
|
|
189
|
+
}), Y && a.push({
|
|
190
|
+
label: M("toursList.actionDuplicate"),
|
|
191
|
+
onSelect: () => void ge(e.id)
|
|
188
192
|
}), i && a.push({
|
|
189
|
-
label:
|
|
190
|
-
onSelect: () => void
|
|
191
|
-
}),
|
|
192
|
-
label:
|
|
193
|
-
onSelect: () => void
|
|
193
|
+
label: M("toursList.actionArchive"),
|
|
194
|
+
onSelect: () => void he(e.id)
|
|
195
|
+
}), K && a.push({
|
|
196
|
+
label: M("toursList.actionDelete"),
|
|
197
|
+
onSelect: () => void _e(e.id),
|
|
194
198
|
intent: "destructive"
|
|
195
|
-
}), /* @__PURE__ */ w(
|
|
199
|
+
}), /* @__PURE__ */ w(k, {
|
|
196
200
|
treatment: "plain",
|
|
197
201
|
className: "p-4 border-border-seam shadow-[var(--shadow-pop)]",
|
|
198
202
|
children: [
|
|
@@ -200,15 +204,15 @@ function k() {
|
|
|
200
204
|
className: "flex items-start justify-between mb-2",
|
|
201
205
|
children: [/* @__PURE__ */ C("h3", {
|
|
202
206
|
className: "font-semibold text-text-primary",
|
|
203
|
-
children:
|
|
207
|
+
children: U ? /* @__PURE__ */ C("button", {
|
|
204
208
|
type: "button",
|
|
205
209
|
className: "cursor-pointer hover:text-primary bg-transparent border-0 p-0 text-left font-inherit",
|
|
206
|
-
onClick: () =>
|
|
210
|
+
onClick: () => N(`${P}/${e.id}/edit`),
|
|
207
211
|
children: e.name
|
|
208
212
|
}) : e.name
|
|
209
213
|
}), /* @__PURE__ */ C("span", {
|
|
210
|
-
className: `px-2 py-1 text-xs rounded-full ${e.status === "PUBLISHED" ? "bg-success/10 text-success" : e.status === "DRAFT" ? "bg-bg-sunken text-text-secondary" : "bg-warning/10 text-warning"}`,
|
|
211
|
-
children:
|
|
214
|
+
className: `px-2 py-1 text-xs rounded-full ${e.status === "PUBLISHED" ? "bg-success/10 text-success motion-safe:animate-vc-glow-pulse" : e.status === "DRAFT" ? "bg-bg-sunken text-text-secondary" : "bg-warning/10 text-warning"}`,
|
|
215
|
+
children: fe(t)
|
|
212
216
|
})]
|
|
213
217
|
}),
|
|
214
218
|
e.description && /* @__PURE__ */ C("p", {
|
|
@@ -220,64 +224,68 @@ function k() {
|
|
|
220
224
|
children: [/* @__PURE__ */ w("span", { children: [
|
|
221
225
|
e.steps?.length || 0,
|
|
222
226
|
" ",
|
|
223
|
-
|
|
227
|
+
M("toursList.steps")
|
|
224
228
|
] }), /* @__PURE__ */ w("span", { children: [
|
|
225
229
|
e.viewCount,
|
|
226
230
|
" ",
|
|
227
|
-
|
|
231
|
+
M("toursList.views")
|
|
228
232
|
] })]
|
|
229
233
|
}),
|
|
230
234
|
/* @__PURE__ */ w("div", {
|
|
231
235
|
className: "flex flex-wrap items-center gap-2 pt-3 border-t border-border-seam",
|
|
232
236
|
children: [
|
|
233
|
-
|
|
237
|
+
W && /* @__PURE__ */ w("button", {
|
|
234
238
|
type: "button",
|
|
235
239
|
onClick: (t) => {
|
|
236
|
-
t.stopPropagation(),
|
|
240
|
+
t.stopPropagation(), N(`${P}/${e.id}/steps`);
|
|
237
241
|
},
|
|
238
242
|
className: "flex-1 min-w-[6.5rem] px-3 py-2 min-h-[44px] text-xs bg-secondary text-secondary-foreground rounded hover:bg-secondary/80 flex items-center justify-center gap-1.5",
|
|
239
|
-
title:
|
|
240
|
-
children: [/* @__PURE__ */ C(y, { size: 14 }),
|
|
243
|
+
title: M("toursList.editStepsTitle"),
|
|
244
|
+
children: [/* @__PURE__ */ C(y, { size: 14 }), M("toursList.stepsButton")]
|
|
241
245
|
}),
|
|
242
|
-
|
|
246
|
+
G && /* @__PURE__ */ w("button", {
|
|
243
247
|
type: "button",
|
|
244
248
|
onClick: (t) => {
|
|
245
|
-
t.stopPropagation(),
|
|
249
|
+
t.stopPropagation(), N(`${P}/${e.id}/preview`);
|
|
246
250
|
},
|
|
247
251
|
className: "flex-1 min-w-[6.5rem] px-3 py-2 min-h-[44px] text-xs border border-border-seam rounded hover:bg-accent flex items-center justify-center gap-1.5",
|
|
248
|
-
title:
|
|
249
|
-
children: [/* @__PURE__ */ C(g, { size: 14 }),
|
|
252
|
+
title: M("toursList.previewTitle"),
|
|
253
|
+
children: [/* @__PURE__ */ C(g, { size: 14 }), M("toursList.previewButton")]
|
|
250
254
|
}),
|
|
251
|
-
|
|
255
|
+
U && /* @__PURE__ */ C("button", {
|
|
252
256
|
type: "button",
|
|
253
257
|
onClick: (t) => {
|
|
254
|
-
t.stopPropagation(),
|
|
258
|
+
t.stopPropagation(), N(`${P}/${e.id}/edit`);
|
|
255
259
|
},
|
|
256
260
|
className: "p-2 min-h-[44px] min-w-[44px] text-xs border border-border-seam rounded hover:bg-accent",
|
|
257
|
-
title:
|
|
258
|
-
"aria-label":
|
|
261
|
+
title: M("toursList.settingsTitle"),
|
|
262
|
+
"aria-label": M("toursList.settingsTitle"),
|
|
259
263
|
children: /* @__PURE__ */ C(S, { size: 14 })
|
|
260
264
|
}),
|
|
261
|
-
a.length > 0 && /* @__PURE__ */ C(
|
|
265
|
+
a.length > 0 && /* @__PURE__ */ C(O, { actions: a })
|
|
262
266
|
]
|
|
263
267
|
})
|
|
264
268
|
]
|
|
265
269
|
}, e.id);
|
|
266
270
|
})
|
|
267
|
-
}) : /* @__PURE__ */
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
271
|
+
}) : /* @__PURE__ */ C(j, {
|
|
272
|
+
illustration: "onboarding",
|
|
273
|
+
title: M("toursList.emptyTitle"),
|
|
274
|
+
description: M("toursList.emptySubtitle"),
|
|
275
|
+
action: /* @__PURE__ */ C(h, {
|
|
276
|
+
permission: o.TOUR_CREATE,
|
|
277
|
+
children: /* @__PURE__ */ w(D, {
|
|
278
|
+
type: "button",
|
|
279
|
+
onClick: $,
|
|
280
|
+
className: "min-h-[44px]",
|
|
281
|
+
children: [/* @__PURE__ */ C(b, { size: 20 }), M("toursList.createTour")]
|
|
282
|
+
})
|
|
283
|
+
})
|
|
276
284
|
})
|
|
277
285
|
]
|
|
278
286
|
});
|
|
279
287
|
}
|
|
280
288
|
//#endregion
|
|
281
|
-
export {
|
|
289
|
+
export { M as ToursListPage };
|
|
282
290
|
|
|
283
291
|
//# sourceMappingURL=ToursListPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToursListPage.js","names":[],"sources":["../../../src/tours/pages/ToursListPage.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Plus, Search, Grid, List as ListIcon, ListOrdered, Eye, Settings } from 'lucide-react';\nimport { PermissionGate } from '@burdenoff/fe-libs/shared/components';\nimport { Button, GlassCard, CTAOverflowMenu, type CTAAction } from '@burdenoff/fe-libs/ui';\nimport { useToursList } from '../hooks/useToursList';\nimport { useTourLifecycle } from '../hooks/useTourLifecycle';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport { useToursStore } from '../store/toursStore';\nimport { useToursContext } from '../providers/ToursProvider';\nimport { useDeleteTourMutation } from '../../generated/global-operations';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport type { TourStatus } from '../types';\nimport type { Tour } from '../../generated/global-types';\nimport { useToursI18n } from '../i18n';\nimport {\n isNative,\n nativeConfirm,\n nativeImpact,\n nativeNotify,\n nativeToast,\n} from '../../utils/nativeBridge';\n\n/**\n * Tours list page\n * Displays all tours with filtering and search\n */\nexport function ToursListPage() {\n const { tr } = useToursI18n();\n const navigate = useNavigate();\n const { basePath = '/' } = useToursContext();\n const {\n viewMode,\n tourFilter,\n toursListRevision,\n setViewMode,\n updateTourFilter,\n notifyToursListChanged,\n } = useToursStore();\n const { hasPermission, isLoading: permissionsLoading } = useToursPermissionAccess();\n\n const canUpdateTour = hasPermission(TOUR_PERMISSIONS.TOUR_UPDATE);\n const canUpdateTourSteps = hasPermission(TOUR_PERMISSIONS.TOUR_STEP_UPDATE);\n const canPreviewTour = hasPermission(TOUR_PERMISSIONS.TOUR_READ);\n const canDeleteTour = hasPermission(TOUR_PERMISSIONS.TOUR_DELETE);\n const canPublishTour = hasPermission(TOUR_PERMISSIONS.TOUR_PUBLISH);\n const canArchiveTour = hasPermission(TOUR_PERMISSIONS.TOUR_ARCHIVE);\n const canDuplicateTour = hasPermission(TOUR_PERMISSIONS.TOUR_DUPLICATE);\n\n // Fetch tours (includes both workspace-specific and global tours)\n const { tours, loading, fetchTours } = useToursList();\n\n const { publishTour, unpublishTour, archiveTour, duplicateTour } = useTourLifecycle();\n const [deleteTourMutation] = useDeleteTourMutation();\n\n const [searchQuery, setSearchQuery] = useState('');\n const [statusFilter, setStatusFilter] = useState<TourStatus | 'all'>('all');\n\n // Fetch tours when filter changes. The list page is also the user-facing\n // tour browser, so backend permissions remain authoritative for actions while\n // normal users can still see published tours returned by the API.\n useEffect(() => {\n if (permissionsLoading) return;\n fetchTours({ ...tourFilter });\n }, [fetchTours, tourFilter, toursListRevision, permissionsLoading]);\n\n const handleSearch = (query: string) => {\n setSearchQuery(query);\n updateTourFilter({ search: query });\n };\n\n const handleStatusFilter = (status: TourStatus | 'all') => {\n setStatusFilter(status);\n updateTourFilter({ status });\n };\n\n const handleCreateTour = () => {\n const newPath = basePath.endsWith('/') ? `${basePath}new` : `${basePath}/new`;\n navigate(newPath);\n };\n\n const getStatusLabel = (status: TourStatus) => {\n switch (status) {\n case 'DRAFT':\n return tr('toursList.statusDraft');\n case 'PUBLISHED':\n return tr('toursList.statusPublished');\n case 'ARCHIVED':\n return tr('toursList.statusArchived');\n case 'SCHEDULED':\n return tr('toursList.statusScheduled');\n }\n };\n\n const handlePublish = async (id: string) => {\n nativeImpact('light');\n try {\n await publishTour(id);\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n if (isNative()) void nativeToast(tr('toursList.errorPublish'));\n else alert(tr('toursList.errorPublish'));\n }\n };\n\n const handleUnpublish = async (id: string) => {\n nativeImpact('light');\n try {\n await unpublishTour(id);\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n if (isNative()) void nativeToast(tr('toursList.errorUnpublish'));\n else alert(tr('toursList.errorUnpublish'));\n }\n };\n\n const handleArchive = async (id: string) => {\n nativeImpact('light');\n try {\n await archiveTour(id);\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n if (isNative()) void nativeToast(tr('toursList.errorArchive'));\n else alert(tr('toursList.errorArchive'));\n }\n };\n\n const handleDuplicate = async (id: string) => {\n nativeImpact('light');\n try {\n await duplicateTour(id);\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n if (isNative()) void nativeToast(tr('toursList.errorDuplicate'));\n else alert(tr('toursList.errorDuplicate'));\n }\n };\n\n const handleDelete = async (id: string) => {\n nativeImpact('medium');\n const confirmMsg = tr('toursList.confirmDelete');\n const nativeResult = await nativeConfirm({\n title: tr('toursList.actionDelete'),\n message: confirmMsg,\n okButtonTitle: tr('toursList.actionDelete'),\n });\n const confirmed = nativeResult === null ? window.confirm(confirmMsg) : nativeResult;\n if (!confirmed) return;\n try {\n await deleteTourMutation({ variables: { id } });\n notifyToursListChanged();\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n if (isNative()) void nativeToast(tr('toursList.errorDelete'));\n else alert(tr('toursList.errorDelete'));\n }\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3\">\n <div className=\"flex-1 min-w-0\">\n <h1 className=\"text-xl sm:text-2xl font-bold text-text-primary\">{tr('toursList.title')}</h1>\n <p className=\"text-sm sm:text-base text-text-secondary\">{tr('toursList.subtitle')}</p>\n </div>\n <PermissionGate permission={TOUR_PERMISSIONS.TOUR_CREATE}>\n <Button\n type=\"button\"\n onClick={handleCreateTour}\n className=\"w-full sm:w-auto min-h-[44px]\"\n >\n <Plus size={20} />\n {tr('toursList.createTour')}\n </Button>\n </PermissionGate>\n </div>\n\n {/* Filters and Search */}\n <div className=\"flex flex-col sm:flex-row gap-3 sm:gap-4\">\n {/* Search */}\n <div className=\"flex-1 relative\">\n <Search\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary\"\n size={20}\n />\n <input\n type=\"text\"\n placeholder={tr('toursList.searchPlaceholder')}\n value={searchQuery}\n onChange={(e) => handleSearch(e.target.value)}\n className=\"w-full pl-[3.25rem] pr-4 py-2 min-h-[44px] border border-border-subtle rounded-md bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n aria-label={tr('toursList.searchPlaceholder')}\n />\n </div>\n\n {/* Status Filter */}\n <div className=\"flex gap-2\">\n <select\n value={statusFilter}\n onChange={(e) => handleStatusFilter(e.target.value as TourStatus | 'all')}\n className=\"px-4 py-2 min-h-[44px] border border-border-subtle rounded-md bg-bg-surface text-text-primary\"\n aria-label={tr('toursList.statusAll')}\n >\n <option value=\"all\">{tr('toursList.statusAll')}</option>\n <option value=\"DRAFT\">{tr('toursList.statusDraft')}</option>\n <option value=\"PUBLISHED\">{tr('toursList.statusPublished')}</option>\n <option value=\"ARCHIVED\">{tr('toursList.statusArchived')}</option>\n <option value=\"SCHEDULED\">{tr('toursList.statusScheduled')}</option>\n </select>\n\n {/* View Mode Toggle */}\n <div className=\"flex border border-border-subtle rounded-md overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setViewMode('grid')}\n className={`px-3 py-2 min-h-[44px] ${\n viewMode === 'grid'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface text-text-primary hover:bg-accent'\n }`}\n aria-label={tr('toursList.gridView')}\n title={tr('toursList.gridView')}\n >\n <Grid size={20} />\n </button>\n <button\n type=\"button\"\n onClick={() => setViewMode('list')}\n className={`px-3 py-2 min-h-[44px] ${\n viewMode === 'list'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface text-text-primary hover:bg-accent'\n }`}\n aria-label={tr('toursList.listView')}\n title={tr('toursList.listView')}\n >\n <ListIcon size={20} />\n </button>\n </div>\n </div>\n </div>\n\n {/* Tours List */}\n {loading ? (\n <div className=\"text-center py-12\">\n <p className=\"text-sm sm:text-base text-text-secondary\">{tr('toursList.loading')}</p>\n </div>\n ) : tours.length > 0 ? (\n <div\n className={\n viewMode === 'grid'\n ? 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4'\n : 'space-y-3'\n }\n >\n {tours.map((tour: Tour) => {\n const status = tour.status as TourStatus;\n const canShowPublishAction = status === 'DRAFT' && canPublishTour;\n const canShowUnpublishAction = status === 'PUBLISHED' && canPublishTour;\n const canShowArchiveAction = status !== 'ARCHIVED' && canArchiveTour;\n\n const overflowActions: CTAAction[] = [];\n if (canShowPublishAction) {\n overflowActions.push({\n label: tr('toursList.actionPublish'),\n onSelect: () => void handlePublish(tour.id),\n });\n }\n if (canShowUnpublishAction) {\n overflowActions.push({\n label: tr('toursList.actionUnpublish'),\n onSelect: () => void handleUnpublish(tour.id),\n });\n }\n if (canDuplicateTour) {\n overflowActions.push({\n label: tr('toursList.actionDuplicate'),\n onSelect: () => void handleDuplicate(tour.id),\n });\n }\n if (canShowArchiveAction) {\n overflowActions.push({\n label: tr('toursList.actionArchive'),\n onSelect: () => void handleArchive(tour.id),\n });\n }\n if (canDeleteTour) {\n overflowActions.push({\n label: tr('toursList.actionDelete'),\n onSelect: () => void handleDelete(tour.id),\n intent: 'destructive',\n });\n }\n\n return (\n <GlassCard\n key={tour.id}\n treatment=\"plain\"\n className=\"p-4 border-border-seam shadow-[var(--shadow-pop)]\"\n >\n <div className=\"flex items-start justify-between mb-2\">\n <h3 className=\"font-semibold text-text-primary\">\n {canUpdateTour ? (\n <button\n type=\"button\"\n className=\"cursor-pointer hover:text-primary bg-transparent border-0 p-0 text-left font-inherit\"\n onClick={() => navigate(`${basePath}/${tour.id}/edit`)}\n >\n {tour.name}\n </button>\n ) : (\n tour.name\n )}\n </h3>\n <span\n className={`px-2 py-1 text-xs rounded-full ${\n tour.status === 'PUBLISHED'\n ? 'bg-success/10 text-success'\n : tour.status === 'DRAFT'\n ? 'bg-bg-sunken text-text-secondary'\n : 'bg-warning/10 text-warning'\n }`}\n >\n {getStatusLabel(status)}\n </span>\n </div>\n {tour.description && (\n <p className=\"text-sm text-text-secondary mb-3\">{tour.description}</p>\n )}\n <div className=\"flex items-center justify-between text-xs text-text-secondary mb-3\">\n <span>\n {tour.steps?.length || 0} {tr('toursList.steps')}\n </span>\n <span>\n {tour.viewCount} {tr('toursList.views')}\n </span>\n </div>\n {/* Quick Actions */}\n <div className=\"flex flex-wrap items-center gap-2 pt-3 border-t border-border-seam\">\n {canUpdateTourSteps && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n navigate(`${basePath}/${tour.id}/steps`);\n }}\n className=\"flex-1 min-w-[6.5rem] px-3 py-2 min-h-[44px] text-xs bg-secondary text-secondary-foreground rounded hover:bg-secondary/80 flex items-center justify-center gap-1.5\"\n title={tr('toursList.editStepsTitle')}\n >\n <ListOrdered size={14} />\n {tr('toursList.stepsButton')}\n </button>\n )}\n {canPreviewTour && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n navigate(`${basePath}/${tour.id}/preview`);\n }}\n className=\"flex-1 min-w-[6.5rem] px-3 py-2 min-h-[44px] text-xs border border-border-seam rounded hover:bg-accent flex items-center justify-center gap-1.5\"\n title={tr('toursList.previewTitle')}\n >\n <Eye size={14} />\n {tr('toursList.previewButton')}\n </button>\n )}\n {canUpdateTour && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n navigate(`${basePath}/${tour.id}/edit`);\n }}\n className=\"p-2 min-h-[44px] min-w-[44px] text-xs border border-border-seam rounded hover:bg-accent\"\n title={tr('toursList.settingsTitle')}\n aria-label={tr('toursList.settingsTitle')}\n >\n <Settings size={14} />\n </button>\n )}\n {/* Lifecycle actions collapsed into the overflow menu */}\n {overflowActions.length > 0 && (\n <CTAOverflowMenu actions={overflowActions} />\n )}\n </div>\n </GlassCard>\n );\n })}\n </div>\n ) : (\n <div className=\"text-center py-12 border border-dashed border-border-subtle rounded-md\">\n <p className=\"text-sm sm:text-base text-text-secondary mb-2\">\n {tr('toursList.emptyTitle')}\n </p>\n <p className=\"text-xs sm:text-sm text-text-secondary\">\n {tr('toursList.emptySubtitle')}\n </p>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA2BA,SAAgB,IAAgB;CAC9B,IAAM,EAAE,UAAO,GAAc,EACvB,IAAW,GAAa,EACxB,EAAE,cAAW,QAAQ,GAAiB,EACtC,EACJ,aACA,eACA,sBACA,gBACA,qBACA,8BACE,GAAe,EACb,EAAE,kBAAe,WAAW,MAAuB,GAA0B,EAE7E,IAAgB,EAAc,EAAiB,YAAY,EAC3D,IAAqB,EAAc,EAAiB,iBAAiB,EACrE,IAAiB,EAAc,EAAiB,UAAU,EAC1D,IAAgB,EAAc,EAAiB,YAAY,EAC3D,IAAiB,EAAc,EAAiB,aAAa,EAC7D,IAAiB,EAAc,EAAiB,aAAa,EAC7D,IAAmB,EAAc,EAAiB,eAAe,EAGjE,EAAE,UAAO,aAAS,kBAAe,GAAc,EAE/C,EAAE,gBAAa,kBAAe,gBAAa,qBAAkB,GAAkB,EAC/E,CAAC,KAAsB,GAAuB,EAE9C,CAAC,IAAa,MAAkB,EAAS,GAAG,EAC5C,CAAC,IAAc,MAAmB,EAA6B,MAAM;AAK3E,SAAgB;AACV,OACJ,EAAW,EAAE,GAAG,GAAY,CAAC;IAC5B;EAAC;EAAY;EAAY;EAAmB;EAAmB,CAAC;CAEnE,IAAM,MAAgB,MAAkB;AAEtC,EADA,GAAe,EAAM,EACrB,EAAiB,EAAE,QAAQ,GAAO,CAAC;IAG/B,MAAsB,MAA+B;AAEzD,EADA,GAAgB,EAAO,EACvB,EAAiB,EAAE,WAAQ,CAAC;IAGxB,WAAyB;AAE7B,IADgB,EAAS,SAAS,IAAI,GAAG,GAAG,EAAS,OAAO,GAAG,EAAS,MACvD;IAGb,MAAkB,MAAuB;AAC7C,UAAQ,GAAR;GACE,KAAK,QACH,QAAO,EAAG,wBAAwB;GACpC,KAAK,YACH,QAAO,EAAG,4BAA4B;GACxC,KAAK,WACH,QAAO,EAAG,2BAA2B;GACvC,KAAK,YACH,QAAO,EAAG,4BAA4B;;IAItC,KAAgB,OAAO,MAAe;AAC1C,IAAa,QAAQ;AACrB,MAAI;AAEG,GADL,MAAM,EAAY,EAAG,EAChB,EAAa,UAAU;UACtB;AAEN,GADK,EAAa,QAAQ,EACtB,GAAU,GAAO,EAAY,EAAG,yBAAyB,CAAC,GACzD,MAAM,EAAG,yBAAyB,CAAC;;IAItC,KAAkB,OAAO,MAAe;AAC5C,IAAa,QAAQ;AACrB,MAAI;AAEG,GADL,MAAM,EAAc,EAAG,EAClB,EAAa,UAAU;UACtB;AAEN,GADK,EAAa,QAAQ,EACtB,GAAU,GAAO,EAAY,EAAG,2BAA2B,CAAC,GAC3D,MAAM,EAAG,2BAA2B,CAAC;;IAIxC,KAAgB,OAAO,MAAe;AAC1C,IAAa,QAAQ;AACrB,MAAI;AAEG,GADL,MAAM,EAAY,EAAG,EAChB,EAAa,UAAU;UACtB;AAEN,GADK,EAAa,QAAQ,EACtB,GAAU,GAAO,EAAY,EAAG,yBAAyB,CAAC,GACzD,MAAM,EAAG,yBAAyB,CAAC;;IAItC,KAAkB,OAAO,MAAe;AAC5C,IAAa,QAAQ;AACrB,MAAI;AAEG,GADL,MAAM,EAAc,EAAG,EAClB,EAAa,UAAU;UACtB;AAEN,GADK,EAAa,QAAQ,EACtB,GAAU,GAAO,EAAY,EAAG,2BAA2B,CAAC,GAC3D,MAAM,EAAG,2BAA2B,CAAC;;IAIxC,KAAe,OAAO,MAAe;AACzC,IAAa,SAAS;EACtB,IAAM,IAAa,EAAG,0BAA0B,EAC1C,IAAe,MAAM,EAAc;GACvC,OAAO,EAAG,yBAAyB;GACnC,SAAS;GACT,eAAe,EAAG,yBAAyB;GAC5C,CAAC;AACgB,YAAiB,OAAO,OAAO,QAAQ,EAAW,GAAG,EAEvE,KAAI;AAGG,GAFL,MAAM,EAAmB,EAAE,WAAW,EAAE,OAAI,EAAE,CAAC,EAC/C,GAAwB,EACnB,EAAa,UAAU;UACtB;AAEN,GADK,EAAa,QAAQ,EACtB,GAAU,GAAO,EAAY,EAAG,wBAAwB,CAAC,GACxD,MAAM,EAAG,wBAAwB,CAAC;;;AAI3C,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAmD,EAAG,kBAAkB;MAAM,CAAA,EAC5F,kBAAC,KAAD;MAAG,WAAU;gBAA4C,EAAG,qBAAqB;MAAK,CAAA,CAClF;QACN,kBAAC,GAAD;KAAgB,YAAY,EAAiB;eAC3C,kBAAC,GAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;gBAHZ,CAKE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,uBAAuB,CACpB;;KACM,CAAA,CACb;;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,WAAU;MACV,MAAM;MACN,CAAA,EACF,kBAAC,SAAD;MACE,MAAK;MACL,aAAa,EAAG,8BAA8B;MAC9C,OAAO;MACP,WAAW,MAAM,GAAa,EAAE,OAAO,MAAM;MAC7C,WAAU;MACV,cAAY,EAAG,8BAA8B;MAC7C,CAAA,CACE;QAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,UAAD;MACE,OAAO;MACP,WAAW,MAAM,GAAmB,EAAE,OAAO,MAA4B;MACzE,WAAU;MACV,cAAY,EAAG,sBAAsB;gBAJvC;OAME,kBAAC,UAAD;QAAQ,OAAM;kBAAO,EAAG,sBAAsB;QAAU,CAAA;OACxD,kBAAC,UAAD;QAAQ,OAAM;kBAAS,EAAG,wBAAwB;QAAU,CAAA;OAC5D,kBAAC,UAAD;QAAQ,OAAM;kBAAa,EAAG,4BAA4B;QAAU,CAAA;OACpE,kBAAC,UAAD;QAAQ,OAAM;kBAAY,EAAG,2BAA2B;QAAU,CAAA;OAClE,kBAAC,UAAD;QAAQ,OAAM;kBAAa,EAAG,4BAA4B;QAAU,CAAA;OAC7D;SAGT,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAY,OAAO;OAClC,WAAW,0BACT,MAAa,SACT,kDACA;OAEN,cAAY,EAAG,qBAAqB;OACpC,OAAO,EAAG,qBAAqB;iBAE/B,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;OACX,CAAA,EACT,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAY,OAAO;OAClC,WAAW,0BACT,MAAa,SACT,kDACA;OAEN,cAAY,EAAG,qBAAqB;OACpC,OAAO,EAAG,qBAAqB;iBAE/B,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA;OACf,CAAA,CACL;QACF;OACF;;GAGL,KACC,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,KAAD;KAAG,WAAU;eAA4C,EAAG,oBAAoB;KAAK,CAAA;IACjF,CAAA,GACJ,EAAM,SAAS,IACjB,kBAAC,OAAD;IACE,WACE,MAAa,SACT,kEACA;cAGL,EAAM,KAAK,MAAe;KACzB,IAAM,IAAS,EAAK,QACd,IAAuB,MAAW,WAAW,GAC7C,IAAyB,MAAW,eAAe,GACnD,IAAuB,MAAW,cAAc,GAEhD,IAA+B,EAAE;AAiCvC,YAhCI,KACF,EAAgB,KAAK;MACnB,OAAO,EAAG,0BAA0B;MACpC,gBAAgB,KAAK,GAAc,EAAK,GAAG;MAC5C,CAAC,EAEA,KACF,EAAgB,KAAK;MACnB,OAAO,EAAG,4BAA4B;MACtC,gBAAgB,KAAK,GAAgB,EAAK,GAAG;MAC9C,CAAC,EAEA,KACF,EAAgB,KAAK;MACnB,OAAO,EAAG,4BAA4B;MACtC,gBAAgB,KAAK,GAAgB,EAAK,GAAG;MAC9C,CAAC,EAEA,KACF,EAAgB,KAAK;MACnB,OAAO,EAAG,0BAA0B;MACpC,gBAAgB,KAAK,GAAc,EAAK,GAAG;MAC5C,CAAC,EAEA,KACF,EAAgB,KAAK;MACnB,OAAO,EAAG,yBAAyB;MACnC,gBAAgB,KAAK,GAAa,EAAK,GAAG;MAC1C,QAAQ;MACT,CAAC,EAIF,kBAAC,GAAD;MAEE,WAAU;MACV,WAAU;gBAHZ;OAKE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,MAAD;SAAI,WAAU;mBACX,IACC,kBAAC,UAAD;UACE,MAAK;UACL,WAAU;UACV,eAAe,EAAS,GAAG,EAAS,GAAG,EAAK,GAAG,OAAO;oBAErD,EAAK;UACC,CAAA,GAET,EAAK;SAEJ,CAAA,EACL,kBAAC,QAAD;SACE,WAAW,kCACT,EAAK,WAAW,cACZ,+BACA,EAAK,WAAW,UACd,qCACA;mBAGP,GAAe,EAAO;SAClB,CAAA,CACH;;OACL,EAAK,eACJ,kBAAC,KAAD;QAAG,WAAU;kBAAoC,EAAK;QAAgB,CAAA;OAExE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD,EAAA,UAAA;SACG,EAAK,OAAO,UAAU;SAAE;SAAE,EAAG,kBAAkB;SAC3C,EAAA,CAAA,EACP,kBAAC,QAAD,EAAA,UAAA;SACG,EAAK;SAAU;SAAE,EAAG,kBAAkB;SAClC,EAAA,CAAA,CACH;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACG,KACC,kBAAC,UAAD;UACE,MAAK;UACL,UAAU,MAAM;AAEd,WADA,EAAE,iBAAiB,EACnB,EAAS,GAAG,EAAS,GAAG,EAAK,GAAG,QAAQ;;UAE1C,WAAU;UACV,OAAO,EAAG,2BAA2B;oBAPvC,CASE,kBAAC,GAAD,EAAa,MAAM,IAAM,CAAA,EACxB,EAAG,wBAAwB,CACrB;;SAEV,KACC,kBAAC,UAAD;UACE,MAAK;UACL,UAAU,MAAM;AAEd,WADA,EAAE,iBAAiB,EACnB,EAAS,GAAG,EAAS,GAAG,EAAK,GAAG,UAAU;;UAE5C,WAAU;UACV,OAAO,EAAG,yBAAyB;oBAPrC,CASE,kBAAC,GAAD,EAAK,MAAM,IAAM,CAAA,EAChB,EAAG,0BAA0B,CACvB;;SAEV,KACC,kBAAC,UAAD;UACE,MAAK;UACL,UAAU,MAAM;AAEd,WADA,EAAE,iBAAiB,EACnB,EAAS,GAAG,EAAS,GAAG,EAAK,GAAG,OAAO;;UAEzC,WAAU;UACV,OAAO,EAAG,0BAA0B;UACpC,cAAY,EAAG,0BAA0B;oBAEzC,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA;UACf,CAAA;SAGV,EAAgB,SAAS,KACxB,kBAAC,GAAD,EAAiB,SAAS,GAAmB,CAAA;SAE3C;;OACI;QA1FL,EAAK,GA0FA;MAEd;IACE,CAAA,GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eACV,EAAG,uBAAuB;KACzB,CAAA,EACJ,kBAAC,KAAD;KAAG,WAAU;eACV,EAAG,0BAA0B;KAC5B,CAAA,CACA;;GAEJ"}
|
|
1
|
+
{"version":3,"file":"ToursListPage.js","names":[],"sources":["../../../src/tours/pages/ToursListPage.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Plus, Search, Grid, List as ListIcon, ListOrdered, Eye, Settings } from 'lucide-react';\nimport { PermissionGate } from '@burdenoff/fe-libs/shared/components';\nimport {\n AuroraBackground,\n Button,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n CTAOverflowMenu,\n type CTAAction,\n} from '@burdenoff/fe-libs/ui';\nimport { useToursList } from '../hooks/useToursList';\nimport { useTourLifecycle } from '../hooks/useTourLifecycle';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport { useToursStore } from '../store/toursStore';\nimport { useToursContext } from '../providers/ToursProvider';\nimport { useDeleteTourMutation } from '../../generated/global-operations';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport type { TourStatus } from '../types';\nimport type { Tour } from '../../generated/global-types';\nimport { useToursI18n } from '../i18n';\nimport {\n isNative,\n nativeConfirm,\n nativeImpact,\n nativeNotify,\n nativeToast,\n} from '../../utils/nativeBridge';\n\n/**\n * Tours list page\n * Displays all tours with filtering and search\n */\nexport function ToursListPage() {\n const { tr } = useToursI18n();\n const navigate = useNavigate();\n const { basePath = '/' } = useToursContext();\n const {\n viewMode,\n tourFilter,\n toursListRevision,\n setViewMode,\n updateTourFilter,\n notifyToursListChanged,\n } = useToursStore();\n const { hasPermission, isLoading: permissionsLoading } = useToursPermissionAccess();\n\n const canUpdateTour = hasPermission(TOUR_PERMISSIONS.TOUR_UPDATE);\n const canUpdateTourSteps = hasPermission(TOUR_PERMISSIONS.TOUR_STEP_UPDATE);\n const canPreviewTour = hasPermission(TOUR_PERMISSIONS.TOUR_READ);\n const canDeleteTour = hasPermission(TOUR_PERMISSIONS.TOUR_DELETE);\n const canPublishTour = hasPermission(TOUR_PERMISSIONS.TOUR_PUBLISH);\n const canArchiveTour = hasPermission(TOUR_PERMISSIONS.TOUR_ARCHIVE);\n const canDuplicateTour = hasPermission(TOUR_PERMISSIONS.TOUR_DUPLICATE);\n\n // Fetch tours (includes both workspace-specific and global tours)\n const { tours, loading, fetchTours } = useToursList();\n\n const { publishTour, unpublishTour, archiveTour, duplicateTour } = useTourLifecycle();\n const [deleteTourMutation] = useDeleteTourMutation();\n\n const [searchQuery, setSearchQuery] = useState('');\n const [statusFilter, setStatusFilter] = useState<TourStatus | 'all'>('all');\n\n // Fetch tours when filter changes. The list page is also the user-facing\n // tour browser, so backend permissions remain authoritative for actions while\n // normal users can still see published tours returned by the API.\n useEffect(() => {\n if (permissionsLoading) return;\n fetchTours({ ...tourFilter });\n }, [fetchTours, tourFilter, toursListRevision, permissionsLoading]);\n\n const handleSearch = (query: string) => {\n setSearchQuery(query);\n updateTourFilter({ search: query });\n };\n\n const handleStatusFilter = (status: TourStatus | 'all') => {\n setStatusFilter(status);\n updateTourFilter({ status });\n };\n\n const handleCreateTour = () => {\n const newPath = basePath.endsWith('/') ? `${basePath}new` : `${basePath}/new`;\n navigate(newPath);\n };\n\n const getStatusLabel = (status: TourStatus) => {\n switch (status) {\n case 'DRAFT':\n return tr('toursList.statusDraft');\n case 'PUBLISHED':\n return tr('toursList.statusPublished');\n case 'ARCHIVED':\n return tr('toursList.statusArchived');\n case 'SCHEDULED':\n return tr('toursList.statusScheduled');\n }\n };\n\n const handlePublish = async (id: string) => {\n nativeImpact('light');\n try {\n await publishTour(id);\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n if (isNative()) void nativeToast(tr('toursList.errorPublish'));\n else alert(tr('toursList.errorPublish'));\n }\n };\n\n const handleUnpublish = async (id: string) => {\n nativeImpact('light');\n try {\n await unpublishTour(id);\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n if (isNative()) void nativeToast(tr('toursList.errorUnpublish'));\n else alert(tr('toursList.errorUnpublish'));\n }\n };\n\n const handleArchive = async (id: string) => {\n nativeImpact('light');\n try {\n await archiveTour(id);\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n if (isNative()) void nativeToast(tr('toursList.errorArchive'));\n else alert(tr('toursList.errorArchive'));\n }\n };\n\n const handleDuplicate = async (id: string) => {\n nativeImpact('light');\n try {\n await duplicateTour(id);\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n if (isNative()) void nativeToast(tr('toursList.errorDuplicate'));\n else alert(tr('toursList.errorDuplicate'));\n }\n };\n\n const handleDelete = async (id: string) => {\n nativeImpact('medium');\n const confirmMsg = tr('toursList.confirmDelete');\n const nativeResult = await nativeConfirm({\n title: tr('toursList.actionDelete'),\n message: confirmMsg,\n okButtonTitle: tr('toursList.actionDelete'),\n });\n const confirmed = nativeResult === null ? window.confirm(confirmMsg) : nativeResult;\n if (!confirmed) return;\n try {\n await deleteTourMutation({ variables: { id } });\n notifyToursListChanged();\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n if (isNative()) void nativeToast(tr('toursList.errorDelete'));\n else alert(tr('toursList.errorDelete'));\n }\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"relative overflow-hidden rounded-xl\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 p-1 sm:p-2\">\n <div className=\"flex-1 min-w-0\">\n <h1 className=\"text-xl sm:text-2xl font-bold text-text-primary\">\n <GradientText>{tr('toursList.title')}</GradientText>\n </h1>\n <p className=\"text-sm sm:text-base text-text-secondary\">{tr('toursList.subtitle')}</p>\n </div>\n <PermissionGate permission={TOUR_PERMISSIONS.TOUR_CREATE}>\n <Button\n type=\"button\"\n onClick={handleCreateTour}\n className=\"w-full sm:w-auto min-h-[44px]\"\n >\n <Plus size={20} />\n {tr('toursList.createTour')}\n </Button>\n </PermissionGate>\n </div>\n </div>\n\n <PagePurpose>{tr('toursList.purpose')}</PagePurpose>\n\n {/* Filters and Search */}\n <div className=\"flex flex-col sm:flex-row gap-3 sm:gap-4\">\n {/* Search */}\n <div className=\"flex-1 relative\">\n <Search\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary\"\n size={20}\n />\n <input\n type=\"text\"\n placeholder={tr('toursList.searchPlaceholder')}\n value={searchQuery}\n onChange={(e) => handleSearch(e.target.value)}\n className=\"w-full pl-[3.25rem] pr-4 py-2 min-h-[44px] border border-border-subtle rounded-md bg-bg-surface text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n aria-label={tr('toursList.searchPlaceholder')}\n />\n </div>\n\n {/* Status Filter */}\n <div className=\"flex gap-2\">\n <select\n value={statusFilter}\n onChange={(e) => handleStatusFilter(e.target.value as TourStatus | 'all')}\n className=\"px-4 py-2 min-h-[44px] border border-border-subtle rounded-md bg-bg-surface text-text-primary\"\n aria-label={tr('toursList.statusAll')}\n >\n <option value=\"all\">{tr('toursList.statusAll')}</option>\n <option value=\"DRAFT\">{tr('toursList.statusDraft')}</option>\n <option value=\"PUBLISHED\">{tr('toursList.statusPublished')}</option>\n <option value=\"ARCHIVED\">{tr('toursList.statusArchived')}</option>\n <option value=\"SCHEDULED\">{tr('toursList.statusScheduled')}</option>\n </select>\n\n {/* View Mode Toggle */}\n <div className=\"flex border border-border-subtle rounded-md overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setViewMode('grid')}\n className={`px-3 py-2 min-h-[44px] ${\n viewMode === 'grid'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface text-text-primary hover:bg-accent'\n }`}\n aria-label={tr('toursList.gridView')}\n title={tr('toursList.gridView')}\n >\n <Grid size={20} />\n </button>\n <button\n type=\"button\"\n onClick={() => setViewMode('list')}\n className={`px-3 py-2 min-h-[44px] ${\n viewMode === 'list'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface text-text-primary hover:bg-accent'\n }`}\n aria-label={tr('toursList.listView')}\n title={tr('toursList.listView')}\n >\n <ListIcon size={20} />\n </button>\n </div>\n </div>\n </div>\n\n {/* Tours List */}\n {loading ? (\n <div className=\"text-center py-12\">\n <p className=\"text-sm sm:text-base text-text-secondary\">{tr('toursList.loading')}</p>\n </div>\n ) : tours.length > 0 ? (\n <div\n className={\n viewMode === 'grid'\n ? 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4'\n : 'space-y-3'\n }\n >\n {tours.map((tour: Tour) => {\n const status = tour.status as TourStatus;\n const canShowPublishAction = status === 'DRAFT' && canPublishTour;\n const canShowUnpublishAction = status === 'PUBLISHED' && canPublishTour;\n const canShowArchiveAction = status !== 'ARCHIVED' && canArchiveTour;\n\n const overflowActions: CTAAction[] = [];\n if (canShowPublishAction) {\n overflowActions.push({\n label: tr('toursList.actionPublish'),\n onSelect: () => void handlePublish(tour.id),\n });\n }\n if (canShowUnpublishAction) {\n overflowActions.push({\n label: tr('toursList.actionUnpublish'),\n onSelect: () => void handleUnpublish(tour.id),\n });\n }\n if (canDuplicateTour) {\n overflowActions.push({\n label: tr('toursList.actionDuplicate'),\n onSelect: () => void handleDuplicate(tour.id),\n });\n }\n if (canShowArchiveAction) {\n overflowActions.push({\n label: tr('toursList.actionArchive'),\n onSelect: () => void handleArchive(tour.id),\n });\n }\n if (canDeleteTour) {\n overflowActions.push({\n label: tr('toursList.actionDelete'),\n onSelect: () => void handleDelete(tour.id),\n intent: 'destructive',\n });\n }\n\n return (\n <GlassCard\n key={tour.id}\n treatment=\"plain\"\n className=\"p-4 border-border-seam shadow-[var(--shadow-pop)]\"\n >\n <div className=\"flex items-start justify-between mb-2\">\n <h3 className=\"font-semibold text-text-primary\">\n {canUpdateTour ? (\n <button\n type=\"button\"\n className=\"cursor-pointer hover:text-primary bg-transparent border-0 p-0 text-left font-inherit\"\n onClick={() => navigate(`${basePath}/${tour.id}/edit`)}\n >\n {tour.name}\n </button>\n ) : (\n tour.name\n )}\n </h3>\n <span\n className={`px-2 py-1 text-xs rounded-full ${\n tour.status === 'PUBLISHED'\n ? 'bg-success/10 text-success motion-safe:animate-vc-glow-pulse'\n : tour.status === 'DRAFT'\n ? 'bg-bg-sunken text-text-secondary'\n : 'bg-warning/10 text-warning'\n }`}\n >\n {getStatusLabel(status)}\n </span>\n </div>\n {tour.description && (\n <p className=\"text-sm text-text-secondary mb-3\">{tour.description}</p>\n )}\n <div className=\"flex items-center justify-between text-xs text-text-secondary mb-3\">\n <span>\n {tour.steps?.length || 0} {tr('toursList.steps')}\n </span>\n <span>\n {tour.viewCount} {tr('toursList.views')}\n </span>\n </div>\n {/* Quick Actions */}\n <div className=\"flex flex-wrap items-center gap-2 pt-3 border-t border-border-seam\">\n {canUpdateTourSteps && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n navigate(`${basePath}/${tour.id}/steps`);\n }}\n className=\"flex-1 min-w-[6.5rem] px-3 py-2 min-h-[44px] text-xs bg-secondary text-secondary-foreground rounded hover:bg-secondary/80 flex items-center justify-center gap-1.5\"\n title={tr('toursList.editStepsTitle')}\n >\n <ListOrdered size={14} />\n {tr('toursList.stepsButton')}\n </button>\n )}\n {canPreviewTour && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n navigate(`${basePath}/${tour.id}/preview`);\n }}\n className=\"flex-1 min-w-[6.5rem] px-3 py-2 min-h-[44px] text-xs border border-border-seam rounded hover:bg-accent flex items-center justify-center gap-1.5\"\n title={tr('toursList.previewTitle')}\n >\n <Eye size={14} />\n {tr('toursList.previewButton')}\n </button>\n )}\n {canUpdateTour && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n navigate(`${basePath}/${tour.id}/edit`);\n }}\n className=\"p-2 min-h-[44px] min-w-[44px] text-xs border border-border-seam rounded hover:bg-accent\"\n title={tr('toursList.settingsTitle')}\n aria-label={tr('toursList.settingsTitle')}\n >\n <Settings size={14} />\n </button>\n )}\n {/* Lifecycle actions collapsed into the overflow menu */}\n {overflowActions.length > 0 && (\n <CTAOverflowMenu actions={overflowActions} />\n )}\n </div>\n </GlassCard>\n );\n })}\n </div>\n ) : (\n <IllustratedEmptyState\n illustration=\"onboarding\"\n title={tr('toursList.emptyTitle')}\n description={tr('toursList.emptySubtitle')}\n action={\n <PermissionGate permission={TOUR_PERMISSIONS.TOUR_CREATE}>\n <Button type=\"button\" onClick={handleCreateTour} className=\"min-h-[44px]\">\n <Plus size={20} />\n {tr('toursList.createTour')}\n </Button>\n </PermissionGate>\n }\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-tours",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.626.1",
|
|
4
4
|
"description": "Burdenoff Tours Microfrontend - Complete product tours and onboarding interface",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@apollo/client": "^3.12.0",
|
|
46
|
-
"@burdenoff/fe-libs": "2026.625.
|
|
46
|
+
"@burdenoff/fe-libs": "2026.625.5",
|
|
47
47
|
"@tanstack/react-query": "^5.90.16",
|
|
48
48
|
"clsx": "^2.1.1",
|
|
49
49
|
"graphql": "^16.10.0",
|