@burdenoff/microfe-buildmyiq 2026.1030.2 → 2026.1030.3

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 (29) hide show
  1. package/dist/buildmyiq/BuildmyiqRoutes.js +3 -3
  2. package/dist/buildmyiq/BuildmyiqRoutes.js.map +1 -1
  3. package/dist/buildmyiq/analytics/buildmyiqAnalytics.d.ts +129 -0
  4. package/dist/buildmyiq/analytics/buildmyiqAnalytics.d.ts.map +1 -0
  5. package/dist/buildmyiq/analytics/buildmyiqAnalytics.js +97 -0
  6. package/dist/buildmyiq/analytics/buildmyiqAnalytics.js.map +1 -0
  7. package/dist/buildmyiq/analytics/index.d.ts +7 -0
  8. package/dist/buildmyiq/analytics/index.d.ts.map +1 -0
  9. package/dist/buildmyiq/analytics/index.js +2 -0
  10. package/dist/buildmyiq/analytics/useBuildmyiqAnalytics.d.ts +12 -0
  11. package/dist/buildmyiq/analytics/useBuildmyiqAnalytics.d.ts.map +1 -0
  12. package/dist/buildmyiq/analytics/useBuildmyiqAnalytics.js +26 -0
  13. package/dist/buildmyiq/analytics/useBuildmyiqAnalytics.js.map +1 -0
  14. package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.d.ts.map +1 -1
  15. package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.js +91 -80
  16. package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.js.map +1 -1
  17. package/dist/buildmyiq/pages/catalog/CatalogPage.d.ts.map +1 -1
  18. package/dist/buildmyiq/pages/catalog/CatalogPage.js +64 -58
  19. package/dist/buildmyiq/pages/catalog/CatalogPage.js.map +1 -1
  20. package/dist/buildmyiq/pages/catalog/CourseDetailPage.d.ts.map +1 -1
  21. package/dist/buildmyiq/pages/catalog/CourseDetailPage.js +250 -244
  22. package/dist/buildmyiq/pages/catalog/CourseDetailPage.js.map +1 -1
  23. package/dist/buildmyiq/pages/certificates/CertificatesPage.d.ts.map +1 -1
  24. package/dist/buildmyiq/pages/certificates/CertificatesPage.js +43 -36
  25. package/dist/buildmyiq/pages/certificates/CertificatesPage.js.map +1 -1
  26. package/dist/buildmyiq/pages/learning/LessonPlayerPage.d.ts.map +1 -1
  27. package/dist/buildmyiq/pages/learning/LessonPlayerPage.js +143 -120
  28. package/dist/buildmyiq/pages/learning/LessonPlayerPage.js.map +1 -1
  29. package/package.json +1 -1
@@ -99,7 +99,7 @@ var z = () => {
99
99
  }),
100
100
  /* @__PURE__ */ u(s, {
101
101
  path: "tutor-review",
102
- element: R("buildmyiq.tutorReview", /* @__PURE__ */ u(D, {}))
102
+ element: R("buildmyiq.tutor-review", /* @__PURE__ */ u(D, {}))
103
103
  }),
104
104
  /* @__PURE__ */ u(s, {
105
105
  path: "cohorts",
@@ -115,7 +115,7 @@ var z = () => {
115
115
  }),
116
116
  /* @__PURE__ */ u(s, {
117
117
  path: "admin-copilot",
118
- element: R("buildmyiq.adminCopilot", /* @__PURE__ */ u(j, {}))
118
+ element: R("buildmyiq.admin-copilot", /* @__PURE__ */ u(j, {}))
119
119
  }),
120
120
  /* @__PURE__ */ u(s, {
121
121
  path: "integrations",
@@ -127,7 +127,7 @@ var z = () => {
127
127
  }),
128
128
  /* @__PURE__ */ u(s, {
129
129
  path: "ai-settings",
130
- element: R("buildmyiq.aiSettings", /* @__PURE__ */ u(F, {}))
130
+ element: R("buildmyiq.ai-settings", /* @__PURE__ */ u(F, {}))
131
131
  }),
132
132
  /* @__PURE__ */ u(s, {
133
133
  path: "lti/launch/:ticketId",
@@ -1 +1 @@
1
- {"version":3,"file":"BuildmyiqRoutes.js","names":[],"sources":["../../src/buildmyiq/BuildmyiqRoutes.tsx"],"sourcesContent":["/**\n * Buildmyiq Routes\n * @module buildmyiq\n *\n * Domain routes. The dashboard is eager-loaded (primary landing); all other\n * pages are lazy-loaded. Every route maps to a real `bui*` backend capability.\n * All product routes are gated by feature flags that default to enabled.\n */\n\nimport React, { type FC, lazy, Suspense } from 'react';\nimport { Routes, Route, Navigate, useLocation } from 'react-router';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { useBuildmyiq } from './context';\nimport { useTr } from './shared/hooks/useTr';\n\n// Eager — primary landing\nimport { DashboardPage } from './pages/DashboardPage';\n\n// Catalog (learner-facing course discovery + detail + enrol)\nconst CatalogPage = lazy(() =>\n import('./pages/catalog/CatalogPage').then((m) => ({ default: m.CatalogPage }))\n);\nconst CourseDetailPage = lazy(() =>\n import('./pages/catalog/CourseDetailPage').then((m) => ({ default: m.CourseDetailPage }))\n);\n\n// My Learning (enrollments + progress + lesson player)\nconst MyLearningPage = lazy(() =>\n import('./pages/learning/MyLearningPage').then((m) => ({ default: m.MyLearningPage }))\n);\nconst LessonPlayerPage = lazy(() =>\n import('./pages/learning/LessonPlayerPage').then((m) => ({ default: m.LessonPlayerPage }))\n);\n\n// Authoring (instructor course management + builder)\nconst AuthoringPage = lazy(() =>\n import('./pages/authoring/AuthoringPage').then((m) => ({ default: m.AuthoringPage }))\n);\nconst CourseBuilderPage = lazy(() =>\n import('./pages/authoring/CourseBuilderPage').then((m) => ({ default: m.CourseBuilderPage }))\n);\n\n// Assessments (list + builder/questions/detail)\nconst AssessmentsPage = lazy(() =>\n import('./pages/assessments/AssessmentsPage').then((m) => ({ default: m.AssessmentsPage }))\n);\nconst AssessmentDetailPage = lazy(() =>\n import('./pages/assessments/AssessmentDetailPage').then((m) => ({\n default: m.AssessmentDetailPage,\n }))\n);\n// Learner-facing: take a published assessment (answer + submit)\nconst TakeAssessmentPage = lazy(() =>\n import('./pages/assessments/TakeAssessmentPage').then((m) => ({ default: m.TakeAssessmentPage }))\n);\n\n// Insights (educator analytics, derived from real data)\nconst InsightsPage = lazy(() =>\n import('./pages/insights/InsightsPage').then((m) => ({ default: m.InsightsPage }))\n);\n\n// Skill Journeys (derived guided paths)\nconst PathsPage = lazy(() =>\n import('./pages/paths/PathsPage').then((m) => ({ default: m.PathsPage }))\n);\n\n// Grading (submissions queue)\nconst SubmissionsPage = lazy(() =>\n import('./pages/submissions/SubmissionsPage').then((m) => ({ default: m.SubmissionsPage }))\n);\nconst BulkGradingPage = lazy(() =>\n import('./pages/submissions/BulkGradingPage').then((m) => ({ default: m.BulkGradingPage }))\n);\n\n// Proctoring review queue — high-stakes exam identity checks (BOFF-4431)\nconst ProctoringReviewPage = lazy(() =>\n import('./pages/proctoring/ProctoringReviewPage').then((m) => ({\n default: m.ProctoringReviewPage,\n }))\n);\n\n// Educator review of AI tutor answers (BOFF-9663)\nconst TutorReviewPage = lazy(() =>\n import('./pages/tutorReview/TutorReviewPage').then((m) => ({ default: m.TutorReviewPage }))\n);\n\n// Cohorts\nconst CohortsPage = lazy(() =>\n import('./pages/cohorts/CohortsPage').then((m) => ({ default: m.CohortsPage }))\n);\n\n// Skills taxonomy\nconst SkillsPage = lazy(() =>\n import('./pages/skills/SkillsPage').then((m) => ({ default: m.SkillsPage }))\n);\n\n// Certificates\nconst CertificatesPage = lazy(() =>\n import('./pages/certificates/CertificatesPage').then((m) => ({ default: m.CertificatesPage }))\n);\n\n// AI Admin Copilot (BOFF-4434) — read-only workspace Q&A\nconst AdminCopilotPage = lazy(() =>\n import('./pages/copilot/AdminCopilotPage').then((m) => ({ default: m.AdminCopilotPage }))\n);\n\n// LMS launch handoff — where a validated LTI 1.3 launch lands (BOFF-9680)\nconst LtiLaunchPage = lazy(() =>\n import('./pages/lti/LtiLaunchPage').then((m) => ({ default: m.LtiLaunchPage }))\n);\n// LMS integrations — LTI 1.3 Advantage platform registry (BOFF-4419)\nconst LtiPlatformsPage = lazy(() =>\n import('./pages/integrations/LtiPlatformsPage').then((m) => ({ default: m.LtiPlatformsPage }))\n);\n\n// L&D workflow automation via FluidGrids (BOFF-9688)\nconst AutomationsPage = lazy(() =>\n import('./pages/automations/AutomationsPage').then((m) => ({ default: m.AutomationsPage }))\n);\n\n// Workspace AI content controls (BOFF-9689)\nconst AiSettingsPage = lazy(() =>\n import('./pages/aiSettings/AiSettingsPage').then((m) => ({ default: m.AiSettingsPage }))\n);\n\nconst PageLoader: FC = () => (\n <div className=\"flex min-h-[400px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n);\n\nfunction FeatureDisabledFallback() {\n const tr = useTr();\n return (\n <div className=\"flex h-full min-h-[200px] items-center justify-center text-sm text-text-secondary\">\n {tr(\n 'buildmyiq.pages.featureDisabled',\n 'This feature is currently disabled. You can enable it from Feature Previews.'\n )}\n </div>\n );\n}\n\nfunction gated(flag: string, element: React.ReactNode, defaultValue = true): React.ReactElement {\n return (\n <FeatureGate flag={flag} defaultValue={defaultValue} fallback={<FeatureDisabledFallback />}>\n {element}\n </FeatureGate>\n );\n}\n\nexport const BuildmyiqRoutes: FC = () => {\n const { basePath, isStandalone } = useBuildmyiq();\n const location = useLocation();\n\n const normalizedBasePath = basePath === '/' ? '' : (basePath ?? '').replace(/\\/$/, '');\n\n // Guard: only render if the current path matches basePath (integrated mode).\n if (normalizedBasePath && !isStandalone) {\n const pathMatches =\n location.pathname === normalizedBasePath ||\n location.pathname.startsWith(normalizedBasePath + '/');\n if (!pathMatches) {\n return null;\n }\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route index element={gated('buildmyiq.overview', <DashboardPage />)} />\n\n <Route path=\"catalog\" element={gated('buildmyiq.catalog', <CatalogPage />)} />\n <Route\n path=\"catalog/:courseId\"\n element={gated('buildmyiq.catalog', <CourseDetailPage />)}\n />\n\n <Route path=\"learning\" element={gated('buildmyiq.learning', <MyLearningPage />)} />\n <Route\n path=\"learning/:enrollmentId\"\n element={gated('buildmyiq.learning', <LessonPlayerPage />)}\n />\n\n <Route path=\"paths\" element={gated('buildmyiq.paths', <PathsPage />)} />\n\n <Route path=\"authoring\" element={gated('buildmyiq.authoring', <AuthoringPage />)} />\n <Route\n path=\"authoring/:courseId\"\n element={gated('buildmyiq.authoring', <CourseBuilderPage />)}\n />\n\n <Route path=\"assessments\" element={gated('buildmyiq.assessments', <AssessmentsPage />)} />\n <Route\n path=\"assessments/:assessmentId\"\n element={gated('buildmyiq.assessments', <AssessmentDetailPage />)}\n />\n <Route\n path=\"assessments/:assessmentId/take\"\n element={gated('buildmyiq.assessments', <TakeAssessmentPage />)}\n />\n\n <Route path=\"insights\" element={gated('buildmyiq.insights', <InsightsPage />)} />\n\n <Route path=\"submissions\" element={gated('buildmyiq.submissions', <SubmissionsPage />)} />\n <Route\n path=\"submissions/bulk\"\n element={gated('buildmyiq.submissions', <BulkGradingPage />)}\n />\n <Route\n path=\"submissions/:submissionId\"\n element={gated('buildmyiq.submissions', <SubmissionsPage />)}\n />\n <Route\n path=\"proctoring\"\n element={gated('buildmyiq.proctoring', <ProctoringReviewPage />)}\n />\n <Route\n path=\"tutor-review\"\n element={gated('buildmyiq.tutorReview', <TutorReviewPage />)}\n />\n <Route path=\"cohorts\" element={gated('buildmyiq.cohorts', <CohortsPage />)} />\n <Route path=\"skills\" element={gated('buildmyiq.skills', <SkillsPage />)} />\n <Route\n path=\"certificates\"\n element={gated('buildmyiq.certificates', <CertificatesPage />)}\n />\n\n <Route\n path=\"admin-copilot\"\n element={gated('buildmyiq.adminCopilot', <AdminCopilotPage />)}\n />\n <Route\n path=\"integrations\"\n element={gated('buildmyiq.integrations', <LtiPlatformsPage />)}\n />\n <Route path=\"automations\" element={gated('buildmyiq.automations', <AutomationsPage />)} />\n <Route path=\"ai-settings\" element={gated('buildmyiq.aiSettings', <AiSettingsPage />)} />\n {/* Not feature-gated: learners arrive here from their LMS, and the\n launch only exists because a workspace admin registered it. */}\n <Route path=\"lti/launch/:ticketId\" element={<LtiLaunchPage />} />\n\n <Route path=\"*\" element={<Navigate to={normalizedBasePath || '/'} replace />} />\n </Routes>\n </Suspense>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"BuildmyiqRoutes.js","names":[],"sources":["../../src/buildmyiq/BuildmyiqRoutes.tsx"],"sourcesContent":["/**\n * Buildmyiq Routes\n * @module buildmyiq\n *\n * Domain routes. The dashboard is eager-loaded (primary landing); all other\n * pages are lazy-loaded. Every route maps to a real `bui*` backend capability.\n * All product routes are gated by feature flags that default to enabled.\n */\n\nimport React, { type FC, lazy, Suspense } from 'react';\nimport { Routes, Route, Navigate, useLocation } from 'react-router';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { Spinner } from '@burdenoff/fe-libs/ui';\nimport { useBuildmyiq } from './context';\nimport { useTr } from './shared/hooks/useTr';\n\n// Eager — primary landing\nimport { DashboardPage } from './pages/DashboardPage';\n\n// Catalog (learner-facing course discovery + detail + enrol)\nconst CatalogPage = lazy(() =>\n import('./pages/catalog/CatalogPage').then((m) => ({ default: m.CatalogPage }))\n);\nconst CourseDetailPage = lazy(() =>\n import('./pages/catalog/CourseDetailPage').then((m) => ({ default: m.CourseDetailPage }))\n);\n\n// My Learning (enrollments + progress + lesson player)\nconst MyLearningPage = lazy(() =>\n import('./pages/learning/MyLearningPage').then((m) => ({ default: m.MyLearningPage }))\n);\nconst LessonPlayerPage = lazy(() =>\n import('./pages/learning/LessonPlayerPage').then((m) => ({ default: m.LessonPlayerPage }))\n);\n\n// Authoring (instructor course management + builder)\nconst AuthoringPage = lazy(() =>\n import('./pages/authoring/AuthoringPage').then((m) => ({ default: m.AuthoringPage }))\n);\nconst CourseBuilderPage = lazy(() =>\n import('./pages/authoring/CourseBuilderPage').then((m) => ({ default: m.CourseBuilderPage }))\n);\n\n// Assessments (list + builder/questions/detail)\nconst AssessmentsPage = lazy(() =>\n import('./pages/assessments/AssessmentsPage').then((m) => ({ default: m.AssessmentsPage }))\n);\nconst AssessmentDetailPage = lazy(() =>\n import('./pages/assessments/AssessmentDetailPage').then((m) => ({\n default: m.AssessmentDetailPage,\n }))\n);\n// Learner-facing: take a published assessment (answer + submit)\nconst TakeAssessmentPage = lazy(() =>\n import('./pages/assessments/TakeAssessmentPage').then((m) => ({ default: m.TakeAssessmentPage }))\n);\n\n// Insights (educator analytics, derived from real data)\nconst InsightsPage = lazy(() =>\n import('./pages/insights/InsightsPage').then((m) => ({ default: m.InsightsPage }))\n);\n\n// Skill Journeys (derived guided paths)\nconst PathsPage = lazy(() =>\n import('./pages/paths/PathsPage').then((m) => ({ default: m.PathsPage }))\n);\n\n// Grading (submissions queue)\nconst SubmissionsPage = lazy(() =>\n import('./pages/submissions/SubmissionsPage').then((m) => ({ default: m.SubmissionsPage }))\n);\nconst BulkGradingPage = lazy(() =>\n import('./pages/submissions/BulkGradingPage').then((m) => ({ default: m.BulkGradingPage }))\n);\n\n// Proctoring review queue — high-stakes exam identity checks (BOFF-4431)\nconst ProctoringReviewPage = lazy(() =>\n import('./pages/proctoring/ProctoringReviewPage').then((m) => ({\n default: m.ProctoringReviewPage,\n }))\n);\n\n// Educator review of AI tutor answers (BOFF-9663)\nconst TutorReviewPage = lazy(() =>\n import('./pages/tutorReview/TutorReviewPage').then((m) => ({ default: m.TutorReviewPage }))\n);\n\n// Cohorts\nconst CohortsPage = lazy(() =>\n import('./pages/cohorts/CohortsPage').then((m) => ({ default: m.CohortsPage }))\n);\n\n// Skills taxonomy\nconst SkillsPage = lazy(() =>\n import('./pages/skills/SkillsPage').then((m) => ({ default: m.SkillsPage }))\n);\n\n// Certificates\nconst CertificatesPage = lazy(() =>\n import('./pages/certificates/CertificatesPage').then((m) => ({ default: m.CertificatesPage }))\n);\n\n// AI Admin Copilot (BOFF-4434) — read-only workspace Q&A\nconst AdminCopilotPage = lazy(() =>\n import('./pages/copilot/AdminCopilotPage').then((m) => ({ default: m.AdminCopilotPage }))\n);\n\n// LMS launch handoff — where a validated LTI 1.3 launch lands (BOFF-9680)\nconst LtiLaunchPage = lazy(() =>\n import('./pages/lti/LtiLaunchPage').then((m) => ({ default: m.LtiLaunchPage }))\n);\n// LMS integrations — LTI 1.3 Advantage platform registry (BOFF-4419)\nconst LtiPlatformsPage = lazy(() =>\n import('./pages/integrations/LtiPlatformsPage').then((m) => ({ default: m.LtiPlatformsPage }))\n);\n\n// L&D workflow automation via FluidGrids (BOFF-9688)\nconst AutomationsPage = lazy(() =>\n import('./pages/automations/AutomationsPage').then((m) => ({ default: m.AutomationsPage }))\n);\n\n// Workspace AI content controls (BOFF-9689)\nconst AiSettingsPage = lazy(() =>\n import('./pages/aiSettings/AiSettingsPage').then((m) => ({ default: m.AiSettingsPage }))\n);\n\nconst PageLoader: FC = () => (\n <div className=\"flex min-h-[400px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n);\n\nfunction FeatureDisabledFallback() {\n const tr = useTr();\n return (\n <div className=\"flex h-full min-h-[200px] items-center justify-center text-sm text-text-secondary\">\n {tr(\n 'buildmyiq.pages.featureDisabled',\n 'This feature is currently disabled. You can enable it from Feature Previews.'\n )}\n </div>\n );\n}\n\nfunction gated(flag: string, element: React.ReactNode, defaultValue = true): React.ReactElement {\n return (\n <FeatureGate flag={flag} defaultValue={defaultValue} fallback={<FeatureDisabledFallback />}>\n {element}\n </FeatureGate>\n );\n}\n\nexport const BuildmyiqRoutes: FC = () => {\n const { basePath, isStandalone } = useBuildmyiq();\n const location = useLocation();\n\n const normalizedBasePath = basePath === '/' ? '' : (basePath ?? '').replace(/\\/$/, '');\n\n // Guard: only render if the current path matches basePath (integrated mode).\n if (normalizedBasePath && !isStandalone) {\n const pathMatches =\n location.pathname === normalizedBasePath ||\n location.pathname.startsWith(normalizedBasePath + '/');\n if (!pathMatches) {\n return null;\n }\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route index element={gated('buildmyiq.overview', <DashboardPage />)} />\n\n <Route path=\"catalog\" element={gated('buildmyiq.catalog', <CatalogPage />)} />\n <Route\n path=\"catalog/:courseId\"\n element={gated('buildmyiq.catalog', <CourseDetailPage />)}\n />\n\n <Route path=\"learning\" element={gated('buildmyiq.learning', <MyLearningPage />)} />\n <Route\n path=\"learning/:enrollmentId\"\n element={gated('buildmyiq.learning', <LessonPlayerPage />)}\n />\n\n <Route path=\"paths\" element={gated('buildmyiq.paths', <PathsPage />)} />\n\n <Route path=\"authoring\" element={gated('buildmyiq.authoring', <AuthoringPage />)} />\n <Route\n path=\"authoring/:courseId\"\n element={gated('buildmyiq.authoring', <CourseBuilderPage />)}\n />\n\n <Route path=\"assessments\" element={gated('buildmyiq.assessments', <AssessmentsPage />)} />\n <Route\n path=\"assessments/:assessmentId\"\n element={gated('buildmyiq.assessments', <AssessmentDetailPage />)}\n />\n <Route\n path=\"assessments/:assessmentId/take\"\n element={gated('buildmyiq.assessments', <TakeAssessmentPage />)}\n />\n\n <Route path=\"insights\" element={gated('buildmyiq.insights', <InsightsPage />)} />\n\n <Route path=\"submissions\" element={gated('buildmyiq.submissions', <SubmissionsPage />)} />\n <Route\n path=\"submissions/bulk\"\n element={gated('buildmyiq.submissions', <BulkGradingPage />)}\n />\n <Route\n path=\"submissions/:submissionId\"\n element={gated('buildmyiq.submissions', <SubmissionsPage />)}\n />\n <Route\n path=\"proctoring\"\n element={gated('buildmyiq.proctoring', <ProctoringReviewPage />)}\n />\n <Route\n path=\"tutor-review\"\n element={gated('buildmyiq.tutor-review', <TutorReviewPage />)}\n />\n <Route path=\"cohorts\" element={gated('buildmyiq.cohorts', <CohortsPage />)} />\n <Route path=\"skills\" element={gated('buildmyiq.skills', <SkillsPage />)} />\n <Route\n path=\"certificates\"\n element={gated('buildmyiq.certificates', <CertificatesPage />)}\n />\n\n <Route\n path=\"admin-copilot\"\n element={gated('buildmyiq.admin-copilot', <AdminCopilotPage />)}\n />\n <Route\n path=\"integrations\"\n element={gated('buildmyiq.integrations', <LtiPlatformsPage />)}\n />\n <Route path=\"automations\" element={gated('buildmyiq.automations', <AutomationsPage />)} />\n <Route path=\"ai-settings\" element={gated('buildmyiq.ai-settings', <AiSettingsPage />)} />\n {/* Not feature-gated: learners arrive here from their LMS, and the\n launch only exists because a workspace admin registered it. */}\n <Route path=\"lti/launch/:ticketId\" element={<LtiLaunchPage />} />\n\n <Route path=\"*\" element={<Navigate to={normalizedBasePath || '/'} replace />} />\n </Routes>\n </Suspense>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AAoBA,IAAM,IAAc,QAClB,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAChF,GACM,IAAmB,QACvB,OAAO,uCAAoC,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAC1F,GAGM,IAAiB,QACrB,OAAO,sCAAmC,MAAM,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CACvF,GACM,IAAmB,QACvB,OAAO,wCAAqC,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAC3F,GAGM,IAAgB,QACpB,OAAO,sCAAmC,MAAM,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CACtF,GACM,IAAoB,QACxB,OAAO,0CAAuC,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAC9F,GAGM,IAAkB,QACtB,OAAO,0CAAuC,MAAM,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAC5F,GACM,IAAuB,QAC3B,OAAO,+CAA4C,MAAM,OAAO,EAC9D,SAAS,EAAE,qBACb,EAAE,CACJ,GAEM,IAAqB,QACzB,OAAO,6CAA0C,MAAM,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAClG,GAGM,IAAe,QACnB,OAAO,oCAAiC,MAAM,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CACnF,GAGM,IAAY,QAChB,OAAO,8BAA2B,MAAM,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAC1E,GAGM,IAAkB,QACtB,OAAO,0CAAuC,MAAM,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAC5F,GACM,IAAkB,QACtB,OAAO,0CAAuC,MAAM,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAC5F,GAGM,IAAuB,QAC3B,OAAO,8CAA2C,MAAM,OAAO,EAC7D,SAAS,EAAE,qBACb,EAAE,CACJ,GAGM,IAAkB,QACtB,OAAO,0CAAuC,MAAM,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAC5F,GAGM,IAAc,QAClB,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAChF,GAGM,IAAa,QACjB,OAAO,gCAA6B,MAAM,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,CAC7E,GAGM,IAAmB,QACvB,OAAO,4CAAyC,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAC/F,GAGM,IAAmB,QACvB,OAAO,uCAAoC,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAC1F,GAGM,IAAgB,QACpB,OAAO,gCAA6B,MAAM,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAChF,GAEM,IAAmB,QACvB,OAAO,4CAAyC,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAC/F,GAGM,IAAkB,QACtB,OAAO,0CAAuC,MAAM,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAC5F,GAGM,IAAiB,QACrB,OAAO,wCAAqC,MAAM,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CACzF,GAEM,UACJ,kBAAC,OAAD;CAAK,WAAU;WACb,kBAAC,GAAD,EAAS,MAAK,KAAM,CAAA;AACjB,CAAA;AAGP,SAAS,IAA0B;CAEjC,OACE,kBAAC,OAAD;EAAK,WAAU;YAFN,EAGN,EACC,mCACA,8EACF;CACG,CAAA;AAET;AAEA,SAAS,EAAM,GAAc,GAA0B,IAAe,IAA0B;CAC9F,OACE,kBAAC,GAAD;EAAmB;EAAoB;EAAc,UAAU,kBAAC,GAAD,CAA0B,CAAA;YACtF;CACU,CAAA;AAEjB;AAEA,IAAa,UAA4B;CACvC,IAAM,EAAE,aAAU,oBAAiB,EAAa,GAC1C,IAAW,EAAY,GAEvB,IAAqB,MAAa,MAAM,MAAM,KAAY,IAAI,QAAQ,OAAO,EAAE;CAYrF,OATI,KAAsB,CAAC,KAIrB,EAFF,EAAS,aAAa,KACtB,EAAS,SAAS,WAAW,IAAqB,GAAG,KAE9C,OAKT,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GAAU,UAAU,kBAAC,GAAD,CAAa,CAAA;aAC/B,kBAAC,GAAD,EAAA,UAAA;IACE,kBAAC,GAAD;KAAO,OAAA;KAAM,SAAS,EAAM,sBAAsB,kBAAC,GAAD,CAAgB,CAAA,CAAC;IAAI,CAAA;IAEvE,kBAAC,GAAD;KAAO,MAAK;KAAU,SAAS,EAAM,qBAAqB,kBAAC,GAAD,CAAc,CAAA,CAAC;IAAI,CAAA;IAC7E,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,qBAAqB,kBAAC,GAAD,CAAmB,CAAA,CAAC;IACzD,CAAA;IAED,kBAAC,GAAD;KAAO,MAAK;KAAW,SAAS,EAAM,sBAAsB,kBAAC,GAAD,CAAiB,CAAA,CAAC;IAAI,CAAA;IAClF,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,sBAAsB,kBAAC,GAAD,CAAmB,CAAA,CAAC;IAC1D,CAAA;IAED,kBAAC,GAAD;KAAO,MAAK;KAAQ,SAAS,EAAM,mBAAmB,kBAAC,GAAD,CAAY,CAAA,CAAC;IAAI,CAAA;IAEvE,kBAAC,GAAD;KAAO,MAAK;KAAY,SAAS,EAAM,uBAAuB,kBAAC,GAAD,CAAgB,CAAA,CAAC;IAAI,CAAA;IACnF,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,uBAAuB,kBAAC,GAAD,CAAoB,CAAA,CAAC;IAC5D,CAAA;IAED,kBAAC,GAAD;KAAO,MAAK;KAAc,SAAS,EAAM,yBAAyB,kBAAC,GAAD,CAAkB,CAAA,CAAC;IAAI,CAAA;IACzF,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,yBAAyB,kBAAC,GAAD,CAAuB,CAAA,CAAC;IACjE,CAAA;IACD,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,yBAAyB,kBAAC,GAAD,CAAqB,CAAA,CAAC;IAC/D,CAAA;IAED,kBAAC,GAAD;KAAO,MAAK;KAAW,SAAS,EAAM,sBAAsB,kBAAC,GAAD,CAAe,CAAA,CAAC;IAAI,CAAA;IAEhF,kBAAC,GAAD;KAAO,MAAK;KAAc,SAAS,EAAM,yBAAyB,kBAAC,GAAD,CAAkB,CAAA,CAAC;IAAI,CAAA;IACzF,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,yBAAyB,kBAAC,GAAD,CAAkB,CAAA,CAAC;IAC5D,CAAA;IACD,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,yBAAyB,kBAAC,GAAD,CAAkB,CAAA,CAAC;IAC5D,CAAA;IACD,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,wBAAwB,kBAAC,GAAD,CAAuB,CAAA,CAAC;IAChE,CAAA;IACD,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,0BAA0B,kBAAC,GAAD,CAAkB,CAAA,CAAC;IAC7D,CAAA;IACD,kBAAC,GAAD;KAAO,MAAK;KAAU,SAAS,EAAM,qBAAqB,kBAAC,GAAD,CAAc,CAAA,CAAC;IAAI,CAAA;IAC7E,kBAAC,GAAD;KAAO,MAAK;KAAS,SAAS,EAAM,oBAAoB,kBAAC,GAAD,CAAa,CAAA,CAAC;IAAI,CAAA;IAC1E,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,0BAA0B,kBAAC,GAAD,CAAmB,CAAA,CAAC;IAC9D,CAAA;IAED,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,2BAA2B,kBAAC,GAAD,CAAmB,CAAA,CAAC;IAC/D,CAAA;IACD,kBAAC,GAAD;KACE,MAAK;KACL,SAAS,EAAM,0BAA0B,kBAAC,GAAD,CAAmB,CAAA,CAAC;IAC9D,CAAA;IACD,kBAAC,GAAD;KAAO,MAAK;KAAc,SAAS,EAAM,yBAAyB,kBAAC,GAAD,CAAkB,CAAA,CAAC;IAAI,CAAA;IACzF,kBAAC,GAAD;KAAO,MAAK;KAAc,SAAS,EAAM,yBAAyB,kBAAC,GAAD,CAAiB,CAAA,CAAC;IAAI,CAAA;IAGxF,kBAAC,GAAD;KAAO,MAAK;KAAuB,SAAS,kBAAC,GAAD,CAAgB,CAAA;IAAI,CAAA;IAEhE,kBAAC,GAAD;KAAO,MAAK;KAAI,SAAS,kBAAC,GAAD;MAAU,IAAI,KAAsB;MAAK,SAAA;KAAS,CAAA;IAAI,CAAA;GACzE,EAAA,CAAA;EACA,CAAA;CACP,CAAA;AAET"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * BuildMyIQ product analytics (BOFF-3082).
3
+ *
4
+ * The learner funnel events this MFE emits on the shared fe-libs event bus.
5
+ * The MFE never talks to Rybbit: the app shell's RybbitSink forwards the names
6
+ * in `BUILDMYIQ_RYBBIT_EVENTS` (fe-libs `shared/events/buildmyiq.ts`) and the
7
+ * other sinks (BroadcastChannel, OTel, devtools) see every event.
8
+ *
9
+ * The event dictionary — firing rules, dimensions, funnels — is
10
+ * `buildmyiq-specs/business/analytics/ANALYTICS_PLAN.md`. Keep the names here,
11
+ * the fe-libs taxonomy and that plan identical.
12
+ *
13
+ * Payload rule: ids are carried for the bus sinks but RybbitSink strips every
14
+ * identifier key before Rybbit. Never put titles, answers, names or other
15
+ * free text in a payload.
16
+ */
17
+ /** Every BuildMyIQ analytics event this MFE emits. */
18
+ export declare const BUILDMYIQ_ANALYTICS_EVENTS: {
19
+ readonly catalogViewed: "buildmyiq.catalog.viewed";
20
+ readonly courseEnrolled: "buildmyiq.course.enrolled";
21
+ readonly lessonStarted: "buildmyiq.lesson.started";
22
+ readonly lessonCompleted: "buildmyiq.lesson.completed";
23
+ readonly assessmentSubmitted: "buildmyiq.assessment.submitted";
24
+ readonly courseCompleted: "buildmyiq.course.completed";
25
+ readonly certificateIssued: "buildmyiq.certificate.issued";
26
+ };
27
+ export type BuildmyiqAnalyticsEventName = (typeof BUILDMYIQ_ANALYTICS_EVENTS)[keyof typeof BUILDMYIQ_ANALYTICS_EVENTS];
28
+ export interface CatalogViewedInput {
29
+ courseCount: number;
30
+ }
31
+ export interface CourseEventInput {
32
+ courseId?: string;
33
+ enrollmentId?: string;
34
+ }
35
+ export interface LessonEventInput {
36
+ courseId?: string;
37
+ enrollmentId: string;
38
+ lessonId: string;
39
+ lessonType?: string;
40
+ }
41
+ export interface AssessmentSubmittedInput {
42
+ assessmentId: string;
43
+ submissionId?: string;
44
+ assessmentType?: string;
45
+ proctored: boolean;
46
+ answeredCount: number;
47
+ questionCount: number;
48
+ }
49
+ export interface CertificateIssuedInput {
50
+ certificateId?: string;
51
+ courseId?: string;
52
+ expires: boolean;
53
+ }
54
+ /** A single bus emission: the event name and its payload. */
55
+ export interface BuildmyiqAnalyticsEmission {
56
+ name: BuildmyiqAnalyticsEventName;
57
+ payload: Record<string, string | number | boolean | undefined>;
58
+ }
59
+ /**
60
+ * Pure payload builders. Kept separate from the hook so the exact shape that
61
+ * reaches the bus is unit-testable without a React tree.
62
+ */
63
+ export declare const buildmyiqAnalytics: {
64
+ catalogViewed(workspaceId: string | undefined, input: CatalogViewedInput): {
65
+ name: "buildmyiq.catalog.viewed";
66
+ payload: {
67
+ workspaceId: string | undefined;
68
+ courseCount: number | undefined;
69
+ };
70
+ };
71
+ courseEnrolled(workspaceId: string | undefined, input: CourseEventInput): {
72
+ name: "buildmyiq.course.enrolled";
73
+ payload: {
74
+ workspaceId: string | undefined;
75
+ courseId: string | undefined;
76
+ enrollmentId: string | undefined;
77
+ };
78
+ };
79
+ lessonStarted(workspaceId: string | undefined, input: LessonEventInput): {
80
+ name: "buildmyiq.lesson.started";
81
+ payload: {
82
+ workspaceId: string | undefined;
83
+ courseId: string | undefined;
84
+ enrollmentId: string;
85
+ lessonId: string;
86
+ lessonType: string | undefined;
87
+ };
88
+ };
89
+ lessonCompleted(workspaceId: string | undefined, input: LessonEventInput): {
90
+ name: "buildmyiq.lesson.completed";
91
+ payload: {
92
+ workspaceId: string | undefined;
93
+ courseId: string | undefined;
94
+ enrollmentId: string;
95
+ lessonId: string;
96
+ lessonType: string | undefined;
97
+ };
98
+ };
99
+ assessmentSubmitted(workspaceId: string | undefined, input: AssessmentSubmittedInput): {
100
+ name: "buildmyiq.assessment.submitted";
101
+ payload: {
102
+ workspaceId: string | undefined;
103
+ assessmentId: string;
104
+ submissionId: string | undefined;
105
+ assessmentType: string | undefined;
106
+ proctored: boolean;
107
+ answeredCount: number | undefined;
108
+ questionCount: number | undefined;
109
+ };
110
+ };
111
+ courseCompleted(workspaceId: string | undefined, input: CourseEventInput): {
112
+ name: "buildmyiq.course.completed";
113
+ payload: {
114
+ workspaceId: string | undefined;
115
+ courseId: string | undefined;
116
+ enrollmentId: string | undefined;
117
+ };
118
+ };
119
+ certificateIssued(workspaceId: string | undefined, input: CertificateIssuedInput): {
120
+ name: "buildmyiq.certificate.issued";
121
+ payload: {
122
+ workspaceId: string | undefined;
123
+ certificateId: string | undefined;
124
+ courseId: string | undefined;
125
+ expires: boolean;
126
+ };
127
+ };
128
+ };
129
+ //# sourceMappingURL=buildmyiqAnalytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildmyiqAnalytics.d.ts","sourceRoot":"","sources":["../../../src/buildmyiq/analytics/buildmyiqAnalytics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,sDAAsD;AACtD,eAAO,MAAM,0BAA0B;;;;;;;;CAQ7B,CAAC;AAEX,MAAM,MAAM,2BAA2B,GACrC,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,OAAO,0BAA0B,CAAC,CAAC;AAE/E,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,6DAA6D;AAC7D,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,2BAA2B,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CAChE;AAOD;;;GAGG;AACH,eAAO,MAAM,kBAAkB;+BACF,MAAM,GAAG,SAAS,SAAS,kBAAkB;;;;;;;gCAM5C,MAAM,GAAG,SAAS,SAAS,gBAAgB;;;;;;;;+BAM5C,MAAM,GAAG,SAAS,SAAS,gBAAgB;;;;;;;;;;iCAYzC,MAAM,GAAG,SAAS,SAAS,gBAAgB;;;;;;;;;;qCAYvC,MAAM,GAAG,SAAS,SAAS,wBAAwB;;;;;;;;;;;;iCAcvD,MAAM,GAAG,SAAS,SAAS,gBAAgB;;;;;;;;mCAMzC,MAAM,GAAG,SAAS,SAAS,sBAAsB;;;;;;;;;CAWjF,CAAC"}
@@ -0,0 +1,97 @@
1
+ //#region src/buildmyiq/analytics/buildmyiqAnalytics.ts
2
+ var e = {
3
+ catalogViewed: "buildmyiq.catalog.viewed",
4
+ courseEnrolled: "buildmyiq.course.enrolled",
5
+ lessonStarted: "buildmyiq.lesson.started",
6
+ lessonCompleted: "buildmyiq.lesson.completed",
7
+ assessmentSubmitted: "buildmyiq.assessment.submitted",
8
+ courseCompleted: "buildmyiq.course.completed",
9
+ certificateIssued: "buildmyiq.certificate.issued"
10
+ };
11
+ function t(e) {
12
+ return Number.isFinite(e) && e >= 0 ? Math.floor(e) : void 0;
13
+ }
14
+ var n = {
15
+ catalogViewed(n, r) {
16
+ return {
17
+ name: e.catalogViewed,
18
+ payload: {
19
+ workspaceId: n,
20
+ courseCount: t(r.courseCount)
21
+ }
22
+ };
23
+ },
24
+ courseEnrolled(t, n) {
25
+ return {
26
+ name: e.courseEnrolled,
27
+ payload: {
28
+ workspaceId: t,
29
+ courseId: n.courseId,
30
+ enrollmentId: n.enrollmentId
31
+ }
32
+ };
33
+ },
34
+ lessonStarted(t, n) {
35
+ return {
36
+ name: e.lessonStarted,
37
+ payload: {
38
+ workspaceId: t,
39
+ courseId: n.courseId,
40
+ enrollmentId: n.enrollmentId,
41
+ lessonId: n.lessonId,
42
+ lessonType: n.lessonType
43
+ }
44
+ };
45
+ },
46
+ lessonCompleted(t, n) {
47
+ return {
48
+ name: e.lessonCompleted,
49
+ payload: {
50
+ workspaceId: t,
51
+ courseId: n.courseId,
52
+ enrollmentId: n.enrollmentId,
53
+ lessonId: n.lessonId,
54
+ lessonType: n.lessonType
55
+ }
56
+ };
57
+ },
58
+ assessmentSubmitted(n, r) {
59
+ return {
60
+ name: e.assessmentSubmitted,
61
+ payload: {
62
+ workspaceId: n,
63
+ assessmentId: r.assessmentId,
64
+ submissionId: r.submissionId,
65
+ assessmentType: r.assessmentType,
66
+ proctored: r.proctored,
67
+ answeredCount: t(r.answeredCount),
68
+ questionCount: t(r.questionCount)
69
+ }
70
+ };
71
+ },
72
+ courseCompleted(t, n) {
73
+ return {
74
+ name: e.courseCompleted,
75
+ payload: {
76
+ workspaceId: t,
77
+ courseId: n.courseId,
78
+ enrollmentId: n.enrollmentId
79
+ }
80
+ };
81
+ },
82
+ certificateIssued(t, n) {
83
+ return {
84
+ name: e.certificateIssued,
85
+ payload: {
86
+ workspaceId: t,
87
+ certificateId: n.certificateId,
88
+ courseId: n.courseId,
89
+ expires: n.expires
90
+ }
91
+ };
92
+ }
93
+ };
94
+ //#endregion
95
+ export { e as BUILDMYIQ_ANALYTICS_EVENTS, n as buildmyiqAnalytics };
96
+
97
+ //# sourceMappingURL=buildmyiqAnalytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildmyiqAnalytics.js","names":[],"sources":["../../../src/buildmyiq/analytics/buildmyiqAnalytics.ts"],"sourcesContent":["/**\n * BuildMyIQ product analytics (BOFF-3082).\n *\n * The learner funnel events this MFE emits on the shared fe-libs event bus.\n * The MFE never talks to Rybbit: the app shell's RybbitSink forwards the names\n * in `BUILDMYIQ_RYBBIT_EVENTS` (fe-libs `shared/events/buildmyiq.ts`) and the\n * other sinks (BroadcastChannel, OTel, devtools) see every event.\n *\n * The event dictionary — firing rules, dimensions, funnels — is\n * `buildmyiq-specs/business/analytics/ANALYTICS_PLAN.md`. Keep the names here,\n * the fe-libs taxonomy and that plan identical.\n *\n * Payload rule: ids are carried for the bus sinks but RybbitSink strips every\n * identifier key before Rybbit. Never put titles, answers, names or other\n * free text in a payload.\n */\n\n/** Every BuildMyIQ analytics event this MFE emits. */\nexport const BUILDMYIQ_ANALYTICS_EVENTS = {\n catalogViewed: 'buildmyiq.catalog.viewed',\n courseEnrolled: 'buildmyiq.course.enrolled',\n lessonStarted: 'buildmyiq.lesson.started',\n lessonCompleted: 'buildmyiq.lesson.completed',\n assessmentSubmitted: 'buildmyiq.assessment.submitted',\n courseCompleted: 'buildmyiq.course.completed',\n certificateIssued: 'buildmyiq.certificate.issued',\n} as const;\n\nexport type BuildmyiqAnalyticsEventName =\n (typeof BUILDMYIQ_ANALYTICS_EVENTS)[keyof typeof BUILDMYIQ_ANALYTICS_EVENTS];\n\nexport interface CatalogViewedInput {\n courseCount: number;\n}\n\nexport interface CourseEventInput {\n courseId?: string;\n enrollmentId?: string;\n}\n\nexport interface LessonEventInput {\n courseId?: string;\n enrollmentId: string;\n lessonId: string;\n lessonType?: string;\n}\n\nexport interface AssessmentSubmittedInput {\n assessmentId: string;\n submissionId?: string;\n assessmentType?: string;\n proctored: boolean;\n answeredCount: number;\n questionCount: number;\n}\n\nexport interface CertificateIssuedInput {\n certificateId?: string;\n courseId?: string;\n expires: boolean;\n}\n\n/** A single bus emission: the event name and its payload. */\nexport interface BuildmyiqAnalyticsEmission {\n name: BuildmyiqAnalyticsEventName;\n payload: Record<string, string | number | boolean | undefined>;\n}\n\n/** Non-negative integer, or undefined for anything that is not a finite count. */\nfunction count(value: number): number | undefined {\n return Number.isFinite(value) && value >= 0 ? Math.floor(value) : undefined;\n}\n\n/**\n * Pure payload builders. Kept separate from the hook so the exact shape that\n * reaches the bus is unit-testable without a React tree.\n */\nexport const buildmyiqAnalytics = {\n catalogViewed(workspaceId: string | undefined, input: CatalogViewedInput) {\n return {\n name: BUILDMYIQ_ANALYTICS_EVENTS.catalogViewed,\n payload: { workspaceId, courseCount: count(input.courseCount) },\n } satisfies BuildmyiqAnalyticsEmission;\n },\n courseEnrolled(workspaceId: string | undefined, input: CourseEventInput) {\n return {\n name: BUILDMYIQ_ANALYTICS_EVENTS.courseEnrolled,\n payload: { workspaceId, courseId: input.courseId, enrollmentId: input.enrollmentId },\n } satisfies BuildmyiqAnalyticsEmission;\n },\n lessonStarted(workspaceId: string | undefined, input: LessonEventInput) {\n return {\n name: BUILDMYIQ_ANALYTICS_EVENTS.lessonStarted,\n payload: {\n workspaceId,\n courseId: input.courseId,\n enrollmentId: input.enrollmentId,\n lessonId: input.lessonId,\n lessonType: input.lessonType,\n },\n } satisfies BuildmyiqAnalyticsEmission;\n },\n lessonCompleted(workspaceId: string | undefined, input: LessonEventInput) {\n return {\n name: BUILDMYIQ_ANALYTICS_EVENTS.lessonCompleted,\n payload: {\n workspaceId,\n courseId: input.courseId,\n enrollmentId: input.enrollmentId,\n lessonId: input.lessonId,\n lessonType: input.lessonType,\n },\n } satisfies BuildmyiqAnalyticsEmission;\n },\n assessmentSubmitted(workspaceId: string | undefined, input: AssessmentSubmittedInput) {\n return {\n name: BUILDMYIQ_ANALYTICS_EVENTS.assessmentSubmitted,\n payload: {\n workspaceId,\n assessmentId: input.assessmentId,\n submissionId: input.submissionId,\n assessmentType: input.assessmentType,\n proctored: input.proctored,\n answeredCount: count(input.answeredCount),\n questionCount: count(input.questionCount),\n },\n } satisfies BuildmyiqAnalyticsEmission;\n },\n courseCompleted(workspaceId: string | undefined, input: CourseEventInput) {\n return {\n name: BUILDMYIQ_ANALYTICS_EVENTS.courseCompleted,\n payload: { workspaceId, courseId: input.courseId, enrollmentId: input.enrollmentId },\n } satisfies BuildmyiqAnalyticsEmission;\n },\n certificateIssued(workspaceId: string | undefined, input: CertificateIssuedInput) {\n return {\n name: BUILDMYIQ_ANALYTICS_EVENTS.certificateIssued,\n payload: {\n workspaceId,\n certificateId: input.certificateId,\n courseId: input.courseId,\n expires: input.expires,\n },\n } satisfies BuildmyiqAnalyticsEmission;\n },\n};\n"],"mappings":";AAkBA,IAAa,IAA6B;CACxC,eAAe;CACf,gBAAgB;CAChB,eAAe;CACf,iBAAiB;CACjB,qBAAqB;CACrB,iBAAiB;CACjB,mBAAmB;AACrB;AA2CA,SAAS,EAAM,GAAmC;CAChD,OAAO,OAAO,SAAS,CAAK,KAAK,KAAS,IAAI,KAAK,MAAM,CAAK,IAAI,KAAA;AACpE;AAMA,IAAa,IAAqB;CAChC,cAAc,GAAiC,GAA2B;EACxE,OAAO;GACL,MAAM,EAA2B;GACjC,SAAS;IAAE;IAAa,aAAa,EAAM,EAAM,WAAW;GAAE;EAChE;CACF;CACA,eAAe,GAAiC,GAAyB;EACvE,OAAO;GACL,MAAM,EAA2B;GACjC,SAAS;IAAE;IAAa,UAAU,EAAM;IAAU,cAAc,EAAM;GAAa;EACrF;CACF;CACA,cAAc,GAAiC,GAAyB;EACtE,OAAO;GACL,MAAM,EAA2B;GACjC,SAAS;IACP;IACA,UAAU,EAAM;IAChB,cAAc,EAAM;IACpB,UAAU,EAAM;IAChB,YAAY,EAAM;GACpB;EACF;CACF;CACA,gBAAgB,GAAiC,GAAyB;EACxE,OAAO;GACL,MAAM,EAA2B;GACjC,SAAS;IACP;IACA,UAAU,EAAM;IAChB,cAAc,EAAM;IACpB,UAAU,EAAM;IAChB,YAAY,EAAM;GACpB;EACF;CACF;CACA,oBAAoB,GAAiC,GAAiC;EACpF,OAAO;GACL,MAAM,EAA2B;GACjC,SAAS;IACP;IACA,cAAc,EAAM;IACpB,cAAc,EAAM;IACpB,gBAAgB,EAAM;IACtB,WAAW,EAAM;IACjB,eAAe,EAAM,EAAM,aAAa;IACxC,eAAe,EAAM,EAAM,aAAa;GAC1C;EACF;CACF;CACA,gBAAgB,GAAiC,GAAyB;EACxE,OAAO;GACL,MAAM,EAA2B;GACjC,SAAS;IAAE;IAAa,UAAU,EAAM;IAAU,cAAc,EAAM;GAAa;EACrF;CACF;CACA,kBAAkB,GAAiC,GAA+B;EAChF,OAAO;GACL,MAAM,EAA2B;GACjC,SAAS;IACP;IACA,eAAe,EAAM;IACrB,UAAU,EAAM;IAChB,SAAS,EAAM;GACjB;EACF;CACF;AACF"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * BuildMyIQ product analytics (BOFF-3082).
3
+ * @module buildmyiq/analytics
4
+ */
5
+ export { BUILDMYIQ_ANALYTICS_EVENTS, buildmyiqAnalytics, type BuildmyiqAnalyticsEventName, type BuildmyiqAnalyticsEmission, } from './buildmyiqAnalytics';
6
+ export { useBuildmyiqAnalytics, type BuildmyiqAnalyticsTrackers } from './useBuildmyiqAnalytics';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/buildmyiq/analytics/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EAClB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,GAChC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import "./buildmyiqAnalytics.js";
2
+ import "./useBuildmyiqAnalytics.js";
@@ -0,0 +1,12 @@
1
+ import { AssessmentSubmittedInput, CatalogViewedInput, CertificateIssuedInput, CourseEventInput, LessonEventInput } from './buildmyiqAnalytics';
2
+ export interface BuildmyiqAnalyticsTrackers {
3
+ trackCatalogViewed: (input: CatalogViewedInput) => void;
4
+ trackCourseEnrolled: (input: CourseEventInput) => void;
5
+ trackLessonStarted: (input: LessonEventInput) => void;
6
+ trackLessonCompleted: (input: LessonEventInput) => void;
7
+ trackAssessmentSubmitted: (input: AssessmentSubmittedInput) => void;
8
+ trackCourseCompleted: (input: CourseEventInput) => void;
9
+ trackCertificateIssued: (input: CertificateIssuedInput) => void;
10
+ }
11
+ export declare function useBuildmyiqAnalytics(): BuildmyiqAnalyticsTrackers;
12
+ //# sourceMappingURL=useBuildmyiqAnalytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBuildmyiqAnalytics.d.ts","sourceRoot":"","sources":["../../../src/buildmyiq/analytics/useBuildmyiqAnalytics.ts"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,wBAAwB,EAE7B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,0BAA0B;IACzC,kBAAkB,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACxD,mBAAmB,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACvD,kBAAkB,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACtD,oBAAoB,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,wBAAwB,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,CAAC;IACpE,oBAAoB,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,sBAAsB,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC;CACjE;AAED,wBAAgB,qBAAqB,IAAI,0BAA0B,CAgClE"}
@@ -0,0 +1,26 @@
1
+ import { useBuildmyiq as e } from "../context/BuildmyiqContext.js";
2
+ import "../context/index.js";
3
+ import { buildmyiqAnalytics as t } from "./buildmyiqAnalytics.js";
4
+ import { useCallback as n, useMemo as r } from "react";
5
+ import { useEventBus as i } from "@burdenoff/fe-libs/shared/events";
6
+ //#region src/buildmyiq/analytics/useBuildmyiqAnalytics.ts
7
+ function a() {
8
+ let a = i(), { workspaceId: o } = e(), s = n((e) => {
9
+ try {
10
+ a.emitCustom(e.name, e.payload);
11
+ } catch {}
12
+ }, [a]);
13
+ return r(() => ({
14
+ trackCatalogViewed: (e) => s(t.catalogViewed(o, e)),
15
+ trackCourseEnrolled: (e) => s(t.courseEnrolled(o, e)),
16
+ trackLessonStarted: (e) => s(t.lessonStarted(o, e)),
17
+ trackLessonCompleted: (e) => s(t.lessonCompleted(o, e)),
18
+ trackAssessmentSubmitted: (e) => s(t.assessmentSubmitted(o, e)),
19
+ trackCourseCompleted: (e) => s(t.courseCompleted(o, e)),
20
+ trackCertificateIssued: (e) => s(t.certificateIssued(o, e))
21
+ }), [s, o]);
22
+ }
23
+ //#endregion
24
+ export { a as useBuildmyiqAnalytics };
25
+
26
+ //# sourceMappingURL=useBuildmyiqAnalytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBuildmyiqAnalytics.js","names":[],"sources":["../../../src/buildmyiq/analytics/useBuildmyiqAnalytics.ts"],"sourcesContent":["/**\n * React hook that emits the BuildMyIQ funnel events on the shared event bus.\n *\n * Every tracker is fire-and-forget and never throws: analytics must not be able\n * to break a learner's enrolment, lesson or submission. Outside an app shell\n * (Storybook, standalone) the bus context is a no-op, so the calls are inert.\n */\nimport { useCallback, useMemo } from 'react';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\n\nimport { useBuildmyiq } from '../context';\nimport {\n buildmyiqAnalytics,\n type AssessmentSubmittedInput,\n type BuildmyiqAnalyticsEmission,\n type CatalogViewedInput,\n type CertificateIssuedInput,\n type CourseEventInput,\n type LessonEventInput,\n} from './buildmyiqAnalytics';\n\nexport interface BuildmyiqAnalyticsTrackers {\n trackCatalogViewed: (input: CatalogViewedInput) => void;\n trackCourseEnrolled: (input: CourseEventInput) => void;\n trackLessonStarted: (input: LessonEventInput) => void;\n trackLessonCompleted: (input: LessonEventInput) => void;\n trackAssessmentSubmitted: (input: AssessmentSubmittedInput) => void;\n trackCourseCompleted: (input: CourseEventInput) => void;\n trackCertificateIssued: (input: CertificateIssuedInput) => void;\n}\n\nexport function useBuildmyiqAnalytics(): BuildmyiqAnalyticsTrackers {\n const bus = useEventBus();\n const { workspaceId } = useBuildmyiq();\n\n const send = useCallback(\n (emission: BuildmyiqAnalyticsEmission) => {\n try {\n // emitCustom: the names are registered in fe-libs' BurdenoffEventName\n // union from the fe-libs release that ships the BuildMyIQ taxonomy; the\n // runtime path (bus.onAny -> sinks) is identical to emit().\n bus.emitCustom(emission.name, emission.payload);\n } catch {\n /* analytics is best-effort and must never break the learner flow */\n }\n },\n [bus]\n );\n\n return useMemo(\n () => ({\n trackCatalogViewed: (input) => send(buildmyiqAnalytics.catalogViewed(workspaceId, input)),\n trackCourseEnrolled: (input) => send(buildmyiqAnalytics.courseEnrolled(workspaceId, input)),\n trackLessonStarted: (input) => send(buildmyiqAnalytics.lessonStarted(workspaceId, input)),\n trackLessonCompleted: (input) => send(buildmyiqAnalytics.lessonCompleted(workspaceId, input)),\n trackAssessmentSubmitted: (input) =>\n send(buildmyiqAnalytics.assessmentSubmitted(workspaceId, input)),\n trackCourseCompleted: (input) => send(buildmyiqAnalytics.courseCompleted(workspaceId, input)),\n trackCertificateIssued: (input) =>\n send(buildmyiqAnalytics.certificateIssued(workspaceId, input)),\n }),\n [send, workspaceId]\n );\n}\n"],"mappings":";;;;;;AA+BA,SAAgB,IAAoD;CAClE,IAAM,IAAM,EAAY,GAClB,EAAE,mBAAgB,EAAa,GAE/B,IAAO,GACV,MAAyC;EACxC,IAAI;GAIF,EAAI,WAAW,EAAS,MAAM,EAAS,OAAO;EAChD,QAAQ,CAER;CACF,GACA,CAAC,CAAG,CACN;CAEA,OAAO,SACE;EACL,qBAAqB,MAAU,EAAK,EAAmB,cAAc,GAAa,CAAK,CAAC;EACxF,sBAAsB,MAAU,EAAK,EAAmB,eAAe,GAAa,CAAK,CAAC;EAC1F,qBAAqB,MAAU,EAAK,EAAmB,cAAc,GAAa,CAAK,CAAC;EACxF,uBAAuB,MAAU,EAAK,EAAmB,gBAAgB,GAAa,CAAK,CAAC;EAC5F,2BAA2B,MACzB,EAAK,EAAmB,oBAAoB,GAAa,CAAK,CAAC;EACjE,uBAAuB,MAAU,EAAK,EAAmB,gBAAgB,GAAa,CAAK,CAAC;EAC5F,yBAAyB,MACvB,EAAK,EAAmB,kBAAkB,GAAa,CAAK,CAAC;CACjE,IACA,CAAC,GAAM,CAAW,CACpB;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"TakeAssessmentPage.d.ts","sourceRoot":"","sources":["../../../../src/buildmyiq/pages/assessments/TakeAssessmentPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAa,MAAM,OAAO,CAAC;AAmE3C,eAAO,MAAM,kBAAkB,EAAE,EA+XhC,CAAC"}
1
+ {"version":3,"file":"TakeAssessmentPage.d.ts","sourceRoot":"","sources":["../../../../src/buildmyiq/pages/assessments/TakeAssessmentPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAa,MAAM,OAAO,CAAC;AAoE3C,eAAO,MAAM,kBAAkB,EAAE,EAwYhC,CAAC"}