@burdenoff/microfe-tours 2026.830.1 → 2026.830.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/tours/ToursAdminRoot.js +28 -27
  2. package/dist/tours/ToursAdminRoot.js.map +1 -1
  3. package/dist/tours/ToursAdminRoutes.js +56 -55
  4. package/dist/tours/ToursAdminRoutes.js.map +1 -1
  5. package/dist/tours/ToursUserRoot.js +34 -29
  6. package/dist/tours/ToursUserRoot.js.map +1 -1
  7. package/dist/tours/ToursUserRoutes.js +33 -33
  8. package/dist/tours/ToursUserRoutes.js.map +1 -1
  9. package/dist/tours/components/MarkdownEditor.js +85 -80
  10. package/dist/tours/components/MarkdownEditor.js.map +1 -1
  11. package/dist/tours/components/RouteHelpers.js +47 -42
  12. package/dist/tours/components/RouteHelpers.js.map +1 -1
  13. package/dist/tours/components/ToursAdminNavRegistrar.js +32 -27
  14. package/dist/tours/components/ToursAdminNavRegistrar.js.map +1 -1
  15. package/dist/tours/hooks/useStepSequencer.js +45 -36
  16. package/dist/tours/hooks/useStepSequencer.js.map +1 -1
  17. package/dist/tours/hooks/useTourBuilder.js +106 -93
  18. package/dist/tours/hooks/useTourBuilder.js.map +1 -1
  19. package/dist/tours/hooks/useTourPreview.js +51 -41
  20. package/dist/tours/hooks/useTourPreview.js.map +1 -1
  21. package/dist/tours/hooks/useToursList.js +28 -27
  22. package/dist/tours/hooks/useToursList.js.map +1 -1
  23. package/dist/tours/i18n.js +187 -5
  24. package/dist/tours/i18n.js.map +1 -1
  25. package/dist/tours/pages/AnalyticsDashboardPage.js +108 -109
  26. package/dist/tours/pages/AnalyticsDashboardPage.js.map +1 -1
  27. package/dist/tours/pages/MediaLibraryPage.js +58 -61
  28. package/dist/tours/pages/MediaLibraryPage.js.map +1 -1
  29. package/dist/tours/pages/MyToursPage.js +5 -5
  30. package/dist/tours/pages/MyToursProgressPage.js +5 -5
  31. package/dist/tours/pages/SchedulerPage.js +78 -81
  32. package/dist/tours/pages/SchedulerPage.js.map +1 -1
  33. package/dist/tours/pages/StepEditorPage.js +32 -32
  34. package/dist/tours/pages/StepEditorPage.js.map +1 -1
  35. package/dist/tours/pages/SystemAnalyticsPage.js +75 -79
  36. package/dist/tours/pages/SystemAnalyticsPage.js.map +1 -1
  37. package/dist/tours/pages/TemplateLibraryPage.js +8 -8
  38. package/dist/tours/pages/TourBuilderPage.js +279 -279
  39. package/dist/tours/pages/TourBuilderPage.js.map +1 -1
  40. package/dist/tours/pages/TourPreviewPage.js +6 -6
  41. package/dist/tours/pages/ToursListPage.js +155 -155
  42. package/dist/tours/pages/ToursListPage.js.map +1 -1
  43. package/dist/tours/store/toursStore.js +11 -7
  44. package/dist/tours/store/toursStore.js.map +1 -1
  45. package/dist/tours/utils/index.js +32 -19
  46. package/dist/tours/utils/index.js.map +1 -1
  47. package/package.json +1 -1
@@ -1,221 +1,220 @@
1
- import { useToursPermissionAccess as e } from "../hooks/useToursPermissionAccess.js";
2
- import { TOUR_PERMISSIONS as t } from "../../constants/permissions.js";
3
- import { useTourAnalytics as n } from "../hooks/useTourAnalytics.js";
4
- import { formatDuration as r, formatNumber as i, formatPercentage as a } from "../utils/index.js";
5
- import { useCallback as o, useEffect as s } from "react";
6
- import { BarChart3 as c, Timer as l, TrendingUp as u, Users as d } from "lucide-react";
7
- import { jsx as f, jsxs as p } from "react/jsx-runtime";
8
- import { useParams as m } from "react-router";
9
- import { EmphasisPanel as h, GlassCard as g, IllustratedEmptyState as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
10
- import { useI18n as y } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
1
+ import { useToursI18n as e } from "../i18n.js";
2
+ import { useToursPermissionAccess as t } from "../hooks/useToursPermissionAccess.js";
3
+ import { TOUR_PERMISSIONS as n } from "../../constants/permissions.js";
4
+ import { useTourAnalytics as r } from "../hooks/useTourAnalytics.js";
5
+ import { useToursFormatters as i } from "../utils/index.js";
6
+ import { useEffect as a } from "react";
7
+ import { BarChart3 as o, Timer as s, TrendingUp as c, Users as l } from "lucide-react";
8
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
9
+ import { useParams as f } from "react-router";
10
+ import { EmphasisPanel as p, GlassCard as m, IllustratedEmptyState as h, PagePurpose as g } from "@burdenoff/fe-libs/ui";
11
11
  //#region src/tours/pages/AnalyticsDashboardPage.tsx
12
- function b() {
13
- let { t: b } = y(), x = o((e, t) => {
14
- let n = b(e);
15
- return n === e ? t : n;
16
- }, [b]), { tourId: S } = m(), { hasPermission: C, isLoading: w } = e(), T = C(t.TOUR_ANALYTICS_READ), { analytics: E, loading: D, fetchAnalytics: O, getCompletionRate: k, getSkipRate: A } = n(S);
17
- return s(() => {
18
- w || !T || O();
12
+ function _() {
13
+ let { tr: _ } = e(), { tourId: v } = f(), { hasPermission: y, isLoading: b } = t(), x = y(n.TOUR_ANALYTICS_READ), { analytics: S, loading: C, fetchAnalytics: w, getCompletionRate: T, getSkipRate: E } = r(v), { formatNumber: D, formatPercentage: O, formatDuration: k } = i();
14
+ return a(() => {
15
+ b || !x || w();
19
16
  }, [
20
- O,
21
17
  w,
22
- T
23
- ]), !w && !T ? /* @__PURE__ */ f("div", {
18
+ b,
19
+ x
20
+ ]), !b && !x ? /* @__PURE__ */ u("div", {
24
21
  className: "flex items-center justify-center h-full p-3 sm:p-6",
25
- children: /* @__PURE__ */ p("div", {
22
+ children: /* @__PURE__ */ d("div", {
26
23
  className: "text-center",
27
- children: [/* @__PURE__ */ f("h2", {
24
+ children: [/* @__PURE__ */ u("h2", {
28
25
  className: "text-lg font-semibold text-text-primary mb-2",
29
- children: x("analyticsDashboard.accessDenied", "Access Denied")
30
- }), /* @__PURE__ */ f("p", {
26
+ children: _("analyticsDashboard.accessDenied", "Access Denied")
27
+ }), /* @__PURE__ */ u("p", {
31
28
  className: "text-sm text-text-secondary",
32
- children: x("analyticsDashboard.noPermission", "You do not have permission to view tour analytics.")
29
+ children: _("analyticsDashboard.noPermission", "You do not have permission to view tour analytics.")
33
30
  })]
34
31
  })
35
- }) : D ? /* @__PURE__ */ f("div", {
32
+ }) : C ? /* @__PURE__ */ u("div", {
36
33
  className: "flex items-center justify-center h-full",
37
- children: /* @__PURE__ */ f("p", {
34
+ children: /* @__PURE__ */ u("p", {
38
35
  className: "text-text-secondary",
39
- children: x("analyticsDashboard.loading", "Loading analytics...")
36
+ children: _("analyticsDashboard.loading", "Loading analytics...")
40
37
  })
41
- }) : E ? /* @__PURE__ */ p("div", {
38
+ }) : S ? /* @__PURE__ */ d("div", {
42
39
  className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
43
40
  children: [
44
- /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h1", {
41
+ /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("h1", {
45
42
  className: "text-xl sm:text-2xl font-bold",
46
- children: x("analyticsDashboard.title", "Tour Analytics")
47
- }), /* @__PURE__ */ f("p", {
43
+ children: _("analyticsDashboard.title", "Tour Analytics")
44
+ }), /* @__PURE__ */ u("p", {
48
45
  className: "text-sm text-text-secondary",
49
- children: x("analyticsDashboard.subtitle", "Performance metrics and insights")
46
+ children: _("analyticsDashboard.subtitle", "Performance metrics and insights")
50
47
  })] }),
51
- /* @__PURE__ */ f(v, { children: x("analyticsDashboard.purpose", "See how this specific tour is performing: how many people viewed it, how many finished versus skipped, and exactly which step they drop off on. Use the per-step drop-off to find and fix the weak point in your walkthrough.") }),
52
- /* @__PURE__ */ p("div", {
48
+ /* @__PURE__ */ u(g, { children: _("analyticsDashboard.purpose", "See how this specific tour is performing: how many people viewed it, how many finished versus skipped, and exactly which step they drop off on. Use the per-step drop-off to find and fix the weak point in your walkthrough.") }),
49
+ /* @__PURE__ */ d("div", {
53
50
  className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",
54
51
  children: [
55
- /* @__PURE__ */ p(g, {
52
+ /* @__PURE__ */ d(m, {
56
53
  treatment: "glass",
57
54
  className: "p-4",
58
- children: [/* @__PURE__ */ p("div", {
55
+ children: [/* @__PURE__ */ d("div", {
59
56
  className: "flex items-center gap-3 mb-2",
60
- children: [/* @__PURE__ */ f("div", {
57
+ children: [/* @__PURE__ */ u("div", {
61
58
  className: "p-2 bg-action-primary-bg/10 rounded-md",
62
- children: /* @__PURE__ */ f(d, {
59
+ children: /* @__PURE__ */ u(l, {
63
60
  className: "text-primary",
64
61
  size: 20
65
62
  })
66
- }), /* @__PURE__ */ f("span", {
63
+ }), /* @__PURE__ */ u("span", {
67
64
  className: "text-sm text-text-secondary",
68
- children: x("analyticsDashboard.totalViews", "Total Views")
65
+ children: _("analyticsDashboard.totalViews", "Total Views")
69
66
  })]
70
- }), /* @__PURE__ */ f("div", {
67
+ }), /* @__PURE__ */ u("div", {
71
68
  className: "text-2xl font-bold tabular-nums",
72
- children: i(E.totalViews)
69
+ children: D(S.totalViews)
73
70
  })]
74
71
  }),
75
- /* @__PURE__ */ p(g, {
72
+ /* @__PURE__ */ d(m, {
76
73
  treatment: "metric",
77
74
  className: "p-4",
78
- children: [/* @__PURE__ */ p("div", {
75
+ children: [/* @__PURE__ */ d("div", {
79
76
  className: "flex items-center gap-3 mb-2",
80
- children: [/* @__PURE__ */ f("div", {
77
+ children: [/* @__PURE__ */ u("div", {
81
78
  className: "p-2 bg-success/10 rounded-md",
82
- children: /* @__PURE__ */ f(u, {
79
+ children: /* @__PURE__ */ u(c, {
83
80
  className: "text-success",
84
81
  size: 20
85
82
  })
86
- }), /* @__PURE__ */ f("span", {
83
+ }), /* @__PURE__ */ u("span", {
87
84
  className: "text-sm text-text-secondary",
88
- children: x("analyticsDashboard.completionRate", "Completion Rate")
85
+ children: _("analyticsDashboard.completionRate", "Completion Rate")
89
86
  })]
90
- }), /* @__PURE__ */ f("div", {
87
+ }), /* @__PURE__ */ u("div", {
91
88
  className: "text-2xl font-bold tabular-nums",
92
- children: a(k())
89
+ children: O(T())
93
90
  })]
94
91
  }),
95
- /* @__PURE__ */ p(g, {
92
+ /* @__PURE__ */ d(m, {
96
93
  treatment: "metric",
97
94
  className: "p-4",
98
- children: [/* @__PURE__ */ p("div", {
95
+ children: [/* @__PURE__ */ d("div", {
99
96
  className: "flex items-center gap-3 mb-2",
100
- children: [/* @__PURE__ */ f("div", {
97
+ children: [/* @__PURE__ */ u("div", {
101
98
  className: "p-2 bg-warning/10 rounded-md",
102
- children: /* @__PURE__ */ f(c, {
99
+ children: /* @__PURE__ */ u(o, {
103
100
  className: "text-warning",
104
101
  size: 20
105
102
  })
106
- }), /* @__PURE__ */ f("span", {
103
+ }), /* @__PURE__ */ u("span", {
107
104
  className: "text-sm text-text-secondary",
108
- children: x("analyticsDashboard.skipRate", "Skip Rate")
105
+ children: _("analyticsDashboard.skipRate", "Skip Rate")
109
106
  })]
110
- }), /* @__PURE__ */ f("div", {
107
+ }), /* @__PURE__ */ u("div", {
111
108
  className: "text-2xl font-bold tabular-nums",
112
- children: a(A())
109
+ children: O(E())
113
110
  })]
114
111
  }),
115
- /* @__PURE__ */ p(g, {
112
+ /* @__PURE__ */ d(m, {
116
113
  treatment: "metric",
117
114
  className: "p-4",
118
- children: [/* @__PURE__ */ p("div", {
115
+ children: [/* @__PURE__ */ d("div", {
119
116
  className: "flex items-center gap-3 mb-2",
120
- children: [/* @__PURE__ */ f("div", {
117
+ children: [/* @__PURE__ */ u("div", {
121
118
  className: "p-2 bg-info/10 rounded-md",
122
- children: /* @__PURE__ */ f(l, {
119
+ children: /* @__PURE__ */ u(s, {
123
120
  className: "text-info",
124
121
  size: 20
125
122
  })
126
- }), /* @__PURE__ */ f("span", {
123
+ }), /* @__PURE__ */ u("span", {
127
124
  className: "text-sm text-text-secondary",
128
- children: x("analyticsDashboard.avgDuration", "Avg Duration")
125
+ children: _("analyticsDashboard.avgDuration", "Avg Duration")
129
126
  })]
130
- }), /* @__PURE__ */ f("div", {
127
+ }), /* @__PURE__ */ u("div", {
131
128
  className: "text-2xl font-bold tabular-nums",
132
- children: r(E.averageDuration)
129
+ children: k(S.averageDuration)
133
130
  })]
134
131
  })
135
132
  ]
136
133
  }),
137
- /* @__PURE__ */ p(h, {
134
+ /* @__PURE__ */ d(p, {
138
135
  className: "p-4 sm:p-6",
139
- children: [/* @__PURE__ */ f("h2", {
136
+ children: [/* @__PURE__ */ u("h2", {
140
137
  className: "text-lg font-semibold mb-4",
141
- children: x("analyticsDashboard.deviceBreakdown", "Device Breakdown")
142
- }), /* @__PURE__ */ f("div", {
138
+ children: _("analyticsDashboard.deviceBreakdown", "Device Breakdown")
139
+ }), /* @__PURE__ */ u("div", {
143
140
  className: "space-y-3",
144
- children: E.byDeviceType.map((e) => /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ p("div", {
141
+ children: S.byDeviceType.map((e) => /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ d("div", {
145
142
  className: "flex items-center justify-between mb-2",
146
- children: [/* @__PURE__ */ f("span", {
147
- className: "text-sm capitalize",
148
- children: e.deviceType
149
- }), /* @__PURE__ */ p("span", {
143
+ children: [/* @__PURE__ */ u("span", {
144
+ className: "text-sm",
145
+ children: _(`deviceType.${e.deviceType}`, e.deviceType)
146
+ }), /* @__PURE__ */ d("span", {
150
147
  className: "text-sm text-text-secondary tabular-nums",
151
148
  children: [
152
- i(e.count),
153
- " views (",
154
- a(e.completionRate),
149
+ D(e.count),
150
+ " ",
151
+ _("analyticsDashboard.deviceViews", "views"),
152
+ " (",
153
+ O(e.completionRate),
155
154
  ")"
156
155
  ]
157
156
  })]
158
- }), /* @__PURE__ */ f("div", {
157
+ }), /* @__PURE__ */ u("div", {
159
158
  className: "w-full bg-bg-sunken rounded-full h-2",
160
- children: /* @__PURE__ */ f("div", {
159
+ children: /* @__PURE__ */ u("div", {
161
160
  className: "bg-action-primary-bg h-2 rounded-full shadow-[var(--shadow-pop)]",
162
161
  style: { width: `${e.completionRate}%` }
163
162
  })
164
163
  })] }, e.deviceType))
165
164
  })]
166
165
  }),
167
- E.stepAnalytics && E.stepAnalytics.length > 0 && /* @__PURE__ */ p(g, {
166
+ S.stepAnalytics && S.stepAnalytics.length > 0 && /* @__PURE__ */ d(m, {
168
167
  treatment: "plain",
169
168
  className: "p-4 sm:p-6 border-border-seam",
170
- children: [/* @__PURE__ */ f("h2", {
169
+ children: [/* @__PURE__ */ u("h2", {
171
170
  className: "text-lg font-semibold mb-4",
172
- children: x("analyticsDashboard.stepPerformance", "Step Performance")
173
- }), /* @__PURE__ */ f("div", {
171
+ children: _("analyticsDashboard.stepPerformance", "Step Performance")
172
+ }), /* @__PURE__ */ u("div", {
174
173
  className: "overflow-x-auto",
175
- children: /* @__PURE__ */ p("table", {
174
+ children: /* @__PURE__ */ d("table", {
176
175
  className: "w-full",
177
- children: [/* @__PURE__ */ f("thead", { children: /* @__PURE__ */ p("tr", {
176
+ children: [/* @__PURE__ */ u("thead", { children: /* @__PURE__ */ d("tr", {
178
177
  className: "border-b border-border-seam",
179
178
  children: [
180
- /* @__PURE__ */ f("th", {
179
+ /* @__PURE__ */ u("th", {
181
180
  className: "text-left py-2 px-4 text-sm font-medium text-text-secondary",
182
- children: x("analyticsDashboard.tableStep", "Step")
181
+ children: _("analyticsDashboard.tableStep", "Step")
183
182
  }),
184
- /* @__PURE__ */ f("th", {
183
+ /* @__PURE__ */ u("th", {
185
184
  className: "text-right py-2 px-4 text-sm font-medium text-text-secondary",
186
- children: x("analyticsDashboard.tableViews", "Views")
185
+ children: _("analyticsDashboard.tableViews", "Views")
187
186
  }),
188
- /* @__PURE__ */ f("th", {
187
+ /* @__PURE__ */ u("th", {
189
188
  className: "text-right py-2 px-4 text-sm font-medium text-text-secondary",
190
- children: x("analyticsDashboard.tableCompletions", "Completions")
189
+ children: _("analyticsDashboard.tableCompletions", "Completions")
191
190
  }),
192
- /* @__PURE__ */ f("th", {
191
+ /* @__PURE__ */ u("th", {
193
192
  className: "text-right py-2 px-4 text-sm font-medium text-text-secondary",
194
- children: x("analyticsDashboard.tableDropOffRate", "Drop-off Rate")
193
+ children: _("analyticsDashboard.tableDropOffRate", "Drop-off Rate")
195
194
  })
196
195
  ]
197
- }) }), /* @__PURE__ */ f("tbody", { children: E.stepAnalytics.map((e) => /* @__PURE__ */ p("tr", {
196
+ }) }), /* @__PURE__ */ u("tbody", { children: S.stepAnalytics.map((e) => /* @__PURE__ */ d("tr", {
198
197
  className: "border-b border-border-seam",
199
198
  children: [
200
- /* @__PURE__ */ p("td", {
199
+ /* @__PURE__ */ d("td", {
201
200
  className: "py-2 px-4 text-sm",
202
201
  children: [
203
- x("analyticsDashboard.stepLabel", "Step"),
202
+ _("analyticsDashboard.stepLabel", "Step"),
204
203
  " ",
205
204
  e.stepOrder
206
205
  ]
207
206
  }),
208
- /* @__PURE__ */ f("td", {
207
+ /* @__PURE__ */ u("td", {
209
208
  className: "text-right py-2 px-4 text-sm tabular-nums",
210
- children: i(e.views)
209
+ children: D(e.views)
211
210
  }),
212
- /* @__PURE__ */ f("td", {
211
+ /* @__PURE__ */ u("td", {
213
212
  className: "text-right py-2 px-4 text-sm tabular-nums",
214
- children: i(e.completions)
213
+ children: D(e.completions)
215
214
  }),
216
- /* @__PURE__ */ f("td", {
215
+ /* @__PURE__ */ u("td", {
217
216
  className: "text-right py-2 px-4 text-sm tabular-nums",
218
- children: a(e.dropOffRate)
217
+ children: O(e.dropOffRate)
219
218
  })
220
219
  ]
221
220
  }, e.stepId)) })]
@@ -223,16 +222,16 @@ function b() {
223
222
  })]
224
223
  })
225
224
  ]
226
- }) : /* @__PURE__ */ f("div", {
225
+ }) : /* @__PURE__ */ u("div", {
227
226
  className: "p-3 sm:p-6",
228
- children: /* @__PURE__ */ f(_, {
227
+ children: /* @__PURE__ */ u(h, {
229
228
  illustration: "empty-data",
230
- title: x("analyticsDashboard.noData", "No analytics data available"),
231
- description: x("analyticsDashboard.noDataHint", "Analytics appear once this tour has been published and seen by users. Publish the tour and check back after it starts collecting views.")
229
+ title: _("analyticsDashboard.noData", "No analytics data available"),
230
+ description: _("analyticsDashboard.noDataHint", "Analytics appear once this tour has been published and seen by users. Publish the tour and check back after it starts collecting views.")
232
231
  })
233
232
  });
234
233
  }
235
234
  //#endregion
236
- export { b as AnalyticsDashboardPage };
235
+ export { _ as AnalyticsDashboardPage };
237
236
 
238
237
  //# sourceMappingURL=AnalyticsDashboardPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsDashboardPage.js","names":[],"sources":["../../../src/tours/pages/AnalyticsDashboardPage.tsx"],"sourcesContent":["import { useCallback, useEffect } from 'react';\nimport { useParams } from 'react-router';\nimport { BarChart3, TrendingUp, Users, Timer } from 'lucide-react';\nimport {\n GlassCard,\n EmphasisPanel,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useTourAnalytics } from '../hooks/useTourAnalytics';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport { formatNumber, formatPercentage, formatDuration } from '../utils';\n\n/**\n * Analytics dashboard page\n * Display tour performance metrics and charts\n */\nexport function AnalyticsDashboardPage() {\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\n const { tourId } = useParams();\n const { hasPermission, isLoading: permissionsLoading } = useToursPermissionAccess();\n const canViewAnalytics = hasPermission(TOUR_PERMISSIONS.TOUR_ANALYTICS_READ);\n\n const { analytics, loading, fetchAnalytics, getCompletionRate, getSkipRate } =\n useTourAnalytics(tourId);\n\n useEffect(() => {\n if (permissionsLoading || !canViewAnalytics) return;\n fetchAnalytics();\n }, [fetchAnalytics, permissionsLoading, canViewAnalytics]);\n\n if (!permissionsLoading && !canViewAnalytics) {\n return (\n <div className=\"flex items-center justify-center h-full p-3 sm:p-6\">\n <div className=\"text-center\">\n <h2 className=\"text-lg font-semibold text-text-primary mb-2\">\n {tr('analyticsDashboard.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n 'analyticsDashboard.noPermission',\n 'You do not have permission to view tour analytics.'\n )}\n </p>\n </div>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <p className=\"text-text-secondary\">\n {tr('analyticsDashboard.loading', 'Loading analytics...')}\n </p>\n </div>\n );\n }\n\n if (!analytics) {\n return (\n <div className=\"p-3 sm:p-6\">\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tr('analyticsDashboard.noData', 'No analytics data available')}\n description={tr(\n 'analyticsDashboard.noDataHint',\n 'Analytics appear once this tour has been published and seen by users. Publish the tour and check back after it starts collecting views.'\n )}\n />\n </div>\n );\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\">\n {tr('analyticsDashboard.title', 'Tour Analytics')}\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {tr('analyticsDashboard.subtitle', 'Performance metrics and insights')}\n </p>\n </div>\n\n <PagePurpose>\n {tr(\n 'analyticsDashboard.purpose',\n 'See how this specific tour is performing: how many people viewed it, how many finished versus skipped, and exactly which step they drop off on. Use the per-step drop-off to find and fix the weak point in your walkthrough.'\n )}\n </PagePurpose>\n\n {/* Summary Cards */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\n <GlassCard treatment=\"glass\" className=\"p-4\">\n <div className=\"flex items-center gap-3 mb-2\">\n <div className=\"p-2 bg-action-primary-bg/10 rounded-md\">\n <Users className=\"text-primary\" size={20} />\n </div>\n <span className=\"text-sm text-text-secondary\">\n {tr('analyticsDashboard.totalViews', 'Total Views')}\n </span>\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">\n {formatNumber(analytics.totalViews)}\n </div>\n </GlassCard>\n\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-3 mb-2\">\n <div className=\"p-2 bg-success/10 rounded-md\">\n <TrendingUp className=\"text-success\" size={20} />\n </div>\n <span className=\"text-sm text-text-secondary\">\n {tr('analyticsDashboard.completionRate', 'Completion Rate')}\n </span>\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">\n {formatPercentage(getCompletionRate())}\n </div>\n </GlassCard>\n\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-3 mb-2\">\n <div className=\"p-2 bg-warning/10 rounded-md\">\n <BarChart3 className=\"text-warning\" size={20} />\n </div>\n <span className=\"text-sm text-text-secondary\">\n {tr('analyticsDashboard.skipRate', 'Skip Rate')}\n </span>\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">{formatPercentage(getSkipRate())}</div>\n </GlassCard>\n\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-3 mb-2\">\n <div className=\"p-2 bg-info/10 rounded-md\">\n <Timer className=\"text-info\" size={20} />\n </div>\n <span className=\"text-sm text-text-secondary\">\n {tr('analyticsDashboard.avgDuration', 'Avg Duration')}\n </span>\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">\n {formatDuration(analytics.averageDuration)}\n </div>\n </GlassCard>\n </div>\n\n {/* Device Breakdown — the key soft-glow data-viz zone */}\n <EmphasisPanel className=\"p-4 sm:p-6\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {tr('analyticsDashboard.deviceBreakdown', 'Device Breakdown')}\n </h2>\n <div className=\"space-y-3\">\n {analytics.byDeviceType.map((device) => (\n <div key={device.deviceType}>\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-sm capitalize\">{device.deviceType}</span>\n <span className=\"text-sm text-text-secondary tabular-nums\">\n {formatNumber(device.count)} views ({formatPercentage(device.completionRate)})\n </span>\n </div>\n <div className=\"w-full bg-bg-sunken rounded-full h-2\">\n <div\n className=\"bg-action-primary-bg h-2 rounded-full shadow-[var(--shadow-pop)]\"\n style={{ width: `${device.completionRate}%` }}\n />\n </div>\n </div>\n ))}\n </div>\n </EmphasisPanel>\n\n {/* Step Analytics */}\n {analytics.stepAnalytics && analytics.stepAnalytics.length > 0 && (\n <GlassCard treatment=\"plain\" className=\"p-4 sm:p-6 border-border-seam\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {tr('analyticsDashboard.stepPerformance', 'Step Performance')}\n </h2>\n <div className=\"overflow-x-auto\">\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b border-border-seam\">\n <th className=\"text-left py-2 px-4 text-sm font-medium text-text-secondary\">\n {tr('analyticsDashboard.tableStep', 'Step')}\n </th>\n <th className=\"text-right py-2 px-4 text-sm font-medium text-text-secondary\">\n {tr('analyticsDashboard.tableViews', 'Views')}\n </th>\n <th className=\"text-right py-2 px-4 text-sm font-medium text-text-secondary\">\n {tr('analyticsDashboard.tableCompletions', 'Completions')}\n </th>\n <th className=\"text-right py-2 px-4 text-sm font-medium text-text-secondary\">\n {tr('analyticsDashboard.tableDropOffRate', 'Drop-off Rate')}\n </th>\n </tr>\n </thead>\n <tbody>\n {analytics.stepAnalytics.map((step) => (\n <tr key={step.stepId} className=\"border-b border-border-seam\">\n <td className=\"py-2 px-4 text-sm\">\n {tr('analyticsDashboard.stepLabel', 'Step')} {step.stepOrder}\n </td>\n <td className=\"text-right py-2 px-4 text-sm tabular-nums\">\n {formatNumber(step.views)}\n </td>\n <td className=\"text-right py-2 px-4 text-sm tabular-nums\">\n {formatNumber(step.completions)}\n </td>\n <td className=\"text-right py-2 px-4 text-sm tabular-nums\">\n {formatPercentage(step.dropOffRate)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </GlassCard>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AnalyticsDashboardPage.js","names":[],"sources":["../../../src/tours/pages/AnalyticsDashboardPage.tsx"],"sourcesContent":["import { useEffect } from 'react';\nimport { useParams } from 'react-router';\nimport { BarChart3, TrendingUp, Users, Timer } from 'lucide-react';\nimport {\n GlassCard,\n EmphasisPanel,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useToursI18n } from '../i18n';\nimport { useTourAnalytics } from '../hooks/useTourAnalytics';\nimport { useToursPermissionAccess } from '../hooks/useToursPermissionAccess';\nimport { TOUR_PERMISSIONS } from '../../constants/permissions';\nimport { useToursFormatters } from '../utils';\n\n/**\n * Analytics dashboard page\n * Display tour performance metrics and charts\n */\nexport function AnalyticsDashboardPage() {\n const { tr } = useToursI18n();\n\n const { tourId } = useParams();\n const { hasPermission, isLoading: permissionsLoading } = useToursPermissionAccess();\n const canViewAnalytics = hasPermission(TOUR_PERMISSIONS.TOUR_ANALYTICS_READ);\n\n const { analytics, loading, fetchAnalytics, getCompletionRate, getSkipRate } =\n useTourAnalytics(tourId);\n const { formatNumber, formatPercentage, formatDuration } = useToursFormatters();\n\n useEffect(() => {\n if (permissionsLoading || !canViewAnalytics) return;\n fetchAnalytics();\n }, [fetchAnalytics, permissionsLoading, canViewAnalytics]);\n\n if (!permissionsLoading && !canViewAnalytics) {\n return (\n <div className=\"flex items-center justify-center h-full p-3 sm:p-6\">\n <div className=\"text-center\">\n <h2 className=\"text-lg font-semibold text-text-primary mb-2\">\n {tr('analyticsDashboard.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n 'analyticsDashboard.noPermission',\n 'You do not have permission to view tour analytics.'\n )}\n </p>\n </div>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <p className=\"text-text-secondary\">\n {tr('analyticsDashboard.loading', 'Loading analytics...')}\n </p>\n </div>\n );\n }\n\n if (!analytics) {\n return (\n <div className=\"p-3 sm:p-6\">\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tr('analyticsDashboard.noData', 'No analytics data available')}\n description={tr(\n 'analyticsDashboard.noDataHint',\n 'Analytics appear once this tour has been published and seen by users. Publish the tour and check back after it starts collecting views.'\n )}\n />\n </div>\n );\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\">\n {tr('analyticsDashboard.title', 'Tour Analytics')}\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {tr('analyticsDashboard.subtitle', 'Performance metrics and insights')}\n </p>\n </div>\n\n <PagePurpose>\n {tr(\n 'analyticsDashboard.purpose',\n 'See how this specific tour is performing: how many people viewed it, how many finished versus skipped, and exactly which step they drop off on. Use the per-step drop-off to find and fix the weak point in your walkthrough.'\n )}\n </PagePurpose>\n\n {/* Summary Cards */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\">\n <GlassCard treatment=\"glass\" className=\"p-4\">\n <div className=\"flex items-center gap-3 mb-2\">\n <div className=\"p-2 bg-action-primary-bg/10 rounded-md\">\n <Users className=\"text-primary\" size={20} />\n </div>\n <span className=\"text-sm text-text-secondary\">\n {tr('analyticsDashboard.totalViews', 'Total Views')}\n </span>\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">\n {formatNumber(analytics.totalViews)}\n </div>\n </GlassCard>\n\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-3 mb-2\">\n <div className=\"p-2 bg-success/10 rounded-md\">\n <TrendingUp className=\"text-success\" size={20} />\n </div>\n <span className=\"text-sm text-text-secondary\">\n {tr('analyticsDashboard.completionRate', 'Completion Rate')}\n </span>\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">\n {formatPercentage(getCompletionRate())}\n </div>\n </GlassCard>\n\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-3 mb-2\">\n <div className=\"p-2 bg-warning/10 rounded-md\">\n <BarChart3 className=\"text-warning\" size={20} />\n </div>\n <span className=\"text-sm text-text-secondary\">\n {tr('analyticsDashboard.skipRate', 'Skip Rate')}\n </span>\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">{formatPercentage(getSkipRate())}</div>\n </GlassCard>\n\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-3 mb-2\">\n <div className=\"p-2 bg-info/10 rounded-md\">\n <Timer className=\"text-info\" size={20} />\n </div>\n <span className=\"text-sm text-text-secondary\">\n {tr('analyticsDashboard.avgDuration', 'Avg Duration')}\n </span>\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">\n {formatDuration(analytics.averageDuration)}\n </div>\n </GlassCard>\n </div>\n\n {/* Device Breakdown — the key soft-glow data-viz zone */}\n <EmphasisPanel className=\"p-4 sm:p-6\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {tr('analyticsDashboard.deviceBreakdown', 'Device Breakdown')}\n </h2>\n <div className=\"space-y-3\">\n {analytics.byDeviceType.map((device) => (\n <div key={device.deviceType}>\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-sm\">\n {tr(`deviceType.${device.deviceType}` as const, device.deviceType)}\n </span>\n <span className=\"text-sm text-text-secondary tabular-nums\">\n {formatNumber(device.count)} {tr('analyticsDashboard.deviceViews', 'views')} (\n {formatPercentage(device.completionRate)})\n </span>\n </div>\n <div className=\"w-full bg-bg-sunken rounded-full h-2\">\n <div\n className=\"bg-action-primary-bg h-2 rounded-full shadow-[var(--shadow-pop)]\"\n style={{ width: `${device.completionRate}%` }}\n />\n </div>\n </div>\n ))}\n </div>\n </EmphasisPanel>\n\n {/* Step Analytics */}\n {analytics.stepAnalytics && analytics.stepAnalytics.length > 0 && (\n <GlassCard treatment=\"plain\" className=\"p-4 sm:p-6 border-border-seam\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {tr('analyticsDashboard.stepPerformance', 'Step Performance')}\n </h2>\n <div className=\"overflow-x-auto\">\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b border-border-seam\">\n <th className=\"text-left py-2 px-4 text-sm font-medium text-text-secondary\">\n {tr('analyticsDashboard.tableStep', 'Step')}\n </th>\n <th className=\"text-right py-2 px-4 text-sm font-medium text-text-secondary\">\n {tr('analyticsDashboard.tableViews', 'Views')}\n </th>\n <th className=\"text-right py-2 px-4 text-sm font-medium text-text-secondary\">\n {tr('analyticsDashboard.tableCompletions', 'Completions')}\n </th>\n <th className=\"text-right py-2 px-4 text-sm font-medium text-text-secondary\">\n {tr('analyticsDashboard.tableDropOffRate', 'Drop-off Rate')}\n </th>\n </tr>\n </thead>\n <tbody>\n {analytics.stepAnalytics.map((step) => (\n <tr key={step.stepId} className=\"border-b border-border-seam\">\n <td className=\"py-2 px-4 text-sm\">\n {tr('analyticsDashboard.stepLabel', 'Step')} {step.stepOrder}\n </td>\n <td className=\"text-right py-2 px-4 text-sm tabular-nums\">\n {formatNumber(step.views)}\n </td>\n <td className=\"text-right py-2 px-4 text-sm tabular-nums\">\n {formatNumber(step.completions)}\n </td>\n <td className=\"text-right py-2 px-4 text-sm tabular-nums\">\n {formatPercentage(step.dropOffRate)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </GlassCard>\n )}\n </div>\n );\n}\n"],"mappings":"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"}