@burdenoff/microfe-tours 2026.608.1 → 2026.625.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/ToursUserRoutes.js +3 -3
- package/dist/tours/ToursUserRoutes.js.map +1 -1
- package/dist/tours/components/RouteHelpers.js +6 -6
- package/dist/tours/components/RouteHelpers.js.map +1 -1
- package/dist/tours/pages/AnalyticsDashboardPage.js +80 -74
- package/dist/tours/pages/AnalyticsDashboardPage.js.map +1 -1
- package/dist/tours/pages/MediaLibraryPage.js +66 -64
- package/dist/tours/pages/MediaLibraryPage.js.map +1 -1
- package/dist/tours/pages/MyToursPage.js +37 -35
- package/dist/tours/pages/MyToursPage.js.map +1 -1
- package/dist/tours/pages/MyToursProgressPage.js +60 -56
- package/dist/tours/pages/MyToursProgressPage.js.map +1 -1
- package/dist/tours/pages/SchedulerPage.js +98 -92
- package/dist/tours/pages/SchedulerPage.js.map +1 -1
- package/dist/tours/pages/StepEditorPage.js +261 -260
- package/dist/tours/pages/StepEditorPage.js.map +1 -1
- package/dist/tours/pages/SystemAnalyticsPage.js +59 -53
- package/dist/tours/pages/SystemAnalyticsPage.js.map +1 -1
- package/dist/tours/pages/TemplateLibraryPage.js +71 -69
- package/dist/tours/pages/TemplateLibraryPage.js.map +1 -1
- package/dist/tours/pages/TourBuilderPage.js +181 -194
- package/dist/tours/pages/TourBuilderPage.js.map +1 -1
- package/dist/tours/pages/TourPreviewPage.js +92 -89
- package/dist/tours/pages/TourPreviewPage.js.map +1 -1
- package/dist/tours/pages/ToursListPage.js +171 -215
- package/dist/tours/pages/ToursListPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -9,49 +9,50 @@ import { useState as d } from "react";
|
|
|
9
9
|
import { Globe as f, LayoutTemplate as p, Lock as m, Search as h, Star as g, Trash2 as _ } from "lucide-react";
|
|
10
10
|
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
11
11
|
import { useNavigate as b } from "react-router-dom";
|
|
12
|
-
import {
|
|
12
|
+
import { GlassCard as x } from "@burdenoff/fe-libs/ui";
|
|
13
|
+
import { useEventBus as S } from "@burdenoff/fe-libs/shared/events";
|
|
13
14
|
//#region src/tours/pages/TemplateLibraryPage.tsx
|
|
14
|
-
function
|
|
15
|
-
let { tr:
|
|
16
|
-
skip: !
|
|
15
|
+
function C() {
|
|
16
|
+
let { tr: C } = o(), w = b(), T = e(), { basePath: E = "/" } = T, D = S(), { hasPermission: O } = i(), k = O(a.TOUR_TEMPLATE_LIST), A = O(a.TOUR_TEMPLATE_USE), j = O(a.TOUR_TEMPLATE_DELETE), [M, N] = d(""), [P, F] = d("all"), [I, L] = d(!1), { data: R, loading: z } = r({
|
|
17
|
+
skip: !k,
|
|
17
18
|
variables: {
|
|
18
|
-
isPublic:
|
|
19
|
-
category:
|
|
19
|
+
isPublic: I || void 0,
|
|
20
|
+
category: P === "all" ? void 0 : P
|
|
20
21
|
}
|
|
21
|
-
}),
|
|
22
|
+
}), B = (R?.tourTemplates ?? []).filter((e) => !M || e.name.toLowerCase().includes(M.toLowerCase())), [V] = t(), H = async (e) => {
|
|
22
23
|
c("light");
|
|
23
24
|
try {
|
|
24
|
-
let { data: t } = await
|
|
25
|
-
t?.createTourFromTemplate && (l("success"),
|
|
25
|
+
let { data: t } = await V({ variables: { templateId: e } });
|
|
26
|
+
t?.createTourFromTemplate && (l("success"), w(`${E}/${t.createTourFromTemplate.id}/edit`));
|
|
26
27
|
} catch {
|
|
27
|
-
l("error"), u(
|
|
28
|
+
l("error"), u(D, "template.create_from_template", T);
|
|
28
29
|
}
|
|
29
|
-
}, [
|
|
30
|
+
}, [U] = n(), W = async (e) => {
|
|
30
31
|
try {
|
|
31
|
-
await
|
|
32
|
+
await U({
|
|
32
33
|
variables: { id: e },
|
|
33
34
|
refetchQueries: ["GetTourTemplates"]
|
|
34
35
|
}), l("success");
|
|
35
36
|
} catch {
|
|
36
|
-
l("error"), u(
|
|
37
|
+
l("error"), u(D, "template.delete", T);
|
|
37
38
|
}
|
|
38
|
-
},
|
|
39
|
+
}, G = async (e) => {
|
|
39
40
|
c("medium");
|
|
40
|
-
let t =
|
|
41
|
-
title:
|
|
41
|
+
let t = C("templateLibrary.deleteConfirm"), n = await s({
|
|
42
|
+
title: C("templateLibrary.deleteConfirm"),
|
|
42
43
|
message: t
|
|
43
44
|
});
|
|
44
|
-
(n === null ? window.confirm(t) : n) && await
|
|
45
|
+
(n === null ? window.confirm(t) : n) && await W(e);
|
|
45
46
|
};
|
|
46
47
|
return /* @__PURE__ */ y("div", {
|
|
47
48
|
className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
|
|
48
49
|
children: [
|
|
49
50
|
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h1", {
|
|
50
51
|
className: "text-xl sm:text-2xl font-bold",
|
|
51
|
-
children:
|
|
52
|
+
children: C("templateLibrary.title")
|
|
52
53
|
}), /* @__PURE__ */ v("p", {
|
|
53
|
-
className: "text-sm text-
|
|
54
|
-
children:
|
|
54
|
+
className: "text-sm text-text-secondary",
|
|
55
|
+
children: C("templateLibrary.subtitle")
|
|
55
56
|
})] }),
|
|
56
57
|
/* @__PURE__ */ y("div", {
|
|
57
58
|
className: "flex flex-col sm:flex-row gap-3",
|
|
@@ -59,78 +60,79 @@ function S() {
|
|
|
59
60
|
/* @__PURE__ */ y("div", {
|
|
60
61
|
className: "flex-1 relative",
|
|
61
62
|
children: [/* @__PURE__ */ v(h, {
|
|
62
|
-
className: "absolute left-3 top-1/2 -translate-y-1/2 text-
|
|
63
|
+
className: "absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary",
|
|
63
64
|
size: 20
|
|
64
65
|
}), /* @__PURE__ */ v("input", {
|
|
65
66
|
type: "text",
|
|
66
|
-
placeholder:
|
|
67
|
-
value:
|
|
68
|
-
onChange: (e) =>
|
|
69
|
-
className: "w-full pl-[3.25rem] pr-4 py-2 min-h-[44px] border border-border rounded-md bg-
|
|
70
|
-
"aria-label":
|
|
67
|
+
placeholder: C("templateLibrary.searchPlaceholder"),
|
|
68
|
+
value: M,
|
|
69
|
+
onChange: (e) => N(e.target.value),
|
|
70
|
+
className: "w-full pl-[3.25rem] pr-4 py-2 min-h-[44px] border border-border-subtle rounded-md bg-bg-surface",
|
|
71
|
+
"aria-label": C("templateLibrary.searchPlaceholder")
|
|
71
72
|
})]
|
|
72
73
|
}),
|
|
73
74
|
/* @__PURE__ */ y("select", {
|
|
74
|
-
value:
|
|
75
|
-
onChange: (e) =>
|
|
76
|
-
className: "px-4 py-2 min-h-[44px] border border-border rounded-md bg-
|
|
77
|
-
"aria-label":
|
|
75
|
+
value: P,
|
|
76
|
+
onChange: (e) => F(e.target.value),
|
|
77
|
+
className: "px-4 py-2 min-h-[44px] border border-border-subtle rounded-md bg-bg-surface",
|
|
78
|
+
"aria-label": C("templateLibrary.allCategories"),
|
|
78
79
|
children: [
|
|
79
80
|
/* @__PURE__ */ v("option", {
|
|
80
81
|
value: "all",
|
|
81
|
-
children:
|
|
82
|
+
children: C("templateLibrary.allCategories")
|
|
82
83
|
}),
|
|
83
84
|
/* @__PURE__ */ v("option", {
|
|
84
85
|
value: "ONBOARDING",
|
|
85
|
-
children:
|
|
86
|
+
children: C("templateLibrary.categoryOnboarding")
|
|
86
87
|
}),
|
|
87
88
|
/* @__PURE__ */ v("option", {
|
|
88
89
|
value: "FEATURE_ANNOUNCEMENT",
|
|
89
|
-
children:
|
|
90
|
+
children: C("templateLibrary.categoryFeatureAnnouncement")
|
|
90
91
|
}),
|
|
91
92
|
/* @__PURE__ */ v("option", {
|
|
92
93
|
value: "HELP",
|
|
93
|
-
children:
|
|
94
|
+
children: C("templateLibrary.categoryHelp")
|
|
94
95
|
}),
|
|
95
96
|
/* @__PURE__ */ v("option", {
|
|
96
97
|
value: "CUSTOM",
|
|
97
|
-
children:
|
|
98
|
+
children: C("templateLibrary.categoryCustom")
|
|
98
99
|
})
|
|
99
100
|
]
|
|
100
101
|
}),
|
|
101
102
|
/* @__PURE__ */ y("label", {
|
|
102
|
-
className: "flex items-center gap-2 px-4 py-2 min-h-[44px] border border-border rounded-md bg-
|
|
103
|
+
className: "flex items-center gap-2 px-4 py-2 min-h-[44px] border border-border-subtle rounded-md bg-bg-surface cursor-pointer",
|
|
103
104
|
children: [/* @__PURE__ */ v("input", {
|
|
104
105
|
type: "checkbox",
|
|
105
|
-
checked:
|
|
106
|
-
onChange: (e) =>
|
|
106
|
+
checked: I,
|
|
107
|
+
onChange: (e) => L(e.target.checked),
|
|
107
108
|
className: "rounded",
|
|
108
|
-
"aria-label":
|
|
109
|
+
"aria-label": C("templateLibrary.publicOnly")
|
|
109
110
|
}), /* @__PURE__ */ v("span", {
|
|
110
111
|
className: "text-sm",
|
|
111
|
-
children:
|
|
112
|
+
children: C("templateLibrary.publicOnly")
|
|
112
113
|
})]
|
|
113
114
|
})
|
|
114
115
|
]
|
|
115
116
|
}),
|
|
116
|
-
|
|
117
|
+
z ? /* @__PURE__ */ v("div", {
|
|
117
118
|
className: "text-center py-12",
|
|
118
119
|
children: /* @__PURE__ */ v("p", {
|
|
119
|
-
className: "text-
|
|
120
|
-
children:
|
|
120
|
+
className: "text-text-secondary",
|
|
121
|
+
children: C("templateLibrary.loading")
|
|
121
122
|
})
|
|
122
|
-
}) :
|
|
123
|
+
}) : B.length > 0 ? /* @__PURE__ */ v("div", {
|
|
123
124
|
className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
124
|
-
children:
|
|
125
|
-
|
|
125
|
+
children: B.map((e) => /* @__PURE__ */ y(x, {
|
|
126
|
+
treatment: "plain",
|
|
127
|
+
className: "overflow-hidden p-0 border-border-seam shadow-[var(--shadow-pop)]",
|
|
126
128
|
children: [/* @__PURE__ */ v("div", {
|
|
127
|
-
className: "aspect-video bg-
|
|
129
|
+
className: "aspect-video bg-bg-sunken flex items-center justify-center",
|
|
128
130
|
children: e.thumbnail ? /* @__PURE__ */ v("img", {
|
|
129
131
|
src: e.thumbnail,
|
|
130
132
|
alt: e.name,
|
|
131
133
|
className: "w-full h-full object-cover"
|
|
132
134
|
}) : /* @__PURE__ */ v(p, {
|
|
133
|
-
className: "text-
|
|
135
|
+
className: "text-text-secondary",
|
|
134
136
|
size: 48
|
|
135
137
|
})
|
|
136
138
|
}), /* @__PURE__ */ y("div", {
|
|
@@ -147,42 +149,42 @@ function S() {
|
|
|
147
149
|
className: "text-warning",
|
|
148
150
|
size: 16
|
|
149
151
|
}), e.isPublic ? /* @__PURE__ */ v(f, {
|
|
150
|
-
className: "text-
|
|
152
|
+
className: "text-text-secondary",
|
|
151
153
|
size: 16
|
|
152
154
|
}) : /* @__PURE__ */ v(m, {
|
|
153
|
-
className: "text-
|
|
155
|
+
className: "text-text-secondary",
|
|
154
156
|
size: 16
|
|
155
157
|
})]
|
|
156
158
|
})]
|
|
157
159
|
}),
|
|
158
160
|
e.description && /* @__PURE__ */ v("p", {
|
|
159
|
-
className: "text-sm text-
|
|
161
|
+
className: "text-sm text-text-secondary mb-3 line-clamp-2",
|
|
160
162
|
children: e.description
|
|
161
163
|
}),
|
|
162
164
|
/* @__PURE__ */ y("div", {
|
|
163
165
|
className: "flex items-center justify-between",
|
|
164
166
|
children: [/* @__PURE__ */ y("span", {
|
|
165
|
-
className: "text-xs text-
|
|
167
|
+
className: "text-xs text-text-secondary",
|
|
166
168
|
children: [
|
|
167
|
-
|
|
169
|
+
C("templateLibrary.usedTimes"),
|
|
168
170
|
" ",
|
|
169
171
|
e.useCount,
|
|
170
172
|
" ",
|
|
171
|
-
|
|
173
|
+
C("templateLibrary.times")
|
|
172
174
|
]
|
|
173
175
|
}), /* @__PURE__ */ y("div", {
|
|
174
176
|
className: "flex items-center gap-2",
|
|
175
|
-
children: [
|
|
177
|
+
children: [j && /* @__PURE__ */ v("button", {
|
|
176
178
|
type: "button",
|
|
177
|
-
onClick: () => void
|
|
178
|
-
className: "p-2 min-h-[44px] min-w-[44px] text-
|
|
179
|
-
"aria-label":
|
|
179
|
+
onClick: () => void G(e.id),
|
|
180
|
+
className: "p-2 min-h-[44px] min-w-[44px] text-text-secondary hover:text-status-error-text rounded-md",
|
|
181
|
+
"aria-label": C("templateLibrary.deleteTemplate"),
|
|
180
182
|
children: /* @__PURE__ */ v(_, { size: 16 })
|
|
181
|
-
}),
|
|
183
|
+
}), A && /* @__PURE__ */ v("button", {
|
|
182
184
|
type: "button",
|
|
183
|
-
onClick: () =>
|
|
184
|
-
className: "px-3 py-2 min-h-[44px] bg-primary text-primary-
|
|
185
|
-
children:
|
|
185
|
+
onClick: () => H(e.id),
|
|
186
|
+
className: "px-3 py-2 min-h-[44px] bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 text-sm",
|
|
187
|
+
children: C("templateLibrary.useTemplate")
|
|
186
188
|
})]
|
|
187
189
|
})]
|
|
188
190
|
})
|
|
@@ -190,19 +192,19 @@ function S() {
|
|
|
190
192
|
})]
|
|
191
193
|
}, e.id))
|
|
192
194
|
}) : /* @__PURE__ */ y("div", {
|
|
193
|
-
className: "text-center py-12 border border-dashed border-border rounded-md",
|
|
195
|
+
className: "text-center py-12 border border-dashed border-border-subtle rounded-md",
|
|
194
196
|
children: [
|
|
195
197
|
/* @__PURE__ */ v(p, {
|
|
196
|
-
className: "mx-auto mb-4 text-
|
|
198
|
+
className: "mx-auto mb-4 text-text-secondary",
|
|
197
199
|
size: 48
|
|
198
200
|
}),
|
|
199
201
|
/* @__PURE__ */ v("p", {
|
|
200
|
-
className: "text-
|
|
201
|
-
children:
|
|
202
|
+
className: "text-text-secondary mb-2",
|
|
203
|
+
children: C("templateLibrary.noTemplatesFound")
|
|
202
204
|
}),
|
|
203
205
|
/* @__PURE__ */ v("p", {
|
|
204
|
-
className: "text-sm text-
|
|
205
|
-
children:
|
|
206
|
+
className: "text-sm text-text-secondary",
|
|
207
|
+
children: C("templateLibrary.adjustFilters")
|
|
206
208
|
})
|
|
207
209
|
]
|
|
208
210
|
})
|
|
@@ -210,6 +212,6 @@ function S() {
|
|
|
210
212
|
});
|
|
211
213
|
}
|
|
212
214
|
//#endregion
|
|
213
|
-
export {
|
|
215
|
+
export { C as TemplateLibraryPage };
|
|
214
216
|
|
|
215
217
|
//# sourceMappingURL=TemplateLibraryPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateLibraryPage.js","names":[],"sources":["../../../src/tours/pages/TemplateLibraryPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Search, LayoutTemplate, Star, Globe, Lock, Trash2 } from 'lucide-react';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\nimport { useToursContext } from '../providers/ToursProvider';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport {\n useGetTourTemplatesQuery,\n useCreateTourFromTemplateMutation,\n useDeleteTourTemplateMutation,\n} from '../../generated/global-operations';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport type { TemplateCategory } from '../types';\nimport { useToursI18n } from '../i18n';\nimport { emitToursApiFailed } from '../telemetry';\nimport { nativeConfirm, nativeImpact, nativeNotify } from '../../utils/nativeBridge';\n\n/**\n * Template library page\n * Browse and use tour templates\n */\nexport function TemplateLibraryPage() {\n const { tr } = useToursI18n();\n\n const navigate = useNavigate();\n const toursContext = useToursContext();\n const { basePath = '/' } = toursContext;\n const eventBus = useEventBus();\n const { hasPermission } = useToursPermissionAccess();\n const canListTemplates = hasPermission(TOUR_PERMISSIONS.TOUR_TEMPLATE_LIST);\n const canUseTemplate = hasPermission(TOUR_PERMISSIONS.TOUR_TEMPLATE_USE);\n const canDeleteTemplate = hasPermission(TOUR_PERMISSIONS.TOUR_TEMPLATE_DELETE);\n\n const [searchQuery, setSearchQuery] = useState('');\n const [categoryFilter, setCategoryFilter] = useState<TemplateCategory | 'all'>('all');\n const [publicOnly, setPublicOnly] = useState(false);\n\n const { data, loading } = useGetTourTemplatesQuery({\n skip: !canListTemplates,\n variables: {\n isPublic: publicOnly || undefined,\n category: categoryFilter === 'all' ? undefined : categoryFilter,\n },\n });\n const templates = data?.tourTemplates ?? [];\n\n const filteredTemplates = templates.filter(\n (t: (typeof templates)[number]) =>\n !searchQuery || t.name.toLowerCase().includes(searchQuery.toLowerCase())\n );\n\n const [createFromTemplate] = useCreateTourFromTemplateMutation();\n\n const handleUseTemplate = async (templateId: string) => {\n nativeImpact('light');\n try {\n const { data } = await createFromTemplate({\n variables: { templateId },\n });\n if (data?.createTourFromTemplate) {\n void nativeNotify('success');\n navigate(`${basePath}/${data.createTourFromTemplate.id}/edit`);\n }\n } catch {\n void nativeNotify('error');\n emitToursApiFailed(eventBus, 'template.create_from_template', toursContext);\n }\n };\n\n const [deleteTemplate] = useDeleteTourTemplateMutation();\n\n const handleDeleteTemplate = async (templateId: string) => {\n try {\n await deleteTemplate({\n variables: { id: templateId },\n refetchQueries: ['GetTourTemplates'],\n });\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n emitToursApiFailed(eventBus, 'template.delete', toursContext);\n }\n };\n\n const handleDeleteTemplateClick = async (templateId: string) => {\n nativeImpact('medium');\n const message = tr('templateLibrary.deleteConfirm');\n const nativeResult = await nativeConfirm({\n title: tr('templateLibrary.deleteConfirm'),\n message,\n });\n const confirmed = nativeResult === null ? window.confirm(message) : nativeResult;\n if (confirmed) await handleDeleteTemplate(templateId);\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div>\n <h1 className=\"text-xl sm:text-2xl font-bold\">{tr('templateLibrary.title')}</h1>\n <p className=\"text-sm text-muted-foreground\">{tr('templateLibrary.subtitle')}</p>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col sm:flex-row gap-3\">\n <div className=\"flex-1 relative\">\n <Search\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground\"\n size={20}\n />\n <input\n type=\"text\"\n placeholder={tr('templateLibrary.searchPlaceholder')}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full pl-[3.25rem] pr-4 py-2 min-h-[44px] border border-border rounded-md bg-background\"\n aria-label={tr('templateLibrary.searchPlaceholder')}\n />\n </div>\n <select\n value={categoryFilter}\n onChange={(e) => setCategoryFilter(e.target.value as TemplateCategory | 'all')}\n className=\"px-4 py-2 min-h-[44px] border border-border rounded-md bg-background\"\n aria-label={tr('templateLibrary.allCategories')}\n >\n <option value=\"all\">{tr('templateLibrary.allCategories')}</option>\n <option value=\"ONBOARDING\">{tr('templateLibrary.categoryOnboarding')}</option>\n <option value=\"FEATURE_ANNOUNCEMENT\">\n {tr('templateLibrary.categoryFeatureAnnouncement')}\n </option>\n <option value=\"HELP\">{tr('templateLibrary.categoryHelp')}</option>\n <option value=\"CUSTOM\">{tr('templateLibrary.categoryCustom')}</option>\n </select>\n <label className=\"flex items-center gap-2 px-4 py-2 min-h-[44px] border border-border rounded-md bg-background cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={publicOnly}\n onChange={(e) => setPublicOnly(e.target.checked)}\n className=\"rounded\"\n aria-label={tr('templateLibrary.publicOnly')}\n />\n <span className=\"text-sm\">{tr('templateLibrary.publicOnly')}</span>\n </label>\n </div>\n\n {/* Templates Grid */}\n {loading ? (\n <div className=\"text-center py-12\">\n <p className=\"text-muted-foreground\">{tr('templateLibrary.loading')}</p>\n </div>\n ) : filteredTemplates.length > 0 ? (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n {filteredTemplates.map((template: (typeof filteredTemplates)[number]) => (\n <div\n key={template.id}\n className=\"border border-border rounded-md overflow-hidden hover:shadow-md transition-shadow\"\n >\n {/* Thumbnail */}\n <div className=\"aspect-video bg-muted flex items-center justify-center\">\n {template.thumbnail ? (\n <img\n src={template.thumbnail}\n alt={template.name}\n className=\"w-full h-full object-cover\"\n />\n ) : (\n <LayoutTemplate className=\"text-muted-foreground\" size={48} />\n )}\n </div>\n\n {/* Content */}\n <div className=\"p-4\">\n <div className=\"flex items-start justify-between mb-2\">\n <h3 className=\"font-semibold\">{template.name}</h3>\n <div className=\"flex gap-1\">\n {template.isPremium && <Star className=\"text-warning\" size={16} />}\n {template.isPublic ? (\n <Globe className=\"text-muted-foreground\" size={16} />\n ) : (\n <Lock className=\"text-muted-foreground\" size={16} />\n )}\n </div>\n </div>\n\n {template.description && (\n <p className=\"text-sm text-muted-foreground mb-3 line-clamp-2\">\n {template.description}\n </p>\n )}\n\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-muted-foreground\">\n {tr('templateLibrary.usedTimes')} {template.useCount}{' '}\n {tr('templateLibrary.times')}\n </span>\n <div className=\"flex items-center gap-2\">\n {canDeleteTemplate && (\n <button\n type=\"button\"\n onClick={() => void handleDeleteTemplateClick(template.id)}\n className=\"p-2 min-h-[44px] min-w-[44px] text-muted-foreground hover:text-destructive rounded-md\"\n aria-label={tr('templateLibrary.deleteTemplate')}\n >\n <Trash2 size={16} />\n </button>\n )}\n {canUseTemplate && (\n <button\n type=\"button\"\n onClick={() => handleUseTemplate(template.id)}\n className=\"px-3 py-2 min-h-[44px] bg-primary text-primary-foreground rounded-md hover:bg-primary/90 text-sm\"\n >\n {tr('templateLibrary.useTemplate')}\n </button>\n )}\n </div>\n </div>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"text-center py-12 border border-dashed border-border rounded-md\">\n <LayoutTemplate className=\"mx-auto mb-4 text-muted-foreground\" size={48} />\n <p className=\"text-muted-foreground mb-2\">{tr('templateLibrary.noTemplatesFound')}</p>\n <p className=\"text-sm text-muted-foreground\">{tr('templateLibrary.adjustFilters')}</p>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TemplateLibraryPage.js","names":[],"sources":["../../../src/tours/pages/TemplateLibraryPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Search, LayoutTemplate, Star, Globe, Lock, Trash2 } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\nimport { useToursContext } from '../providers/ToursProvider';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport {\n useGetTourTemplatesQuery,\n useCreateTourFromTemplateMutation,\n useDeleteTourTemplateMutation,\n} from '../../generated/global-operations';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport type { TemplateCategory } from '../types';\nimport { useToursI18n } from '../i18n';\nimport { emitToursApiFailed } from '../telemetry';\nimport { nativeConfirm, nativeImpact, nativeNotify } from '../../utils/nativeBridge';\n\n/**\n * Template library page\n * Browse and use tour templates\n */\nexport function TemplateLibraryPage() {\n const { tr } = useToursI18n();\n\n const navigate = useNavigate();\n const toursContext = useToursContext();\n const { basePath = '/' } = toursContext;\n const eventBus = useEventBus();\n const { hasPermission } = useToursPermissionAccess();\n const canListTemplates = hasPermission(TOUR_PERMISSIONS.TOUR_TEMPLATE_LIST);\n const canUseTemplate = hasPermission(TOUR_PERMISSIONS.TOUR_TEMPLATE_USE);\n const canDeleteTemplate = hasPermission(TOUR_PERMISSIONS.TOUR_TEMPLATE_DELETE);\n\n const [searchQuery, setSearchQuery] = useState('');\n const [categoryFilter, setCategoryFilter] = useState<TemplateCategory | 'all'>('all');\n const [publicOnly, setPublicOnly] = useState(false);\n\n const { data, loading } = useGetTourTemplatesQuery({\n skip: !canListTemplates,\n variables: {\n isPublic: publicOnly || undefined,\n category: categoryFilter === 'all' ? undefined : categoryFilter,\n },\n });\n const templates = data?.tourTemplates ?? [];\n\n const filteredTemplates = templates.filter(\n (t: (typeof templates)[number]) =>\n !searchQuery || t.name.toLowerCase().includes(searchQuery.toLowerCase())\n );\n\n const [createFromTemplate] = useCreateTourFromTemplateMutation();\n\n const handleUseTemplate = async (templateId: string) => {\n nativeImpact('light');\n try {\n const { data } = await createFromTemplate({\n variables: { templateId },\n });\n if (data?.createTourFromTemplate) {\n void nativeNotify('success');\n navigate(`${basePath}/${data.createTourFromTemplate.id}/edit`);\n }\n } catch {\n void nativeNotify('error');\n emitToursApiFailed(eventBus, 'template.create_from_template', toursContext);\n }\n };\n\n const [deleteTemplate] = useDeleteTourTemplateMutation();\n\n const handleDeleteTemplate = async (templateId: string) => {\n try {\n await deleteTemplate({\n variables: { id: templateId },\n refetchQueries: ['GetTourTemplates'],\n });\n void nativeNotify('success');\n } catch {\n void nativeNotify('error');\n emitToursApiFailed(eventBus, 'template.delete', toursContext);\n }\n };\n\n const handleDeleteTemplateClick = async (templateId: string) => {\n nativeImpact('medium');\n const message = tr('templateLibrary.deleteConfirm');\n const nativeResult = await nativeConfirm({\n title: tr('templateLibrary.deleteConfirm'),\n message,\n });\n const confirmed = nativeResult === null ? window.confirm(message) : nativeResult;\n if (confirmed) await handleDeleteTemplate(templateId);\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div>\n <h1 className=\"text-xl sm:text-2xl font-bold\">{tr('templateLibrary.title')}</h1>\n <p className=\"text-sm text-text-secondary\">{tr('templateLibrary.subtitle')}</p>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col sm:flex-row gap-3\">\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('templateLibrary.searchPlaceholder')}\n value={searchQuery}\n onChange={(e) => setSearchQuery(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\"\n aria-label={tr('templateLibrary.searchPlaceholder')}\n />\n </div>\n <select\n value={categoryFilter}\n onChange={(e) => setCategoryFilter(e.target.value as TemplateCategory | 'all')}\n className=\"px-4 py-2 min-h-[44px] border border-border-subtle rounded-md bg-bg-surface\"\n aria-label={tr('templateLibrary.allCategories')}\n >\n <option value=\"all\">{tr('templateLibrary.allCategories')}</option>\n <option value=\"ONBOARDING\">{tr('templateLibrary.categoryOnboarding')}</option>\n <option value=\"FEATURE_ANNOUNCEMENT\">\n {tr('templateLibrary.categoryFeatureAnnouncement')}\n </option>\n <option value=\"HELP\">{tr('templateLibrary.categoryHelp')}</option>\n <option value=\"CUSTOM\">{tr('templateLibrary.categoryCustom')}</option>\n </select>\n <label className=\"flex items-center gap-2 px-4 py-2 min-h-[44px] border border-border-subtle rounded-md bg-bg-surface cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={publicOnly}\n onChange={(e) => setPublicOnly(e.target.checked)}\n className=\"rounded\"\n aria-label={tr('templateLibrary.publicOnly')}\n />\n <span className=\"text-sm\">{tr('templateLibrary.publicOnly')}</span>\n </label>\n </div>\n\n {/* Templates Grid */}\n {loading ? (\n <div className=\"text-center py-12\">\n <p className=\"text-text-secondary\">{tr('templateLibrary.loading')}</p>\n </div>\n ) : filteredTemplates.length > 0 ? (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n {filteredTemplates.map((template: (typeof filteredTemplates)[number]) => (\n <GlassCard\n key={template.id}\n treatment=\"plain\"\n className=\"overflow-hidden p-0 border-border-seam shadow-[var(--shadow-pop)]\"\n >\n {/* Thumbnail */}\n <div className=\"aspect-video bg-bg-sunken flex items-center justify-center\">\n {template.thumbnail ? (\n <img\n src={template.thumbnail}\n alt={template.name}\n className=\"w-full h-full object-cover\"\n />\n ) : (\n <LayoutTemplate className=\"text-text-secondary\" size={48} />\n )}\n </div>\n\n {/* Content */}\n <div className=\"p-4\">\n <div className=\"flex items-start justify-between mb-2\">\n <h3 className=\"font-semibold\">{template.name}</h3>\n <div className=\"flex gap-1\">\n {template.isPremium && <Star className=\"text-warning\" size={16} />}\n {template.isPublic ? (\n <Globe className=\"text-text-secondary\" size={16} />\n ) : (\n <Lock className=\"text-text-secondary\" size={16} />\n )}\n </div>\n </div>\n\n {template.description && (\n <p className=\"text-sm text-text-secondary mb-3 line-clamp-2\">\n {template.description}\n </p>\n )}\n\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary\">\n {tr('templateLibrary.usedTimes')} {template.useCount}{' '}\n {tr('templateLibrary.times')}\n </span>\n <div className=\"flex items-center gap-2\">\n {canDeleteTemplate && (\n <button\n type=\"button\"\n onClick={() => void handleDeleteTemplateClick(template.id)}\n className=\"p-2 min-h-[44px] min-w-[44px] text-text-secondary hover:text-status-error-text rounded-md\"\n aria-label={tr('templateLibrary.deleteTemplate')}\n >\n <Trash2 size={16} />\n </button>\n )}\n {canUseTemplate && (\n <button\n type=\"button\"\n onClick={() => handleUseTemplate(template.id)}\n className=\"px-3 py-2 min-h-[44px] bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 text-sm\"\n >\n {tr('templateLibrary.useTemplate')}\n </button>\n )}\n </div>\n </div>\n </div>\n </GlassCard>\n ))}\n </div>\n ) : (\n <div className=\"text-center py-12 border border-dashed border-border-subtle rounded-md\">\n <LayoutTemplate className=\"mx-auto mb-4 text-text-secondary\" size={48} />\n <p className=\"text-text-secondary mb-2\">{tr('templateLibrary.noTemplatesFound')}</p>\n <p className=\"text-sm text-text-secondary\">{tr('templateLibrary.adjustFilters')}</p>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|