@burdenoff/microfe-tours 2026.510.112

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 (164) hide show
  1. package/README.md +342 -0
  2. package/dist/__tests__/setup.d.ts +2 -0
  3. package/dist/__tests__/setup.d.ts.map +1 -0
  4. package/dist/constants/featureFlags.d.ts +25 -0
  5. package/dist/constants/featureFlags.d.ts.map +1 -0
  6. package/dist/constants/featureFlags.js +9 -0
  7. package/dist/constants/featureFlags.js.map +1 -0
  8. package/dist/constants/permissions.d.ts +49 -0
  9. package/dist/constants/permissions.d.ts.map +1 -0
  10. package/dist/constants/permissions.js +38 -0
  11. package/dist/constants/permissions.js.map +1 -0
  12. package/dist/dev/main.d.ts +2 -0
  13. package/dist/dev/main.d.ts.map +1 -0
  14. package/dist/generated/global-operations.d.ts +1270 -0
  15. package/dist/generated/global-operations.d.ts.map +1 -0
  16. package/dist/generated/global-operations.js +650 -0
  17. package/dist/generated/global-operations.js.map +1 -0
  18. package/dist/generated/global-types.d.ts +20448 -0
  19. package/dist/generated/global-types.d.ts.map +1 -0
  20. package/dist/generated/wspace-operations.d.ts +2 -0
  21. package/dist/generated/wspace-operations.d.ts.map +1 -0
  22. package/dist/generated/wspace-types.d.ts +53398 -0
  23. package/dist/generated/wspace-types.d.ts.map +1 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +6 -0
  27. package/dist/tours/ToursAdminRoot.d.ts +16 -0
  28. package/dist/tours/ToursAdminRoot.d.ts.map +1 -0
  29. package/dist/tours/ToursAdminRoot.js +42 -0
  30. package/dist/tours/ToursAdminRoot.js.map +1 -0
  31. package/dist/tours/ToursAdminRoutes.d.ts +12 -0
  32. package/dist/tours/ToursAdminRoutes.d.ts.map +1 -0
  33. package/dist/tours/ToursAdminRoutes.js +109 -0
  34. package/dist/tours/ToursAdminRoutes.js.map +1 -0
  35. package/dist/tours/ToursRoot.d.ts +10 -0
  36. package/dist/tours/ToursRoot.d.ts.map +1 -0
  37. package/dist/tours/ToursRoot.js +1 -0
  38. package/dist/tours/ToursRoutes.d.ts +8 -0
  39. package/dist/tours/ToursRoutes.d.ts.map +1 -0
  40. package/dist/tours/ToursUserRoot.d.ts +15 -0
  41. package/dist/tours/ToursUserRoot.d.ts.map +1 -0
  42. package/dist/tours/ToursUserRoot.js +48 -0
  43. package/dist/tours/ToursUserRoot.js.map +1 -0
  44. package/dist/tours/ToursUserRoutes.d.ts +15 -0
  45. package/dist/tours/ToursUserRoutes.d.ts.map +1 -0
  46. package/dist/tours/ToursUserRoutes.js +66 -0
  47. package/dist/tours/ToursUserRoutes.js.map +1 -0
  48. package/dist/tours/components/RouteHelpers.d.ts +33 -0
  49. package/dist/tours/components/RouteHelpers.d.ts.map +1 -0
  50. package/dist/tours/components/RouteHelpers.js +75 -0
  51. package/dist/tours/components/RouteHelpers.js.map +1 -0
  52. package/dist/tours/components/ToursAdminNavRegistrar.d.ts +25 -0
  53. package/dist/tours/components/ToursAdminNavRegistrar.d.ts.map +1 -0
  54. package/dist/tours/components/ToursAdminNavRegistrar.js +60 -0
  55. package/dist/tours/components/ToursAdminNavRegistrar.js.map +1 -0
  56. package/dist/tours/components/ui.d.ts +2 -0
  57. package/dist/tours/components/ui.d.ts.map +1 -0
  58. package/dist/tours/hooks/useMediaLibrary.d.ts +22 -0
  59. package/dist/tours/hooks/useMediaLibrary.d.ts.map +1 -0
  60. package/dist/tours/hooks/useMediaLibrary.js +82 -0
  61. package/dist/tours/hooks/useMediaLibrary.js.map +1 -0
  62. package/dist/tours/hooks/useStepSequencer.d.ts +20 -0
  63. package/dist/tours/hooks/useStepSequencer.d.ts.map +1 -0
  64. package/dist/tours/hooks/useStepSequencer.js +53 -0
  65. package/dist/tours/hooks/useStepSequencer.js.map +1 -0
  66. package/dist/tours/hooks/useTourAnalytics.d.ts +32 -0
  67. package/dist/tours/hooks/useTourAnalytics.d.ts.map +1 -0
  68. package/dist/tours/hooks/useTourAnalytics.js +70 -0
  69. package/dist/tours/hooks/useTourAnalytics.js.map +1 -0
  70. package/dist/tours/hooks/useTourBuilder.d.ts +61 -0
  71. package/dist/tours/hooks/useTourBuilder.d.ts.map +1 -0
  72. package/dist/tours/hooks/useTourBuilder.js +192 -0
  73. package/dist/tours/hooks/useTourBuilder.js.map +1 -0
  74. package/dist/tours/hooks/useTourLifecycle.d.ts +22 -0
  75. package/dist/tours/hooks/useTourLifecycle.d.ts.map +1 -0
  76. package/dist/tours/hooks/useTourLifecycle.js +28 -0
  77. package/dist/tours/hooks/useTourLifecycle.js.map +1 -0
  78. package/dist/tours/hooks/useTourPreview.d.ts +33 -0
  79. package/dist/tours/hooks/useTourPreview.d.ts.map +1 -0
  80. package/dist/tours/hooks/useTourPreview.js +70 -0
  81. package/dist/tours/hooks/useTourPreview.js.map +1 -0
  82. package/dist/tours/hooks/useToursList.d.ts +30 -0
  83. package/dist/tours/hooks/useToursList.d.ts.map +1 -0
  84. package/dist/tours/hooks/useToursList.js +49 -0
  85. package/dist/tours/hooks/useToursList.js.map +1 -0
  86. package/dist/tours/hooks/useToursPermissionAccess.d.ts +16 -0
  87. package/dist/tours/hooks/useToursPermissionAccess.d.ts.map +1 -0
  88. package/dist/tours/hooks/useToursPermissionAccess.js +9 -0
  89. package/dist/tours/hooks/useToursPermissionAccess.js.map +1 -0
  90. package/dist/tours/i18n.d.ts +172 -0
  91. package/dist/tours/i18n.d.ts.map +1 -0
  92. package/dist/tours/i18n.js +175 -0
  93. package/dist/tours/i18n.js.map +1 -0
  94. package/dist/tours/index.d.ts +21 -0
  95. package/dist/tours/index.d.ts.map +1 -0
  96. package/dist/tours/index.js +5 -0
  97. package/dist/tours/pages/AnalyticsDashboardPage.d.ts +6 -0
  98. package/dist/tours/pages/AnalyticsDashboardPage.d.ts.map +1 -0
  99. package/dist/tours/pages/AnalyticsDashboardPage.js +230 -0
  100. package/dist/tours/pages/AnalyticsDashboardPage.js.map +1 -0
  101. package/dist/tours/pages/MediaLibraryPage.d.ts +6 -0
  102. package/dist/tours/pages/MediaLibraryPage.d.ts.map +1 -0
  103. package/dist/tours/pages/MediaLibraryPage.js +195 -0
  104. package/dist/tours/pages/MediaLibraryPage.js.map +1 -0
  105. package/dist/tours/pages/MyToursPage.d.ts +11 -0
  106. package/dist/tours/pages/MyToursPage.d.ts.map +1 -0
  107. package/dist/tours/pages/MyToursPage.js +103 -0
  108. package/dist/tours/pages/MyToursPage.js.map +1 -0
  109. package/dist/tours/pages/MyToursProgressPage.d.ts +6 -0
  110. package/dist/tours/pages/MyToursProgressPage.d.ts.map +1 -0
  111. package/dist/tours/pages/MyToursProgressPage.js +142 -0
  112. package/dist/tours/pages/MyToursProgressPage.js.map +1 -0
  113. package/dist/tours/pages/SchedulerPage.d.ts +6 -0
  114. package/dist/tours/pages/SchedulerPage.d.ts.map +1 -0
  115. package/dist/tours/pages/SchedulerPage.js +231 -0
  116. package/dist/tours/pages/SchedulerPage.js.map +1 -0
  117. package/dist/tours/pages/StepEditorPage.d.ts +7 -0
  118. package/dist/tours/pages/StepEditorPage.d.ts.map +1 -0
  119. package/dist/tours/pages/StepEditorPage.js +586 -0
  120. package/dist/tours/pages/StepEditorPage.js.map +1 -0
  121. package/dist/tours/pages/SystemAnalyticsPage.d.ts +6 -0
  122. package/dist/tours/pages/SystemAnalyticsPage.d.ts.map +1 -0
  123. package/dist/tours/pages/SystemAnalyticsPage.js +155 -0
  124. package/dist/tours/pages/SystemAnalyticsPage.js.map +1 -0
  125. package/dist/tours/pages/TemplateLibraryPage.d.ts +6 -0
  126. package/dist/tours/pages/TemplateLibraryPage.d.ts.map +1 -0
  127. package/dist/tours/pages/TemplateLibraryPage.js +207 -0
  128. package/dist/tours/pages/TemplateLibraryPage.js.map +1 -0
  129. package/dist/tours/pages/TourBuilderPage.d.ts +6 -0
  130. package/dist/tours/pages/TourBuilderPage.d.ts.map +1 -0
  131. package/dist/tours/pages/TourBuilderPage.js +363 -0
  132. package/dist/tours/pages/TourBuilderPage.js.map +1 -0
  133. package/dist/tours/pages/TourPreviewPage.d.ts +6 -0
  134. package/dist/tours/pages/TourPreviewPage.d.ts.map +1 -0
  135. package/dist/tours/pages/TourPreviewPage.js +239 -0
  136. package/dist/tours/pages/TourPreviewPage.js.map +1 -0
  137. package/dist/tours/pages/ToursListPage.d.ts +6 -0
  138. package/dist/tours/pages/ToursListPage.d.ts.map +1 -0
  139. package/dist/tours/pages/ToursListPage.js +310 -0
  140. package/dist/tours/pages/ToursListPage.js.map +1 -0
  141. package/dist/tours/providers/ToursProvider.d.ts +27 -0
  142. package/dist/tours/providers/ToursProvider.d.ts.map +1 -0
  143. package/dist/tours/providers/ToursProvider.js +28 -0
  144. package/dist/tours/providers/ToursProvider.js.map +1 -0
  145. package/dist/tours/store/toursStore.d.ts +39 -0
  146. package/dist/tours/store/toursStore.d.ts.map +1 -0
  147. package/dist/tours/store/toursStore.js +143 -0
  148. package/dist/tours/store/toursStore.js.map +1 -0
  149. package/dist/tours/types/index.d.ts +350 -0
  150. package/dist/tours/types/index.d.ts.map +1 -0
  151. package/dist/tours/utils/cn.d.ts +8 -0
  152. package/dist/tours/utils/cn.d.ts.map +1 -0
  153. package/dist/tours/utils/index.d.ts +102 -0
  154. package/dist/tours/utils/index.d.ts.map +1 -0
  155. package/dist/tours/utils/index.js +28 -0
  156. package/dist/tours/utils/index.js.map +1 -0
  157. package/dist/tours/utils/joinPath.d.ts +9 -0
  158. package/dist/tours/utils/joinPath.d.ts.map +1 -0
  159. package/dist/tours/utils/joinPath.js +8 -0
  160. package/dist/tours/utils/joinPath.js.map +1 -0
  161. package/dist/utils/nativeBridge.d.ts +3 -0
  162. package/dist/utils/nativeBridge.d.ts.map +1 -0
  163. package/dist/utils/nativeBridge.js +2 -0
  164. package/package.json +114 -0
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tours Microfrontend - Root Export
3
+ * Re-exports from the main tours module for build-time composition
4
+ */
5
+ export * from './tours';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import { useToursContext as e } from "./tours/providers/ToursProvider.js";
2
+ import { useToursStore as t } from "./tours/store/toursStore.js";
3
+ import { ToursAdminRoot as n } from "./tours/ToursAdminRoot.js";
4
+ import { ToursUserRoot as r } from "./tours/ToursUserRoot.js";
5
+ import "./tours/index.js";
6
+ export { n as ToursAdminRoot, n as ToursRoot, r as ToursUserRoot, e as useToursContext, t as useToursStore };
@@ -0,0 +1,16 @@
1
+ import { FC } from 'react';
2
+ import { ToursRootProps } from './types';
3
+
4
+ /**
5
+ * Admin-facing root component for the Tours microfrontend.
6
+ *
7
+ * Mounts the full authoring suite (CRUD, builder, step editor, media
8
+ * library, analytics, templates, scheduler, preview). Nav-item registration
9
+ * lives in `ToursAdminNavRegistrar` so it can consult feature flags from
10
+ * inside the provider subtree; only items whose flags are enabled are
11
+ * registered with the shell. Consumed by `admin-app`.
12
+ *
13
+ * Pair with `ToursUserRoot` for user shells.
14
+ */
15
+ export declare const ToursAdminRoot: FC<ToursRootProps>;
16
+ //# sourceMappingURL=ToursAdminRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToursAdminRoot.d.ts","sourceRoot":"","sources":["../../src/tours/ToursAdminRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAOhC,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,SAAS,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,cAAc,CAqC7C,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { ToursAdminNavRegistrar as e } from "./components/ToursAdminNavRegistrar.js";
2
+ import { ToursProvider as t } from "./providers/ToursProvider.js";
3
+ import { ToursAdminRoutes as n } from "./ToursAdminRoutes.js";
4
+ import { useEffect as r } from "react";
5
+ import { ErrorBoundary as i } from "@burdenoff/fe-libs/shared/components";
6
+ import { FeatureFlagProvider as a } from "@burdenoff/fe-libs/shared/feature-flags";
7
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
8
+ //#region src/tours/ToursAdminRoot.tsx
9
+ var c = (c) => {
10
+ let { basePath: l = "/", registerNavItems: u, registerFooterItems: d, workspaceId: f } = c;
11
+ return r(() => {
12
+ if (d) return d([{
13
+ id: "tours-status",
14
+ label: "Product Tours Ready",
15
+ type: "status",
16
+ order: 10,
17
+ section: "left"
18
+ }]);
19
+ }, [d]), /* @__PURE__ */ o(a, {
20
+ workspaceId: f ?? null,
21
+ gateway: "global",
22
+ defaultEnabled: !1,
23
+ children: /* @__PURE__ */ s(i, {
24
+ fallback: /* @__PURE__ */ o("div", {
25
+ className: "p-6 text-center text-text-secondary",
26
+ children: "Something went wrong loading this module. Please refresh the page."
27
+ }),
28
+ children: [u && /* @__PURE__ */ o(e, {
29
+ basePath: l,
30
+ registerNavItems: u
31
+ }), /* @__PURE__ */ o(t, {
32
+ ...c,
33
+ variant: "admin",
34
+ children: /* @__PURE__ */ o(n, {})
35
+ })]
36
+ })
37
+ });
38
+ };
39
+ //#endregion
40
+ export { c as ToursAdminRoot };
41
+
42
+ //# sourceMappingURL=ToursAdminRoot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToursAdminRoot.js","names":[],"sources":["../../src/tours/ToursAdminRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect } from 'react';\nimport { ErrorBoundary } from '@burdenoff/fe-libs/shared/components';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { ToursAdminNavRegistrar } from './components/ToursAdminNavRegistrar';\nimport { ToursProvider } from './providers/ToursProvider';\nimport { ToursAdminRoutes } from './ToursAdminRoutes';\nimport type { FooterItem, ToursRootProps } from './types';\n\n/**\n * Admin-facing root component for the Tours microfrontend.\n *\n * Mounts the full authoring suite (CRUD, builder, step editor, media\n * library, analytics, templates, scheduler, preview). Nav-item registration\n * lives in `ToursAdminNavRegistrar` so it can consult feature flags from\n * inside the provider subtree; only items whose flags are enabled are\n * registered with the shell. Consumed by `admin-app`.\n *\n * Pair with `ToursUserRoot` for user shells.\n */\nexport const ToursAdminRoot: FC<ToursRootProps> = (props) => {\n const { basePath = '/', registerNavItems, registerFooterItems, workspaceId } = props;\n\n useEffect(() => {\n if (!registerFooterItems) return;\n\n const footerItems: FooterItem[] = [\n {\n id: 'tours-status',\n label: 'Product Tours Ready',\n type: 'status',\n order: 10,\n section: 'left',\n },\n ];\n\n return registerFooterItems(footerItems);\n }, [registerFooterItems]);\n\n return (\n <FeatureFlagProvider workspaceId={workspaceId ?? null} gateway=\"global\" defaultEnabled={false}>\n <ErrorBoundary\n fallback={\n <div className=\"p-6 text-center text-text-secondary\">\n Something went wrong loading this module. Please refresh the page.\n </div>\n }\n >\n {registerNavItems && (\n <ToursAdminNavRegistrar basePath={basePath} registerNavItems={registerNavItems} />\n )}\n <ToursProvider {...props} variant=\"admin\">\n <ToursAdminRoutes />\n </ToursProvider>\n </ErrorBoundary>\n </FeatureFlagProvider>\n );\n};\n"],"mappings":";;;;;;;;AAoBA,IAAa,KAAsC,MAAU;CAC3D,IAAM,EAAE,cAAW,KAAK,qBAAkB,wBAAqB,mBAAgB;AAkB/E,QAhBA,QAAgB;AACT,QAYL,QAAO,EAV2B,CAChC;GACE,IAAI;GACJ,OAAO;GACP,MAAM;GACN,OAAO;GACP,SAAS;GACV,CACF,CAEsC;IACtC,CAAC,EAAoB,CAAC,EAGvB,kBAAC,GAAD;EAAqB,aAAa,KAAe;EAAM,SAAQ;EAAS,gBAAgB;YACtF,kBAAC,GAAD;GACE,UACE,kBAAC,OAAD;IAAK,WAAU;cAAsC;IAE/C,CAAA;aAJV,CAOG,KACC,kBAAC,GAAD;IAAkC;IAA4B;IAAoB,CAAA,EAEpF,kBAAC,GAAD;IAAe,GAAI;IAAO,SAAQ;cAChC,kBAAC,GAAD,EAAoB,CAAA;IACN,CAAA,CACF;;EACI,CAAA"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Admin-facing routes for the Tours microfrontend.
3
+ *
4
+ * Exposes the full authoring surface — CRUD, builder, step editor, media
5
+ * library, analytics, templates, scheduler, preview. Mounted by
6
+ * `ToursAdminRoot` from `admin-app`.
7
+ *
8
+ * `ToursRoutes` is kept as a back-compat alias for callers that haven't
9
+ * migrated yet.
10
+ */
11
+ export declare function ToursAdminRoutes(): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=ToursAdminRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToursAdminRoutes.d.ts","sourceRoot":"","sources":["../../src/tours/ToursAdminRoutes.tsx"],"names":[],"mappings":"AAkGA;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,4CA4C/B"}
@@ -0,0 +1,109 @@
1
+ import { TOURS_FEATURES as e } from "../constants/featureFlags.js";
2
+ import { LazyErrorBoundary as t, PageLoader as n } from "./components/RouteHelpers.js";
3
+ import { ToursListPage as r } from "./pages/ToursListPage.js";
4
+ import { Suspense as i, lazy as a, useEffect as o } from "react";
5
+ import { FeatureGate as s } from "@burdenoff/fe-libs/shared/feature-flags";
6
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
+ import { Navigate as u, Route as d, Routes as f, useNavigate as p } from "react-router-dom";
8
+ //#region src/tours/ToursAdminRoutes.tsx
9
+ var m = a(() => import("./pages/TourBuilderPage.js").then((e) => ({ default: e.TourBuilderPage }))), h = a(() => import("./pages/StepEditorPage.js").then((e) => ({ default: e.StepEditorPage }))), g = a(() => import("./pages/MediaLibraryPage.js").then((e) => ({ default: e.MediaLibraryPage }))), _ = a(() => import("./pages/AnalyticsDashboardPage.js").then((e) => ({ default: e.AnalyticsDashboardPage }))), v = a(() => import("./pages/SystemAnalyticsPage.js").then((e) => ({ default: e.SystemAnalyticsPage }))), y = a(() => import("./pages/TemplateLibraryPage.js").then((e) => ({ default: e.TemplateLibraryPage }))), b = a(() => import("./pages/SchedulerPage.js").then((e) => ({ default: e.SchedulerPage }))), x = a(() => import("./pages/TourPreviewPage.js").then((e) => ({ default: e.TourPreviewPage }))), S = 2e3;
10
+ function C({ redirectTo: e }) {
11
+ let t = p();
12
+ return o(() => {
13
+ let n = setTimeout(() => {
14
+ t(e, { replace: !0 });
15
+ }, S);
16
+ return () => clearTimeout(n);
17
+ }, [t, e]), /* @__PURE__ */ c("div", {
18
+ className: "flex h-full items-center justify-center p-8 text-center",
19
+ role: "alert",
20
+ children: /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h2", {
21
+ className: "text-lg font-semibold mb-2 text-text-primary",
22
+ children: "Feature Not Available"
23
+ }), /* @__PURE__ */ c("p", {
24
+ className: "text-sm text-text-secondary",
25
+ children: "This feature is not currently enabled. Redirecting you to the tours list…"
26
+ })] })
27
+ });
28
+ }
29
+ function w(e, t, { defaultValue: n = !1, redirectTo: r = "../list" } = {}) {
30
+ return /* @__PURE__ */ c(s, {
31
+ flag: e,
32
+ defaultValue: n,
33
+ fallback: /* @__PURE__ */ c(C, { redirectTo: r }),
34
+ children: t
35
+ });
36
+ }
37
+ function T() {
38
+ return /* @__PURE__ */ c(t, { children: /* @__PURE__ */ c(i, {
39
+ fallback: /* @__PURE__ */ c(n, {}),
40
+ children: /* @__PURE__ */ l(f, { children: [
41
+ /* @__PURE__ */ c(d, {
42
+ index: !0,
43
+ element: /* @__PURE__ */ c(u, {
44
+ to: "list",
45
+ replace: !0
46
+ })
47
+ }),
48
+ /* @__PURE__ */ c(d, {
49
+ path: "list",
50
+ element: /* @__PURE__ */ c(r, {})
51
+ }),
52
+ /* @__PURE__ */ c(d, {
53
+ path: "new",
54
+ element: /* @__PURE__ */ c(m, {})
55
+ }),
56
+ /* @__PURE__ */ c(d, {
57
+ path: ":tourId/edit",
58
+ element: /* @__PURE__ */ c(m, {})
59
+ }),
60
+ /* @__PURE__ */ c(d, {
61
+ path: ":tourId/steps",
62
+ element: /* @__PURE__ */ c(h, {})
63
+ }),
64
+ /* @__PURE__ */ c(d, {
65
+ path: ":tourId/steps/:stepId",
66
+ element: /* @__PURE__ */ c(h, {})
67
+ }),
68
+ /* @__PURE__ */ c(d, {
69
+ path: "media",
70
+ element: w(e.MEDIA, /* @__PURE__ */ c(g, {}))
71
+ }),
72
+ /* @__PURE__ */ c(d, {
73
+ path: "analytics",
74
+ element: /* @__PURE__ */ c(v, {})
75
+ }),
76
+ /* @__PURE__ */ c(d, {
77
+ path: ":tourId/analytics",
78
+ element: /* @__PURE__ */ c(_, {})
79
+ }),
80
+ /* @__PURE__ */ c(d, {
81
+ path: "templates",
82
+ element: /* @__PURE__ */ c(y, {})
83
+ }),
84
+ /* @__PURE__ */ c(d, {
85
+ path: "templates/:templateId",
86
+ element: /* @__PURE__ */ c(y, {})
87
+ }),
88
+ /* @__PURE__ */ c(d, {
89
+ path: ":tourId/schedule",
90
+ element: /* @__PURE__ */ c(b, {})
91
+ }),
92
+ /* @__PURE__ */ c(d, {
93
+ path: ":tourId/preview",
94
+ element: /* @__PURE__ */ c(x, {})
95
+ }),
96
+ /* @__PURE__ */ c(d, {
97
+ path: "*",
98
+ element: /* @__PURE__ */ c(u, {
99
+ to: "list",
100
+ replace: !0
101
+ })
102
+ })
103
+ ] })
104
+ }) });
105
+ }
106
+ //#endregion
107
+ export { T as ToursAdminRoutes };
108
+
109
+ //# sourceMappingURL=ToursAdminRoutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToursAdminRoutes.js","names":[],"sources":["../../src/tours/ToursAdminRoutes.tsx"],"sourcesContent":["import { lazy, Suspense, useEffect } from 'react';\nimport { Navigate, Route, Routes, useNavigate } from 'react-router-dom';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\n\nimport { TOURS_FEATURES, type ToursFeatureKey } from '../constants/featureFlags';\nimport { LazyErrorBoundary, PageLoader } from './components/RouteHelpers';\n// Eager load - main entry point for the microfrontend\nimport { ToursListPage } from './pages/ToursListPage';\n\n// Lazy loaded pages - loaded on demand for better initial bundle size\nconst TourBuilderPage = lazy(() =>\n import('./pages/TourBuilderPage').then((m) => ({ default: m.TourBuilderPage }))\n);\nconst StepEditorPage = lazy(() =>\n import('./pages/StepEditorPage').then((m) => ({ default: m.StepEditorPage }))\n);\nconst MediaLibraryPage = lazy(() =>\n import('./pages/MediaLibraryPage').then((m) => ({ default: m.MediaLibraryPage }))\n);\nconst AnalyticsDashboardPage = lazy(() =>\n import('./pages/AnalyticsDashboardPage').then((m) => ({ default: m.AnalyticsDashboardPage }))\n);\nconst SystemAnalyticsPage = lazy(() =>\n import('./pages/SystemAnalyticsPage').then((m) => ({ default: m.SystemAnalyticsPage }))\n);\nconst TemplateLibraryPage = lazy(() =>\n import('./pages/TemplateLibraryPage').then((m) => ({ default: m.TemplateLibraryPage }))\n);\nconst SchedulerPage = lazy(() =>\n import('./pages/SchedulerPage').then((m) => ({ default: m.SchedulerPage }))\n);\nconst TourPreviewPage = lazy(() =>\n import('./pages/TourPreviewPage').then((m) => ({ default: m.TourPreviewPage }))\n);\n\n/**\n * Fallback shown when a feature-gated route is disabled. Auto-redirects to\n * the given path after a short delay so users are never stranded on a dead\n * screen when an admin flips a flag off mid-session. The visible message is\n * kept for ~2s so screen readers reliably process the `role=\"alert\"` live\n * region before the navigation fires (NVDA/JAWS typically need 1–2 seconds\n * to announce a live region, especially if the user is mid-interaction).\n */\nconst FEATURE_DISABLED_REDIRECT_DELAY_MS = 2000;\n\nfunction FeatureDisabledFallback({ redirectTo }: { redirectTo: string }) {\n const navigate = useNavigate();\n\n useEffect(() => {\n const timer = setTimeout(() => {\n navigate(redirectTo, { replace: true });\n }, FEATURE_DISABLED_REDIRECT_DELAY_MS);\n return () => clearTimeout(timer);\n }, [navigate, redirectTo]);\n\n return (\n <div className=\"flex h-full items-center justify-center p-8 text-center\" role=\"alert\">\n <div>\n <h2 className=\"text-lg font-semibold mb-2 text-text-primary\">Feature Not Available</h2>\n <p className=\"text-sm text-text-secondary\">\n This feature is not currently enabled. Redirecting you to the tours list…\n </p>\n </div>\n </div>\n );\n}\n\n/**\n * Helper: wraps a page element in a FeatureGate.\n *\n * defaultValue=false aligns with the backend seed (`defaultValue: false,\n * previewable: true`) — when a flag can't be resolved (missing from seed or\n * gateway unreachable), the feature stays hidden rather than leaking an\n * unreleased surface to users.\n *\n * `redirectTo` is resolved relative to the gated route's URL. All current\n * gated routes sit one level below the tours basePath, so `../list` lands\n * on `/<basePath>/list` (the default admin landing page).\n */\nfunction gated(\n flag: ToursFeatureKey,\n element: React.ReactNode,\n {\n defaultValue = false,\n redirectTo = '../list',\n }: { defaultValue?: boolean; redirectTo?: string } = {}\n): React.ReactElement {\n return (\n <FeatureGate\n flag={flag}\n defaultValue={defaultValue}\n fallback={<FeatureDisabledFallback redirectTo={redirectTo} />}\n >\n {element}\n </FeatureGate>\n );\n}\n\n/**\n * Admin-facing routes for the Tours microfrontend.\n *\n * Exposes the full authoring surface — CRUD, builder, step editor, media\n * library, analytics, templates, scheduler, preview. Mounted by\n * `ToursAdminRoot` from `admin-app`.\n *\n * `ToursRoutes` is kept as a back-compat alias for callers that haven't\n * migrated yet.\n */\nexport function ToursAdminRoutes() {\n return (\n <LazyErrorBoundary>\n <Suspense fallback={<PageLoader />}>\n <Routes>\n {/* Default redirect */}\n <Route index element={<Navigate to=\"list\" replace />} />\n\n {/* Tour List - Eager loaded (main entry point) */}\n <Route path=\"list\" element={<ToursListPage />} />\n\n {/* Tour Builder - Lazy loaded */}\n <Route path=\"new\" element={<TourBuilderPage />} />\n <Route path=\":tourId/edit\" element={<TourBuilderPage />} />\n\n {/* Step Editor - Lazy loaded */}\n <Route path=\":tourId/steps\" element={<StepEditorPage />} />\n <Route path=\":tourId/steps/:stepId\" element={<StepEditorPage />} />\n\n {/* Media Library - gated by tours.media (feature is Partial: upload storage URL is hardcoded, real pipeline pending) */}\n <Route path=\"media\" element={gated(TOURS_FEATURES.MEDIA, <MediaLibraryPage />)} />\n\n {/* System Analytics - un-gated (feature is 100% E2E complete) */}\n <Route path=\"analytics\" element={<SystemAnalyticsPage />} />\n\n {/* Per-tour Analytics - un-gated (feature is 100% E2E complete) */}\n <Route path=\":tourId/analytics\" element={<AnalyticsDashboardPage />} />\n\n {/* Templates - un-gated (feature is 100% E2E complete) */}\n <Route path=\"templates\" element={<TemplateLibraryPage />} />\n <Route path=\"templates/:templateId\" element={<TemplateLibraryPage />} />\n\n {/* Scheduler - un-gated (feature is 100% E2E complete) */}\n <Route path=\":tourId/schedule\" element={<SchedulerPage />} />\n\n {/* Preview - Lazy loaded (not gated) */}\n <Route path=\":tourId/preview\" element={<TourPreviewPage />} />\n\n {/* Catch-all route - redirect to list */}\n <Route path=\"*\" element={<Navigate to=\"list\" replace />} />\n </Routes>\n </Suspense>\n </LazyErrorBoundary>\n );\n}\n"],"mappings":";;;;;;;;AAUA,IAAM,IAAkB,QACtB,OAAO,8BAA2B,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAChF,EACK,IAAiB,QACrB,OAAO,6BAA0B,MAAM,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAC9E,EACK,IAAmB,QACvB,OAAO,+BAA4B,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAClF,EACK,IAAyB,QAC7B,OAAO,qCAAkC,MAAM,OAAO,EAAE,SAAS,EAAE,wBAAwB,EAAE,CAC9F,EACK,IAAsB,QAC1B,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,CACxF,EACK,IAAsB,QAC1B,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,CACxF,EACK,IAAgB,QACpB,OAAO,4BAAyB,MAAM,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CAC5E,EACK,IAAkB,QACtB,OAAO,8BAA2B,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAChF,EAUK,IAAqC;AAE3C,SAAS,EAAwB,EAAE,iBAAsC;CACvE,IAAM,IAAW,GAAa;AAS9B,QAPA,QAAgB;EACd,IAAM,IAAQ,iBAAiB;AAC7B,KAAS,GAAY,EAAE,SAAS,IAAM,CAAC;KACtC,EAAmC;AACtC,eAAa,aAAa,EAAM;IAC/B,CAAC,GAAU,EAAW,CAAC,EAGxB,kBAAC,OAAD;EAAK,WAAU;EAA0D,MAAK;YAC5E,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;GAAI,WAAU;aAA+C;GAA0B,CAAA,EACvF,kBAAC,KAAD;GAAG,WAAU;aAA8B;GAEvC,CAAA,CACA,EAAA,CAAA;EACF,CAAA;;AAgBV,SAAS,EACP,GACA,GACA,EACE,kBAAe,IACf,gBAAa,cACsC,EAAE,EACnC;AACpB,QACE,kBAAC,GAAD;EACQ;EACQ;EACd,UAAU,kBAAC,GAAD,EAAqC,eAAc,CAAA;YAE5D;EACW,CAAA;;AAclB,SAAgB,IAAmB;AACjC,QACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;EAAU,UAAU,kBAAC,GAAD,EAAc,CAAA;YAChC,kBAAC,GAAD,EAAA,UAAA;GAEE,kBAAC,GAAD;IAAO,OAAA;IAAM,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAO,SAAA;KAAU,CAAA;IAAI,CAAA;GAGxD,kBAAC,GAAD;IAAO,MAAK;IAAO,SAAS,kBAAC,GAAD,EAAiB,CAAA;IAAI,CAAA;GAGjD,kBAAC,GAAD;IAAO,MAAK;IAAM,SAAS,kBAAC,GAAD,EAAmB,CAAA;IAAI,CAAA;GAClD,kBAAC,GAAD;IAAO,MAAK;IAAe,SAAS,kBAAC,GAAD,EAAmB,CAAA;IAAI,CAAA;GAG3D,kBAAC,GAAD;IAAO,MAAK;IAAgB,SAAS,kBAAC,GAAD,EAAkB,CAAA;IAAI,CAAA;GAC3D,kBAAC,GAAD;IAAO,MAAK;IAAwB,SAAS,kBAAC,GAAD,EAAkB,CAAA;IAAI,CAAA;GAGnE,kBAAC,GAAD;IAAO,MAAK;IAAQ,SAAS,EAAM,EAAe,OAAO,kBAAC,GAAD,EAAoB,CAAA,CAAC;IAAI,CAAA;GAGlF,kBAAC,GAAD;IAAO,MAAK;IAAY,SAAS,kBAAC,GAAD,EAAuB,CAAA;IAAI,CAAA;GAG5D,kBAAC,GAAD;IAAO,MAAK;IAAoB,SAAS,kBAAC,GAAD,EAA0B,CAAA;IAAI,CAAA;GAGvE,kBAAC,GAAD;IAAO,MAAK;IAAY,SAAS,kBAAC,GAAD,EAAuB,CAAA;IAAI,CAAA;GAC5D,kBAAC,GAAD;IAAO,MAAK;IAAwB,SAAS,kBAAC,GAAD,EAAuB,CAAA;IAAI,CAAA;GAGxE,kBAAC,GAAD;IAAO,MAAK;IAAmB,SAAS,kBAAC,GAAD,EAAiB,CAAA;IAAI,CAAA;GAG7D,kBAAC,GAAD;IAAO,MAAK;IAAkB,SAAS,kBAAC,GAAD,EAAmB,CAAA;IAAI,CAAA;GAG9D,kBAAC,GAAD;IAAO,MAAK;IAAI,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAO,SAAA;KAAU,CAAA;IAAI,CAAA;GACpD,EAAA,CAAA;EACA,CAAA,EACO,CAAA"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Back-compat alias. Use `ToursAdminRoot` directly in new code.
3
+ *
4
+ * `ToursRoot` historically rendered the admin authoring surface; admin-app
5
+ * (and any other shell that imported it) keeps working while we migrate
6
+ * callers to the explicit `ToursAdminRoot` / `ToursUserRoot` naming
7
+ * introduced in BOFF-2391.
8
+ */
9
+ export { ToursAdminRoot as ToursRoot } from './ToursAdminRoot';
10
+ //# sourceMappingURL=ToursRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToursRoot.d.ts","sourceRoot":"","sources":["../../src/tours/ToursRoot.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,IAAI,SAAS,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ import "./ToursAdminRoot.js";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Back-compat re-export. Real implementation lives in `ToursAdminRoutes`.
3
+ * Kept so existing imports of `ToursRoutes` continue to compile while
4
+ * downstream callers migrate to the explicit Admin / User naming
5
+ * (BOFF-2391).
6
+ */
7
+ export { ToursAdminRoutes as ToursRoutes } from './ToursAdminRoutes';
8
+ //# sourceMappingURL=ToursRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToursRoutes.d.ts","sourceRoot":"","sources":["../../src/tours/ToursRoutes.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,gBAAgB,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { FC } from 'react';
2
+ import { ToursRootProps } from './types';
3
+
4
+ /**
5
+ * User-facing root component for the Tours microfrontend.
6
+ *
7
+ * Mounts the read-only "My Tours" + "My Progress" surface for product
8
+ * user shells (vibecontrols-app, and later workspaces-app / bigconsole-app).
9
+ * Registers exactly two nav items; never exposes authoring or governance
10
+ * pages.
11
+ *
12
+ * Pair with `ToursAdminRoot` for the admin shell.
13
+ */
14
+ export declare const ToursUserRoot: FC<ToursRootProps>;
15
+ //# sourceMappingURL=ToursUserRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToursUserRoot.d.ts","sourceRoot":"","sources":["../../src/tours/ToursUserRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAOhC,OAAO,KAAK,EAAW,cAAc,EAAE,MAAM,SAAS,CAAC;AAGvD;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,cAAc,CA2C5C,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { joinPath as e } from "./utils/joinPath.js";
2
+ import { ToursProvider as t } from "./providers/ToursProvider.js";
3
+ import { ToursUserRoutes as n } from "./ToursUserRoutes.js";
4
+ import { useEffect as r } from "react";
5
+ import { ErrorBoundary as i } from "@burdenoff/fe-libs/shared/components";
6
+ import { FeatureFlagProvider as a } from "@burdenoff/fe-libs/shared/feature-flags";
7
+ import { Compass as o, ListChecks as s } from "lucide-react";
8
+ import { jsx as c } from "react/jsx-runtime";
9
+ //#region src/tours/ToursUserRoot.tsx
10
+ var l = (l) => {
11
+ let { basePath: u = "/", registerNavItems: d, workspaceId: f } = l;
12
+ return r(() => {
13
+ if (d) return d([{
14
+ id: "tours-my",
15
+ label: "My Tours",
16
+ path: u,
17
+ icon: /* @__PURE__ */ c(o, { size: 20 }),
18
+ order: 10,
19
+ group: "tours"
20
+ }, {
21
+ id: "tours-my-progress",
22
+ label: "My Progress",
23
+ path: e(u, "progress"),
24
+ icon: /* @__PURE__ */ c(s, { size: 20 }),
25
+ order: 20,
26
+ group: "tours"
27
+ }]);
28
+ }, [d, u]), /* @__PURE__ */ c(a, {
29
+ workspaceId: f ?? null,
30
+ gateway: "global",
31
+ defaultEnabled: !0,
32
+ children: /* @__PURE__ */ c(i, {
33
+ fallback: /* @__PURE__ */ c("div", {
34
+ className: "p-6 text-center text-text-secondary",
35
+ children: "Something went wrong loading this module. Please refresh the page."
36
+ }),
37
+ children: /* @__PURE__ */ c(t, {
38
+ ...l,
39
+ variant: "user",
40
+ children: /* @__PURE__ */ c(n, {})
41
+ })
42
+ })
43
+ });
44
+ };
45
+ //#endregion
46
+ export { l as ToursUserRoot };
47
+
48
+ //# sourceMappingURL=ToursUserRoot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToursUserRoot.js","names":[],"sources":["../../src/tours/ToursUserRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect } from 'react';\nimport { ErrorBoundary } from '@burdenoff/fe-libs/shared/components';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { Compass, ListChecks } from 'lucide-react';\nimport { ToursProvider } from './providers/ToursProvider';\nimport { ToursUserRoutes } from './ToursUserRoutes';\nimport type { NavItem, ToursRootProps } from './types';\nimport { joinPath } from './utils/joinPath';\n\n/**\n * User-facing root component for the Tours microfrontend.\n *\n * Mounts the read-only \"My Tours\" + \"My Progress\" surface for product\n * user shells (vibecontrols-app, and later workspaces-app / bigconsole-app).\n * Registers exactly two nav items; never exposes authoring or governance\n * pages.\n *\n * Pair with `ToursAdminRoot` for the admin shell.\n */\nexport const ToursUserRoot: FC<ToursRootProps> = (props) => {\n const { basePath = '/', registerNavItems, workspaceId } = props;\n\n useEffect(() => {\n if (!registerNavItems) return;\n\n const navItems: NavItem[] = [\n {\n id: 'tours-my',\n label: 'My Tours',\n path: basePath,\n icon: <Compass size={20} />,\n order: 10,\n group: 'tours',\n },\n {\n id: 'tours-my-progress',\n label: 'My Progress',\n path: joinPath(basePath, 'progress'),\n icon: <ListChecks size={20} />,\n order: 20,\n group: 'tours',\n },\n ];\n\n return registerNavItems(navItems);\n }, [registerNavItems, basePath]);\n\n return (\n <FeatureFlagProvider workspaceId={workspaceId ?? null} gateway=\"global\" defaultEnabled={true}>\n <ErrorBoundary\n fallback={\n <div className=\"p-6 text-center text-text-secondary\">\n Something went wrong loading this module. Please refresh the page.\n </div>\n }\n >\n <ToursProvider {...props} variant=\"user\">\n <ToursUserRoutes />\n </ToursProvider>\n </ErrorBoundary>\n </FeatureFlagProvider>\n );\n};\n"],"mappings":";;;;;;;;;AAoBA,IAAa,KAAqC,MAAU;CAC1D,IAAM,EAAE,cAAW,KAAK,qBAAkB,mBAAgB;AA2B1D,QAzBA,QAAgB;AACT,QAqBL,QAAO,EAnBqB,CAC1B;GACE,IAAI;GACJ,OAAO;GACP,MAAM;GACN,MAAM,kBAAC,GAAD,EAAS,MAAM,IAAM,CAAA;GAC3B,OAAO;GACP,OAAO;GACR,EACD;GACE,IAAI;GACJ,OAAO;GACP,MAAM,EAAS,GAAU,WAAW;GACpC,MAAM,kBAAC,GAAD,EAAY,MAAM,IAAM,CAAA;GAC9B,OAAO;GACP,OAAO;GACR,CACF,CAEgC;IAChC,CAAC,GAAkB,EAAS,CAAC,EAG9B,kBAAC,GAAD;EAAqB,aAAa,KAAe;EAAM,SAAQ;EAAS,gBAAgB;YACtF,kBAAC,GAAD;GACE,UACE,kBAAC,OAAD;IAAK,WAAU;cAAsC;IAE/C,CAAA;aAGR,kBAAC,GAAD;IAAe,GAAI;IAAO,SAAQ;cAChC,kBAAC,GAAD,EAAmB,CAAA;IACL,CAAA;GACF,CAAA;EACI,CAAA"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * User-facing routes for the Tours microfrontend.
3
+ *
4
+ * Exposes a tight surface — browse available tours and review own progress.
5
+ * Tour playback itself is handled by the SDK overlay, not by routed pages.
6
+ *
7
+ * Routes (relative to basePath, e.g. `/tours`):
8
+ * - `/` → MyToursPage (browse + status)
9
+ * - `/progress` → MyToursProgressPage (own progress, grouped)
10
+ * - `*` → UserRouteNotFound, then absolute navigate to basePath
11
+ * (collapses any admin-style URL like `/new`, `/media`,
12
+ * `/templates` after briefly signalling unavailability)
13
+ */
14
+ export declare function ToursUserRoutes(): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=ToursUserRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToursUserRoutes.d.ts","sourceRoot":"","sources":["../../src/tours/ToursUserRoutes.tsx"],"names":[],"mappings":"AA+CA;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,4CAc9B"}
@@ -0,0 +1,66 @@
1
+ import { TOURS_FEATURES as e } from "../constants/featureFlags.js";
2
+ import { useToursContext as t } from "./providers/ToursProvider.js";
3
+ import { LazyErrorBoundary as n, PageLoader as r } from "./components/RouteHelpers.js";
4
+ import { useToursI18n as i } from "./i18n.js";
5
+ import { MyToursPage as a } from "./pages/MyToursPage.js";
6
+ import { Suspense as o, lazy as s, useEffect as c } from "react";
7
+ import { FeatureGate as l } from "@burdenoff/fe-libs/shared/feature-flags";
8
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
9
+ import { Route as f, Routes as p, useNavigate as m } from "react-router-dom";
10
+ //#region src/tours/ToursUserRoutes.tsx
11
+ var h = s(() => import("./pages/MyToursProgressPage.js").then((e) => ({ default: e.MyToursProgressPage })));
12
+ function g() {
13
+ let e = m(), { tr: n } = i(), { basePath: r } = t();
14
+ return c(() => {
15
+ let t = r && r.length > 0 ? r : "/", n = window.setTimeout(() => e(t, { replace: !0 }), 1500);
16
+ return () => window.clearTimeout(n);
17
+ }, [e, r]), /* @__PURE__ */ d("div", {
18
+ className: "flex flex-col items-center justify-center min-h-[300px] text-center p-6 gap-2",
19
+ children: [/* @__PURE__ */ u("h2", {
20
+ className: "text-lg font-semibold text-foreground",
21
+ children: n("myTours.notFoundTitle")
22
+ }), /* @__PURE__ */ u("p", {
23
+ className: "text-sm text-muted-foreground max-w-md",
24
+ children: n("myTours.notFoundBody")
25
+ })]
26
+ });
27
+ }
28
+ function _() {
29
+ return /* @__PURE__ */ u(l, {
30
+ flag: e.USER,
31
+ defaultValue: !0,
32
+ fallback: /* @__PURE__ */ u(v, {}),
33
+ children: /* @__PURE__ */ u(n, { children: /* @__PURE__ */ u(o, {
34
+ fallback: /* @__PURE__ */ u(r, {}),
35
+ children: /* @__PURE__ */ d(p, { children: [
36
+ /* @__PURE__ */ u(f, {
37
+ index: !0,
38
+ element: /* @__PURE__ */ u(a, {})
39
+ }),
40
+ /* @__PURE__ */ u(f, {
41
+ path: "progress",
42
+ element: /* @__PURE__ */ u(h, {})
43
+ }),
44
+ /* @__PURE__ */ u(f, {
45
+ path: "*",
46
+ element: /* @__PURE__ */ u(g, {})
47
+ })
48
+ ] })
49
+ }) })
50
+ });
51
+ }
52
+ function v() {
53
+ return /* @__PURE__ */ u("div", {
54
+ className: "flex min-h-[300px] items-center justify-center p-6 text-center",
55
+ role: "status",
56
+ "aria-live": "polite",
57
+ children: /* @__PURE__ */ u("p", {
58
+ className: "max-w-md text-sm text-muted-foreground",
59
+ children: "Tours are not available for this workspace right now."
60
+ })
61
+ });
62
+ }
63
+ //#endregion
64
+ export { _ as ToursUserRoutes };
65
+
66
+ //# sourceMappingURL=ToursUserRoutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToursUserRoutes.js","names":[],"sources":["../../src/tours/ToursUserRoutes.tsx"],"sourcesContent":["import { lazy, Suspense, useEffect } from 'react';\nimport { Route, Routes, useNavigate } from 'react-router-dom';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { TOURS_FEATURES } from '../constants/featureFlags';\nimport { LazyErrorBoundary, PageLoader } from './components/RouteHelpers';\nimport { useToursContext } from './providers/ToursProvider';\nimport { useToursI18n } from './i18n';\n\n// Eager — primary landing\nimport { MyToursPage } from './pages/MyToursPage';\n\n// Lazy — secondary surface\nconst MyToursProgressPage = lazy(() =>\n import('./pages/MyToursProgressPage').then((m) => ({ default: m.MyToursProgressPage }))\n);\n\n/**\n * 404-style landing shown briefly before redirecting any unknown\n * `/tours/*` path back to the user landing. Gives bookmarkers a signal\n * that the page they tried to load doesn't exist under the user surface,\n * rather than silently snapping them back to `/tours`.\n *\n * Note: react-router's relative `navigate('')` / `navigate('.')` resolves\n * to the current pathname, so for a `*` wildcard matched at\n * `/tours/new` those calls would keep the browser on `/tours/new`. We\n * redirect absolutely via `useToursContext().basePath` so the redirect\n * lands on the landing regardless of how deep the unknown URL was.\n */\nfunction UserRouteNotFound() {\n const navigate = useNavigate();\n const { tr } = useToursI18n();\n const { basePath } = useToursContext();\n\n useEffect(() => {\n const target = basePath && basePath.length > 0 ? basePath : '/';\n const id = window.setTimeout(() => navigate(target, { replace: true }), 1500);\n return () => window.clearTimeout(id);\n }, [navigate, basePath]);\n\n return (\n <div className=\"flex flex-col items-center justify-center min-h-[300px] text-center p-6 gap-2\">\n <h2 className=\"text-lg font-semibold text-foreground\">{tr('myTours.notFoundTitle')}</h2>\n <p className=\"text-sm text-muted-foreground max-w-md\">{tr('myTours.notFoundBody')}</p>\n </div>\n );\n}\n\n/**\n * User-facing routes for the Tours microfrontend.\n *\n * Exposes a tight surface — browse available tours and review own progress.\n * Tour playback itself is handled by the SDK overlay, not by routed pages.\n *\n * Routes (relative to basePath, e.g. `/tours`):\n * - `/` → MyToursPage (browse + status)\n * - `/progress` → MyToursProgressPage (own progress, grouped)\n * - `*` → UserRouteNotFound, then absolute navigate to basePath\n * (collapses any admin-style URL like `/new`, `/media`,\n * `/templates` after briefly signalling unavailability)\n */\nexport function ToursUserRoutes() {\n return (\n <FeatureGate flag={TOURS_FEATURES.USER} defaultValue={true} fallback={<UserToursUnavailable />}>\n <LazyErrorBoundary>\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route index element={<MyToursPage />} />\n <Route path=\"progress\" element={<MyToursProgressPage />} />\n <Route path=\"*\" element={<UserRouteNotFound />} />\n </Routes>\n </Suspense>\n </LazyErrorBoundary>\n </FeatureGate>\n );\n}\n\nfunction UserToursUnavailable() {\n return (\n <div\n className=\"flex min-h-[300px] items-center justify-center p-6 text-center\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <p className=\"max-w-md text-sm text-muted-foreground\">\n Tours are not available for this workspace right now.\n </p>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAYA,IAAM,IAAsB,QAC1B,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,CACxF;AAcD,SAAS,IAAoB;CAC3B,IAAM,IAAW,GAAa,EACxB,EAAE,UAAO,GAAc,EACvB,EAAE,gBAAa,GAAiB;AAQtC,QANA,QAAgB;EACd,IAAM,IAAS,KAAY,EAAS,SAAS,IAAI,IAAW,KACtD,IAAK,OAAO,iBAAiB,EAAS,GAAQ,EAAE,SAAS,IAAM,CAAC,EAAE,KAAK;AAC7E,eAAa,OAAO,aAAa,EAAG;IACnC,CAAC,GAAU,EAAS,CAAC,EAGtB,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,MAAD;GAAI,WAAU;aAAyC,EAAG,wBAAwB;GAAM,CAAA,EACxF,kBAAC,KAAD;GAAG,WAAU;aAA0C,EAAG,uBAAuB;GAAK,CAAA,CAClF;;;AAiBV,SAAgB,IAAkB;AAChC,QACE,kBAAC,GAAD;EAAa,MAAM,EAAe;EAAM,cAAc;EAAM,UAAU,kBAAC,GAAD,EAAwB,CAAA;YAC5F,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;GAAU,UAAU,kBAAC,GAAD,EAAc,CAAA;aAChC,kBAAC,GAAD,EAAA,UAAA;IACE,kBAAC,GAAD;KAAO,OAAA;KAAM,SAAS,kBAAC,GAAD,EAAe,CAAA;KAAI,CAAA;IACzC,kBAAC,GAAD;KAAO,MAAK;KAAW,SAAS,kBAAC,GAAD,EAAuB,CAAA;KAAI,CAAA;IAC3D,kBAAC,GAAD;KAAO,MAAK;KAAI,SAAS,kBAAC,GAAD,EAAqB,CAAA;KAAI,CAAA;IAC3C,EAAA,CAAA;GACA,CAAA,EACO,CAAA;EACR,CAAA;;AAIlB,SAAS,IAAuB;AAC9B,QACE,kBAAC,OAAD;EACE,WAAU;EACV,MAAK;EACL,aAAU;YAEV,kBAAC,KAAD;GAAG,WAAU;aAAyC;GAElD,CAAA;EACA,CAAA"}
@@ -0,0 +1,33 @@
1
+ import { Component, ReactNode, ErrorInfo } from 'react';
2
+
3
+ /**
4
+ * Loading fallback for lazy-loaded pages.
5
+ * Shared between ToursAdminRoutes and ToursUserRoutes (Section D/E of BOFF-2391).
6
+ */
7
+ export declare function PageLoader(): import("react/jsx-runtime").JSX.Element;
8
+ /**
9
+ * Error boundary for lazy-loaded page chunks.
10
+ *
11
+ * React.lazy() caches rejected promises, so resetting error state alone would
12
+ * re-throw the same cached rejection. The retryCount key forces a full remount
13
+ * of the subtree on retry, creating fresh lazy-component instances.
14
+ */
15
+ export declare class LazyErrorBoundary extends Component<{
16
+ children: ReactNode;
17
+ }, {
18
+ hasError: boolean;
19
+ error: Error | null;
20
+ retryCount: number;
21
+ }> {
22
+ constructor(props: {
23
+ children: ReactNode;
24
+ });
25
+ static getDerivedStateFromError(error: Error): {
26
+ hasError: boolean;
27
+ error: Error;
28
+ };
29
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
30
+ handleRetry: () => void;
31
+ render(): import("react/jsx-runtime").JSX.Element;
32
+ }
33
+ //# sourceMappingURL=RouteHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteHelpers.d.ts","sourceRoot":"","sources":["../../../src/tours/components/RouteHelpers.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG5E;;;GAGG;AACH,wBAAgB,UAAU,4CAMzB;AAKD;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,SAAS,CAC9C;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,EACvB;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAC/D;gBACa,KAAK,EAAE;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE;IAK1C,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK;;;;IAI5C,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS;IAQpD,WAAW,aAMT;IAEF,MAAM;CAyCP"}
@@ -0,0 +1,75 @@
1
+ import { Component as e, Fragment as t } from "react";
2
+ import { AlertTriangle as n, Loader2 as r, RefreshCw as i } from "lucide-react";
3
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
4
+ //#region src/tours/components/RouteHelpers.tsx
5
+ function s() {
6
+ return /* @__PURE__ */ a("div", {
7
+ className: "flex items-center justify-center min-h-[200px]",
8
+ children: /* @__PURE__ */ a(r, { className: "h-8 w-8 animate-spin text-primary" })
9
+ });
10
+ }
11
+ var c = 3, l = class extends e {
12
+ constructor(e) {
13
+ super(e), this.state = {
14
+ hasError: !1,
15
+ error: null,
16
+ retryCount: 0
17
+ };
18
+ }
19
+ static getDerivedStateFromError(e) {
20
+ return {
21
+ hasError: !0,
22
+ error: e
23
+ };
24
+ }
25
+ componentDidCatch(e, t) {
26
+ console.error("[Tours] Lazy page load failed:", e, t);
27
+ }
28
+ handleRetry = () => {
29
+ this.setState((e) => ({
30
+ hasError: !1,
31
+ error: null,
32
+ retryCount: e.retryCount + 1
33
+ }));
34
+ };
35
+ render() {
36
+ if (this.state.hasError) {
37
+ let e = this.state.retryCount < c;
38
+ return /* @__PURE__ */ o("div", {
39
+ className: "flex flex-col items-center justify-center min-h-[400px] gap-4 text-center p-6",
40
+ children: [
41
+ /* @__PURE__ */ a("div", {
42
+ className: "p-3 rounded-full bg-destructive/10",
43
+ children: /* @__PURE__ */ a(n, { className: "h-8 w-8 text-destructive" })
44
+ }),
45
+ /* @__PURE__ */ o("div", {
46
+ className: "space-y-2",
47
+ children: [/* @__PURE__ */ a("h3", {
48
+ className: "text-lg font-semibold text-foreground",
49
+ children: "Failed to load page"
50
+ }), /* @__PURE__ */ a("p", {
51
+ className: "text-sm text-muted-foreground max-w-md",
52
+ children: e ? "The page chunk could not be loaded. This may be due to a network issue." : "The page chunk could not be loaded after multiple attempts. Please refresh the page."
53
+ })]
54
+ }),
55
+ e ? /* @__PURE__ */ o("button", {
56
+ type: "button",
57
+ onClick: this.handleRetry,
58
+ className: "inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
59
+ children: [/* @__PURE__ */ a(i, { className: "h-4 w-4" }), "Try Again"]
60
+ }) : /* @__PURE__ */ o("button", {
61
+ type: "button",
62
+ onClick: () => window.location.reload(),
63
+ className: "inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
64
+ children: [/* @__PURE__ */ a(i, { className: "h-4 w-4" }), "Refresh Page"]
65
+ })
66
+ ]
67
+ });
68
+ }
69
+ return /* @__PURE__ */ a(t, { children: this.props.children }, this.state.retryCount);
70
+ }
71
+ };
72
+ //#endregion
73
+ export { l as LazyErrorBoundary, s as PageLoader };
74
+
75
+ //# sourceMappingURL=RouteHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteHelpers.js","names":[],"sources":["../../../src/tours/components/RouteHelpers.tsx"],"sourcesContent":["import { Component, Fragment, type ReactNode, type ErrorInfo } from 'react';\nimport { Loader2, AlertTriangle, RefreshCw } from 'lucide-react';\n\n/**\n * Loading fallback for lazy-loaded pages.\n * Shared between ToursAdminRoutes and ToursUserRoutes (Section D/E of BOFF-2391).\n */\nexport function PageLoader() {\n return (\n <div className=\"flex items-center justify-center min-h-[200px]\">\n <Loader2 className=\"h-8 w-8 animate-spin text-primary\" />\n </div>\n );\n}\n\n/** Max consecutive retries before the error screen suggests a full reload. */\nconst MAX_RETRY_COUNT = 3;\n\n/**\n * Error boundary for lazy-loaded page chunks.\n *\n * React.lazy() caches rejected promises, so resetting error state alone would\n * re-throw the same cached rejection. The retryCount key forces a full remount\n * of the subtree on retry, creating fresh lazy-component instances.\n */\nexport class LazyErrorBoundary extends Component<\n { children: ReactNode },\n { hasError: boolean; error: Error | null; retryCount: number }\n> {\n constructor(props: { children: ReactNode }) {\n super(props);\n this.state = { hasError: false, error: null, retryCount: 0 };\n }\n\n static getDerivedStateFromError(error: Error) {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n // TODO: forward to error monitoring service (Sentry, etc.)\n // Log the full error server-side / in the console; do NOT surface the raw\n // message to users since chunk-load errors can include CDN paths, build\n // hashes, or deployment details that shouldn't appear in the UI.\n console.error('[Tours] Lazy page load failed:', error, errorInfo);\n }\n\n handleRetry = () => {\n this.setState((prev) => ({\n hasError: false,\n error: null,\n retryCount: prev.retryCount + 1,\n }));\n };\n\n render() {\n if (this.state.hasError) {\n const canRetry = this.state.retryCount < MAX_RETRY_COUNT;\n return (\n <div className=\"flex flex-col items-center justify-center min-h-[400px] gap-4 text-center p-6\">\n <div className=\"p-3 rounded-full bg-destructive/10\">\n <AlertTriangle className=\"h-8 w-8 text-destructive\" />\n </div>\n <div className=\"space-y-2\">\n <h3 className=\"text-lg font-semibold text-foreground\">Failed to load page</h3>\n <p className=\"text-sm text-muted-foreground max-w-md\">\n {canRetry\n ? 'The page chunk could not be loaded. This may be due to a network issue.'\n : 'The page chunk could not be loaded after multiple attempts. Please refresh the page.'}\n </p>\n </div>\n {canRetry ? (\n <button\n type=\"button\"\n onClick={this.handleRetry}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors\"\n >\n <RefreshCw className=\"h-4 w-4\" />\n Try Again\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={() => window.location.reload()}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors\"\n >\n <RefreshCw className=\"h-4 w-4\" />\n Refresh Page\n </button>\n )}\n </div>\n );\n }\n\n return <Fragment key={this.state.retryCount}>{this.props.children}</Fragment>;\n }\n}\n"],"mappings":";;;;AAOA,SAAgB,IAAa;AAC3B,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAS,WAAU,qCAAsC,CAAA;EACrD,CAAA;;AAKV,IAAM,IAAkB,GASX,IAAb,cAAuC,EAGrC;CACA,YAAY,GAAgC;AAE1C,EADA,MAAM,EAAM,EACZ,KAAK,QAAQ;GAAE,UAAU;GAAO,OAAO;GAAM,YAAY;GAAG;;CAG9D,OAAO,yBAAyB,GAAc;AAC5C,SAAO;GAAE,UAAU;GAAM;GAAO;;CAGlC,kBAAkB,GAAc,GAAsB;AAKpD,UAAQ,MAAM,kCAAkC,GAAO,EAAU;;CAGnE,oBAAoB;AAClB,OAAK,UAAU,OAAU;GACvB,UAAU;GACV,OAAO;GACP,YAAY,EAAK,aAAa;GAC/B,EAAE;;CAGL,SAAS;AACP,MAAI,KAAK,MAAM,UAAU;GACvB,IAAM,IAAW,KAAK,MAAM,aAAa;AACzC,UACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAe,WAAU,4BAA6B,CAAA;MAClD,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBAAwC;OAAwB,CAAA,EAC9E,kBAAC,KAAD;OAAG,WAAU;iBACV,IACG,4EACA;OACF,CAAA,CACA;;KACL,IACC,kBAAC,UAAD;MACE,MAAK;MACL,SAAS,KAAK;MACd,WAAU;gBAHZ,CAKE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,YAE1B;UAET,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,OAAO,SAAS,QAAQ;MACvC,WAAU;gBAHZ,CAKE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,eAE1B;;KAEP;;;AAIV,SAAO,kBAAC,GAAD,EAAA,UAAuC,KAAK,MAAM,UAAoB,EAAvD,KAAK,MAAM,WAA4C"}
@@ -0,0 +1,25 @@
1
+ import { NavItem } from '../types';
2
+
3
+ interface ToursAdminNavRegistrarProps {
4
+ basePath: string;
5
+ registerNavItems: (items: NavItem | NavItem[]) => () => void;
6
+ }
7
+ /**
8
+ * Registers the admin tours nav items with the host shell.
9
+ *
10
+ * Rendered inside `<FeatureFlagProvider>` so it can consult `useFeatureFlag`
11
+ * to conditionally include flag-gated items. Re-registers whenever flag state
12
+ * changes so the host shell's nav reflects the current evaluation in real time.
13
+ *
14
+ * Baseline items (always registered): All Tours, Create Tour, Templates,
15
+ * Analytics. Media Library is gated on `tours.media` because the upload
16
+ * pipeline is still incomplete — the nav item appears only when the flag is
17
+ * enabled for the workspace or the user has opted in via Feature Previews.
18
+ *
19
+ * `registerNavItems` is captured in a ref so a host shell that hands over a
20
+ * fresh closure on every render can't trigger an unregister → re-register
21
+ * storm. Only flag-state / `basePath` changes cause re-registration.
22
+ */
23
+ export declare function ToursAdminNavRegistrar({ basePath, registerNavItems, }: ToursAdminNavRegistrarProps): null;
24
+ export {};
25
+ //# sourceMappingURL=ToursAdminNavRegistrar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToursAdminNavRegistrar.d.ts","sourceRoot":"","sources":["../../../src/tours/components/ToursAdminNavRegistrar.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGxC,UAAU,2BAA2B;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,KAAK,MAAM,IAAI,CAAC;CAC9D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,gBAAgB,GACjB,EAAE,2BAA2B,QA8D7B"}