@burdenoff/microfe-buildmyiq 2026.705.8 → 2026.705.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/buildmyiq/BuildmyiqRoot.d.ts +5 -0
- package/dist/buildmyiq/BuildmyiqRoot.d.ts.map +1 -0
- package/dist/buildmyiq/BuildmyiqRoot.js +54 -46
- package/dist/buildmyiq/BuildmyiqRoot.js.map +1 -1
- package/dist/buildmyiq/BuildmyiqRoutes.d.ts +4 -0
- package/dist/buildmyiq/BuildmyiqRoutes.d.ts.map +1 -0
- package/dist/buildmyiq/BuildmyiqRoutes.js +19 -11
- package/dist/buildmyiq/BuildmyiqRoutes.js.map +1 -1
- package/dist/buildmyiq/components/BuiDiscussion.d.ts +18 -0
- package/dist/buildmyiq/components/BuiDiscussion.d.ts.map +1 -0
- package/dist/buildmyiq/components/BuiTags.d.ts +17 -0
- package/dist/buildmyiq/components/BuiTags.d.ts.map +1 -0
- package/dist/buildmyiq/components/DataTable.d.ts +28 -0
- package/dist/buildmyiq/components/DataTable.d.ts.map +1 -0
- package/dist/buildmyiq/components/DataTable.js +1 -1
- package/dist/buildmyiq/components/DataTable.js.map +1 -1
- package/dist/buildmyiq/components/EmptyState.d.ts +18 -0
- package/dist/buildmyiq/components/EmptyState.d.ts.map +1 -0
- package/dist/buildmyiq/components/EvidenceUpload.d.ts +14 -0
- package/dist/buildmyiq/components/EvidenceUpload.d.ts.map +1 -0
- package/dist/buildmyiq/components/FileLink.d.ts +15 -0
- package/dist/buildmyiq/components/FileLink.d.ts.map +1 -0
- package/dist/buildmyiq/components/FilterTabs.d.ts +18 -0
- package/dist/buildmyiq/components/FilterTabs.d.ts.map +1 -0
- package/dist/buildmyiq/components/MetricsCard.d.ts +23 -0
- package/dist/buildmyiq/components/MetricsCard.d.ts.map +1 -0
- package/dist/buildmyiq/components/MiniBar.d.ts +16 -0
- package/dist/buildmyiq/components/MiniBar.d.ts.map +1 -0
- package/dist/buildmyiq/components/MiniBar.js +1 -1
- package/dist/buildmyiq/components/MiniBar.js.map +1 -1
- package/dist/buildmyiq/components/PageLayout.d.ts +16 -0
- package/dist/buildmyiq/components/PageLayout.d.ts.map +1 -0
- package/dist/buildmyiq/components/Pagination.d.ts +22 -0
- package/dist/buildmyiq/components/Pagination.d.ts.map +1 -0
- package/dist/buildmyiq/components/StateViews.d.ts +24 -0
- package/dist/buildmyiq/components/StateViews.d.ts.map +1 -0
- package/dist/buildmyiq/components/StatusBadge.d.ts +9 -0
- package/dist/buildmyiq/components/StatusBadge.d.ts.map +1 -0
- package/dist/buildmyiq/components/Tabs.d.ts +17 -0
- package/dist/buildmyiq/components/Tabs.d.ts.map +1 -0
- package/dist/buildmyiq/components/index.d.ts +19 -0
- package/dist/buildmyiq/components/index.d.ts.map +1 -0
- package/dist/buildmyiq/context/BuildmyiqContext.d.ts +16 -0
- package/dist/buildmyiq/context/BuildmyiqContext.d.ts.map +1 -0
- package/dist/buildmyiq/context/index.d.ts +6 -0
- package/dist/buildmyiq/context/index.d.ts.map +1 -0
- package/dist/buildmyiq/hooks/index.d.ts +10 -0
- package/dist/buildmyiq/hooks/index.d.ts.map +1 -0
- package/dist/buildmyiq/hooks/useBuiComments.d.ts +36 -0
- package/dist/buildmyiq/hooks/useBuiComments.d.ts.map +1 -0
- package/dist/buildmyiq/hooks/useBuiFiles.d.ts +47 -0
- package/dist/buildmyiq/hooks/useBuiFiles.d.ts.map +1 -0
- package/dist/buildmyiq/hooks/useBuiTags.d.ts +44 -0
- package/dist/buildmyiq/hooks/useBuiTags.d.ts.map +1 -0
- package/dist/buildmyiq/hooks/useBuildmyiqApi.d.ts +65 -0
- package/dist/buildmyiq/hooks/useBuildmyiqApi.d.ts.map +1 -0
- package/dist/buildmyiq/hooks/useBuildmyiqApi.js +23 -15
- package/dist/buildmyiq/hooks/useBuildmyiqApi.js.map +1 -1
- package/dist/buildmyiq/hooks/useCursorPager.d.ts +33 -0
- package/dist/buildmyiq/hooks/useCursorPager.d.ts.map +1 -0
- package/dist/buildmyiq/index.d.ts +9 -0
- package/dist/buildmyiq/index.d.ts.map +1 -0
- package/dist/buildmyiq/pages/DashboardPage.d.ts +4 -0
- package/dist/buildmyiq/pages/DashboardPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/DashboardPage.js +2 -2
- package/dist/buildmyiq/pages/DashboardPage.js.map +1 -1
- package/dist/buildmyiq/pages/_shared/CourseCard.d.ts +13 -0
- package/dist/buildmyiq/pages/_shared/CourseCard.d.ts.map +1 -0
- package/dist/buildmyiq/pages/_shared/index.d.ts +6 -0
- package/dist/buildmyiq/pages/_shared/index.d.ts.map +1 -0
- package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.d.ts +4 -0
- package/dist/buildmyiq/pages/assessments/AssessmentDetailPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/assessments/AssessmentsPage.d.ts +4 -0
- package/dist/buildmyiq/pages/assessments/AssessmentsPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.d.ts +4 -0
- package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.js +264 -0
- package/dist/buildmyiq/pages/assessments/TakeAssessmentPage.js.map +1 -0
- package/dist/buildmyiq/pages/authoring/AuthoringPage.d.ts +4 -0
- package/dist/buildmyiq/pages/authoring/AuthoringPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/authoring/AuthoringPage.js +4 -4
- package/dist/buildmyiq/pages/authoring/AuthoringPage.js.map +1 -1
- package/dist/buildmyiq/pages/authoring/CourseBuilderPage.d.ts +4 -0
- package/dist/buildmyiq/pages/authoring/CourseBuilderPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/authoring/_forms.d.ts +44 -0
- package/dist/buildmyiq/pages/authoring/_forms.d.ts.map +1 -0
- package/dist/buildmyiq/pages/authoring/_forms.js +15 -15
- package/dist/buildmyiq/pages/authoring/_forms.js.map +1 -1
- package/dist/buildmyiq/pages/catalog/CatalogPage.d.ts +4 -0
- package/dist/buildmyiq/pages/catalog/CatalogPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/catalog/CourseDetailPage.d.ts +4 -0
- package/dist/buildmyiq/pages/catalog/CourseDetailPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/catalog/CourseDetailPage.js +9 -1
- package/dist/buildmyiq/pages/catalog/CourseDetailPage.js.map +1 -1
- package/dist/buildmyiq/pages/certificates/CertificatesPage.d.ts +4 -0
- package/dist/buildmyiq/pages/certificates/CertificatesPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/certificates/CertificatesPage.js +1 -1
- package/dist/buildmyiq/pages/certificates/CertificatesPage.js.map +1 -1
- package/dist/buildmyiq/pages/cohorts/CohortsPage.d.ts +4 -0
- package/dist/buildmyiq/pages/cohorts/CohortsPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/cohorts/CohortsPage.js +1 -1
- package/dist/buildmyiq/pages/cohorts/CohortsPage.js.map +1 -1
- package/dist/buildmyiq/pages/insights/InsightsPage.d.ts +4 -0
- package/dist/buildmyiq/pages/insights/InsightsPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/insights/InsightsPage.js +242 -0
- package/dist/buildmyiq/pages/insights/InsightsPage.js.map +1 -0
- package/dist/buildmyiq/pages/learning/LessonPlayerPage.d.ts +4 -0
- package/dist/buildmyiq/pages/learning/LessonPlayerPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/learning/MyLearningPage.d.ts +4 -0
- package/dist/buildmyiq/pages/learning/MyLearningPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/learning/MyLearningPage.js +83 -77
- package/dist/buildmyiq/pages/learning/MyLearningPage.js.map +1 -1
- package/dist/buildmyiq/pages/skills/SkillsPage.d.ts +4 -0
- package/dist/buildmyiq/pages/skills/SkillsPage.d.ts.map +1 -0
- package/dist/buildmyiq/pages/submissions/SubmissionsPage.d.ts +4 -0
- package/dist/buildmyiq/pages/submissions/SubmissionsPage.d.ts.map +1 -0
- package/dist/buildmyiq/types/index.d.ts +382 -0
- package/dist/buildmyiq/types/index.d.ts.map +1 -0
- package/dist/buildmyiq/utils/cn.d.ts +4 -0
- package/dist/buildmyiq/utils/cn.d.ts.map +1 -0
- package/dist/buildmyiq/utils/formatters.d.ts +33 -0
- package/dist/buildmyiq/utils/formatters.d.ts.map +1 -0
- package/dist/buildmyiq/utils/i18n.d.ts +6 -0
- package/dist/buildmyiq/utils/i18n.d.ts.map +1 -0
- package/dist/buildmyiq/utils/index.d.ts +9 -0
- package/dist/buildmyiq/utils/index.d.ts.map +1 -0
- package/dist/buildmyiq/utils/navigation.d.ts +14 -0
- package/dist/buildmyiq/utils/navigation.d.ts.map +1 -0
- package/dist/dev/main.d.ts +2 -0
- package/dist/dev/main.d.ts.map +1 -0
- package/dist/generated/global-operations.d.ts +2 -0
- package/dist/generated/global-operations.d.ts.map +1 -0
- package/dist/generated/global-types.d.ts +18199 -0
- package/dist/generated/global-types.d.ts.map +1 -0
- package/dist/generated/wspace-operations.d.ts +2 -0
- package/dist/generated/wspace-operations.d.ts.map +1 -0
- package/dist/generated/wspace-types.d.ts +43046 -0
- package/dist/generated/wspace-types.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MyLearningPage.js","names":[],"sources":["../../../../src/buildmyiq/pages/learning/MyLearningPage.tsx"],"sourcesContent":["/**\n * MyLearningPage — the caller's personal learning surface.\n * @module buildmyiq/pages/learning\n *\n * Renders the current learner's real enrollments (`buiListEnrollments` filtered\n * by `learnerId`) grouped by progress, plus the credentials they have earned\n * (`buiListCertificates`). Course titles are resolved from `buiListCourses`\n * (id → title map, falling back to \"Course\"). Every list carries an honest\n * loading / error / empty state — no fabricated rows.\n */\n\nimport type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { GraduationCap, Award, ArrowRight, PlayCircle } from 'lucide-react';\nimport { Button, GlassCard } from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n Tabs,\n StatusBadge,\n MiniBar,\n EmptyState,\n LoadingView,\n ErrorView,\n Section,\n FileLink,\n} from '../../components';\nimport type { TabItem } from '../../components';\nimport { useBuildmyiq } from '../../context';\nimport { useBuiEnrollments, useBuiCourses, useBuiCertificates } from '../../hooks';\nimport { formatRelativeTime, formatDate } from '../../utils/formatters';\nimport type { BuiEnrollment, BuiCourse, BuiCertificate } from '../../types';\n\ntype LearningTab = 'in_progress' | 'completed' | 'all';\n\nconst IN_PROGRESS_STATUSES = new Set(['ENROLLED', 'IN_PROGRESS']);\n\nexport const MyLearningPage: FC = () => {\n const { currentUser, navigateTo } = useBuildmyiq();\n const learnerId = currentUser?.id;\n\n const [tab, setTab] = useState<LearningTab>('in_progress');\n\n const enrollmentsQuery = useBuiEnrollments({\n learnerId,\n limit: 100,\n enabled: Boolean(learnerId),\n });\n const coursesQuery = useBuiCourses({ limit: 100 });\n const certsQuery = useBuiCertificates(undefined, learnerId);\n\n const enrollments: BuiEnrollment[] = useMemo(\n () => enrollmentsQuery.data?.items ?? [],\n [enrollmentsQuery.data]\n );\n const courses: BuiCourse[] = useMemo(() => coursesQuery.data?.items ?? [], [coursesQuery.data]);\n const certificates: BuiCertificate[] = useMemo(() => certsQuery.data ?? [], [certsQuery.data]);\n\n const courseTitleById = useMemo(() => {\n const map = new Map<string, string>();\n for (const c of courses) map.set(c.id, c.title);\n return map;\n }, [courses]);\n\n const titleFor = (courseId: string): string => courseTitleById.get(courseId) ?? 'Course';\n\n const inProgress = useMemo(\n () => enrollments.filter((e) => IN_PROGRESS_STATUSES.has(e.status)),\n [enrollments]\n );\n const completed = useMemo(\n () => enrollments.filter((e) => e.status === 'COMPLETED'),\n [enrollments]\n );\n\n const visible = useMemo(() => {\n const rows = tab === 'in_progress' ? inProgress : tab === 'completed' ? completed : enrollments;\n return [...rows].sort((a, b) =>\n (b.lastActiveAt ?? b.enrolledAt).localeCompare(a.lastActiveAt ?? a.enrolledAt)\n );\n }, [tab, inProgress, completed, enrollments]);\n\n const sortedCertificates = useMemo(\n () => [...certificates].sort((a, b) => b.issuedAt.localeCompare(a.issuedAt)),\n [certificates]\n );\n\n const tabs: TabItem<LearningTab>[] = [\n { value: 'in_progress', label: 'In progress', count: inProgress.length },\n { value: 'completed', label: 'Completed', count: completed.length },\n { value: 'all', label: 'All', count: enrollments.length },\n ];\n\n const isLoading = Boolean(learnerId) && (enrollmentsQuery.isLoading || coursesQuery.isLoading);\n\n const renderEnrollments = () => {\n if (!learnerId) {\n return (\n <EmptyState\n illustration=\"empty-people\"\n title=\"Sign in to see your learning\"\n description=\"Your enrollments and progress appear here once you are signed in to the workspace.\"\n />\n );\n }\n if (isLoading) return <LoadingView label=\"Loading your enrollments…\" />;\n if (enrollmentsQuery.isError) {\n return (\n <ErrorView\n title=\"Couldn't load your learning\"\n message={\n enrollmentsQuery.error instanceof Error ? enrollmentsQuery.error.message : undefined\n }\n onRetry={() => enrollmentsQuery.refetch()}\n />\n );\n }\n if (enrollments.length === 0) {\n return (\n <EmptyState\n illustration=\"onboarding\"\n title=\"You're not enrolled in anything yet\"\n description=\"Browse the catalog and enrol in a course to start learning.\"\n action={<Button onClick={() => navigateTo('catalog')}>Explore the catalog</Button>}\n />\n );\n }\n if (visible.length === 0) {\n const label =\n tab === 'in_progress'\n ? 'No courses in progress'\n : tab === 'completed'\n ? 'No completed courses yet'\n : 'No courses';\n return (\n <EmptyState\n illustration=\"empty-data\"\n title={label}\n description={\n tab === 'completed'\n ? 'Finish a course to see it here — and earn a certificate.'\n : 'Switch tabs or enrol in a new course to keep learning.'\n }\n />\n );\n }\n return (\n <div className=\"flex flex-col gap-3\">\n {visible.map((e) => (\n <GlassCard\n key={e.id}\n treatment=\"plain\"\n className=\"flex flex-col gap-3 p-4 sm:flex-row sm:items-center sm:gap-4\"\n >\n <div className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)]\">\n <PlayCircle className=\"h-5 w-5 text-text-primary\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <p className=\"truncate font-medium text-text-primary\">{titleFor(e.courseId)}</p>\n <StatusBadge status={e.status} />\n </div>\n <div className=\"mt-2 flex items-center gap-2\">\n <MiniBar value={e.progressPct} className=\"max-w-sm flex-1\" />\n <span className=\"shrink-0 text-xs tabular-nums text-text-secondary\">\n {Math.round(e.progressPct ?? 0)}%\n </span>\n </div>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {e.status === 'COMPLETED' && e.completedAt\n ? `Completed ${formatRelativeTime(e.completedAt)}`\n : `Active ${formatRelativeTime(e.lastActiveAt ?? e.enrolledAt)}`}\n </p>\n </div>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n className=\"shrink-0 max-sm:w-full\"\n onClick={() => navigateTo(`learning/${e.id}`)}\n >\n {e.status === 'COMPLETED' ? 'Review' : 'Continue'}\n <ArrowRight className=\"ml-1 h-4 w-4\" />\n </Button>\n </GlassCard>\n ))}\n </div>\n );\n };\n\n const renderCertificates = () => {\n if (!learnerId) return null;\n if (certsQuery.isLoading) return <LoadingView label=\"Loading your certificates…\" />;\n if (certsQuery.isError) {\n return (\n <ErrorView\n title=\"Couldn't load your certificates\"\n message={certsQuery.error instanceof Error ? certsQuery.error.message : undefined}\n onRetry={() => certsQuery.refetch()}\n />\n );\n }\n if (sortedCertificates.length === 0) {\n return (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No certificates yet\"\n description=\"Complete a credentialed course to earn a verifiable certificate.\"\n />\n );\n }\n return (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {sortedCertificates.map((cert) => (\n <GlassCard key={cert.id} treatment=\"plain\" className=\"flex flex-col gap-3 p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)]\">\n <Award className=\"h-5 w-5 text-text-primary\" />\n </div>\n <StatusBadge status={cert.status} />\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{titleFor(cert.courseId)}</p>\n <p className=\"mt-0.5 font-mono text-xs text-text-secondary\">{cert.serial}</p>\n </div>\n <div className=\"mt-auto flex flex-wrap items-center justify-between gap-2 pt-1 text-xs text-text-secondary\">\n <span>Issued {formatDate(cert.issuedAt)}</span>\n {cert.file ? <FileLink fileId={cert.file.id} /> : null}\n </div>\n </GlassCard>\n ))}\n </div>\n );\n };\n\n return (\n <PageLayout\n title=\"My Learning\"\n description=\"Your enrollments, progress and the credentials you've earned.\"\n titleGradient\n aurora\n >\n <div className=\"flex flex-col gap-6\">\n <Section title=\"Courses\" description=\"Everything you're enrolled in.\">\n {learnerId && enrollments.length > 0 && (\n <div className=\"mb-4\">\n <Tabs items={tabs} value={tab} onChange={setTab} />\n </div>\n )}\n {renderEnrollments()}\n </Section>\n\n <Section\n title=\"Certificates\"\n description=\"Verifiable credentials issued for the courses you've completed.\"\n action={\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateTo('certificates')}>\n <GraduationCap className=\"mr-1 h-4 w-4\" /> All certificates\n </Button>\n }\n >\n {renderCertificates()}\n </Section>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MyLearningPage.js","names":[],"sources":["../../../../src/buildmyiq/pages/learning/MyLearningPage.tsx"],"sourcesContent":["/**\n * MyLearningPage — the caller's personal learning surface.\n * @module buildmyiq/pages/learning\n *\n * Renders the current learner's real enrollments (`buiListEnrollments` filtered\n * by `learnerId`) grouped by progress, plus the credentials they have earned\n * (`buiListCertificates`). Course titles are resolved from `buiListCourses`\n * (id → title map, falling back to \"Course\"). Every list carries an honest\n * loading / error / empty state — no fabricated rows.\n */\n\nimport type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { GraduationCap, Award, ArrowRight, PlayCircle, ClipboardCheck } from 'lucide-react';\nimport { Button, GlassCard } from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n Tabs,\n StatusBadge,\n MiniBar,\n EmptyState,\n LoadingView,\n ErrorView,\n Section,\n FileLink,\n} from '../../components';\nimport type { TabItem } from '../../components';\nimport { useBuildmyiq } from '../../context';\nimport {\n useBuiEnrollments,\n useBuiCourses,\n useBuiCertificates,\n useBuiSubmissions,\n} from '../../hooks';\nimport { formatRelativeTime, formatDate } from '../../utils/formatters';\nimport type { BuiEnrollment, BuiCourse, BuiCertificate } from '../../types';\n\ntype LearningTab = 'in_progress' | 'completed' | 'all';\n\nconst IN_PROGRESS_STATUSES = new Set(['ENROLLED', 'IN_PROGRESS']);\n\nexport const MyLearningPage: FC = () => {\n const { currentUser, navigateTo } = useBuildmyiq();\n const learnerId = currentUser?.id;\n\n const [tab, setTab] = useState<LearningTab>('in_progress');\n\n const enrollmentsQuery = useBuiEnrollments({\n learnerId,\n limit: 100,\n enabled: Boolean(learnerId),\n });\n const coursesQuery = useBuiCourses({ limit: 100 });\n const certsQuery = useBuiCertificates(undefined, learnerId);\n const submissionsQuery = useBuiSubmissions({\n learnerId,\n limit: 50,\n enabled: Boolean(learnerId),\n });\n const submissions = useMemo(\n () =>\n [...(submissionsQuery.data?.items ?? [])].sort((a, b) =>\n (b.submittedAt ?? b.createdAt).localeCompare(a.submittedAt ?? a.createdAt)\n ),\n [submissionsQuery.data]\n );\n\n const enrollments: BuiEnrollment[] = useMemo(\n () => enrollmentsQuery.data?.items ?? [],\n [enrollmentsQuery.data]\n );\n const courses: BuiCourse[] = useMemo(() => coursesQuery.data?.items ?? [], [coursesQuery.data]);\n const certificates: BuiCertificate[] = useMemo(() => certsQuery.data ?? [], [certsQuery.data]);\n\n const courseTitleById = useMemo(() => {\n const map = new Map<string, string>();\n for (const c of courses) map.set(c.id, c.title);\n return map;\n }, [courses]);\n\n const titleFor = (courseId: string): string => courseTitleById.get(courseId) ?? 'Course';\n\n const inProgress = useMemo(\n () => enrollments.filter((e) => IN_PROGRESS_STATUSES.has(e.status)),\n [enrollments]\n );\n const completed = useMemo(\n () => enrollments.filter((e) => e.status === 'COMPLETED'),\n [enrollments]\n );\n\n const visible = useMemo(() => {\n const rows = tab === 'in_progress' ? inProgress : tab === 'completed' ? completed : enrollments;\n return [...rows].sort((a, b) =>\n (b.lastActiveAt ?? b.enrolledAt).localeCompare(a.lastActiveAt ?? a.enrolledAt)\n );\n }, [tab, inProgress, completed, enrollments]);\n\n const sortedCertificates = useMemo(\n () => [...certificates].sort((a, b) => b.issuedAt.localeCompare(a.issuedAt)),\n [certificates]\n );\n\n const tabs: TabItem<LearningTab>[] = [\n { value: 'in_progress', label: 'In progress', count: inProgress.length },\n { value: 'completed', label: 'Completed', count: completed.length },\n { value: 'all', label: 'All', count: enrollments.length },\n ];\n\n const isLoading = Boolean(learnerId) && (enrollmentsQuery.isLoading || coursesQuery.isLoading);\n\n const renderEnrollments = () => {\n if (!learnerId) {\n return (\n <EmptyState\n illustration=\"empty-people\"\n title=\"Sign in to see your learning\"\n description=\"Your enrollments and progress appear here once you are signed in to the workspace.\"\n />\n );\n }\n if (isLoading) return <LoadingView label=\"Loading your enrollments…\" />;\n if (enrollmentsQuery.isError) {\n return (\n <ErrorView\n title=\"Couldn't load your learning\"\n message={\n enrollmentsQuery.error instanceof Error ? enrollmentsQuery.error.message : undefined\n }\n onRetry={() => enrollmentsQuery.refetch()}\n />\n );\n }\n if (enrollments.length === 0) {\n return (\n <EmptyState\n illustration=\"onboarding\"\n title=\"You're not enrolled in anything yet\"\n description=\"Browse the catalog and enrol in a course to start learning.\"\n action={<Button onClick={() => navigateTo('catalog')}>Explore the catalog</Button>}\n />\n );\n }\n if (visible.length === 0) {\n const label =\n tab === 'in_progress'\n ? 'No courses in progress'\n : tab === 'completed'\n ? 'No completed courses yet'\n : 'No courses';\n return (\n <EmptyState\n illustration=\"empty-data\"\n title={label}\n description={\n tab === 'completed'\n ? 'Finish a course to see it here — and earn a certificate.'\n : 'Switch tabs or enrol in a new course to keep learning.'\n }\n />\n );\n }\n return (\n <div className=\"flex flex-col gap-3\">\n {visible.map((e) => (\n <GlassCard\n key={e.id}\n treatment=\"plain\"\n className=\"flex flex-col gap-3 p-4 sm:flex-row sm:items-center sm:gap-4\"\n >\n <div className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)]\">\n <PlayCircle className=\"h-5 w-5 text-text-primary\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <p className=\"truncate font-medium text-text-primary\">{titleFor(e.courseId)}</p>\n <StatusBadge status={e.status} />\n </div>\n <div className=\"mt-2 flex items-center gap-2\">\n <MiniBar value={e.progressPct} className=\"max-w-sm flex-1\" />\n <span className=\"shrink-0 text-xs tabular-nums text-text-secondary\">\n {Math.round(e.progressPct ?? 0)}%\n </span>\n </div>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {e.status === 'COMPLETED' && e.completedAt\n ? `Completed ${formatRelativeTime(e.completedAt)}`\n : `Active ${formatRelativeTime(e.lastActiveAt ?? e.enrolledAt)}`}\n </p>\n </div>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n className=\"shrink-0 max-sm:w-full\"\n onClick={() => navigateTo(`learning/${e.id}`)}\n >\n {e.status === 'COMPLETED' ? 'Review' : 'Continue'}\n <ArrowRight className=\"ml-1 h-4 w-4\" />\n </Button>\n </GlassCard>\n ))}\n </div>\n );\n };\n\n const renderCertificates = () => {\n if (!learnerId) return null;\n if (certsQuery.isLoading) return <LoadingView label=\"Loading your certificates…\" />;\n if (certsQuery.isError) {\n return (\n <ErrorView\n title=\"Couldn't load your certificates\"\n message={certsQuery.error instanceof Error ? certsQuery.error.message : undefined}\n onRetry={() => certsQuery.refetch()}\n />\n );\n }\n if (sortedCertificates.length === 0) {\n return (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No certificates yet\"\n description=\"Complete a credentialed course to earn a verifiable certificate.\"\n />\n );\n }\n return (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {sortedCertificates.map((cert) => (\n <GlassCard key={cert.id} treatment=\"plain\" className=\"flex flex-col gap-3 p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)]\">\n <Award className=\"h-5 w-5 text-text-primary\" />\n </div>\n <StatusBadge status={cert.status} />\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{titleFor(cert.courseId)}</p>\n <p className=\"mt-0.5 font-mono text-xs text-text-secondary\">{cert.serial}</p>\n </div>\n <div className=\"mt-auto flex flex-wrap items-center justify-between gap-2 pt-1 text-xs text-text-secondary\">\n <span>Issued {formatDate(cert.issuedAt)}</span>\n {cert.file ? <FileLink fileId={cert.file.id} /> : null}\n </div>\n </GlassCard>\n ))}\n </div>\n );\n };\n\n const renderResults = () => {\n if (!learnerId) return null;\n if (submissionsQuery.isLoading) return <LoadingView label=\"Loading your results…\" />;\n if (submissionsQuery.isError)\n return (\n <ErrorView\n title=\"Couldn't load your results\"\n message={submissionsQuery.error instanceof Error ? submissionsQuery.error.message : undefined}\n onRetry={() => submissionsQuery.refetch()}\n />\n );\n if (submissions.length === 0)\n return (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No assessment results yet\"\n description=\"Take a course assessment and your score and feedback will appear here.\"\n />\n );\n return (\n <div className=\"flex flex-col gap-3\">\n {submissions.map((s) => (\n <GlassCard key={s.id} treatment=\"plain\" className=\"flex flex-wrap items-center gap-3 p-4\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)]\">\n <ClipboardCheck className=\"h-5 w-5 text-text-primary\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <p className=\"font-medium text-text-primary\">Attempt {s.attempt}</p>\n <StatusBadge status={s.status} />\n {s.passed != null && (\n <span\n className={`text-xs font-medium ${s.passed ? 'text-status-success-text' : 'text-status-error-text'}`}\n >\n {s.passed ? 'Passed' : 'Not passed'}\n </span>\n )}\n </div>\n {s.feedback && <p className=\"mt-1 text-sm text-text-secondary\">{s.feedback}</p>}\n <p className=\"mt-1 text-xs text-text-secondary\">\n Submitted {formatDate(s.submittedAt ?? s.createdAt)}\n {s.gradedAt ? ` · graded ${formatDate(s.gradedAt)}` : ''}\n </p>\n </div>\n <div className=\"shrink-0 text-right\">\n <p className=\"text-lg font-semibold tabular-nums text-text-primary\">\n {s.score != null ? `${s.score}%` : '—'}\n </p>\n <p className=\"text-xs text-text-secondary\">score</p>\n </div>\n </GlassCard>\n ))}\n </div>\n );\n };\n\n return (\n <PageLayout\n title=\"My Learning\"\n description=\"Your enrollments, progress and the credentials you've earned.\"\n titleGradient\n aurora\n >\n <div className=\"flex flex-col gap-6\">\n <Section title=\"Courses\" description=\"Everything you're enrolled in.\">\n {learnerId && enrollments.length > 0 && (\n <div className=\"mb-4\">\n <Tabs items={tabs} value={tab} onChange={setTab} />\n </div>\n )}\n {renderEnrollments()}\n </Section>\n\n <Section\n title=\"Certificates\"\n description=\"Verifiable credentials issued for the courses you've completed.\"\n action={\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateTo('certificates')}>\n <GraduationCap className=\"mr-1 h-4 w-4\" /> All certificates\n </Button>\n }\n >\n {renderCertificates()}\n </Section>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAuCA,IAAM,IAAuB,IAAI,IAAI,CAAC,YAAY,cAAc,CAAC,EAEpD,UAA2B;CACtC,IAAM,EAAE,gBAAa,kBAAe,GAAc,EAC5C,IAAY,GAAa,IAEzB,CAAC,GAAK,KAAU,EAAsB,cAAc,EAEpD,IAAmB,EAAkB;EACzC;EACA,OAAO;EACP,SAAS,EAAQ;EAClB,CAAC,EACI,IAAe,EAAc,EAAE,OAAO,KAAK,CAAC,EAC5C,IAAa,EAAmB,KAAA,GAAW,EAAU,EACrD,IAAmB,EAAkB;EACzC;EACA,OAAO;EACP,SAAS,EAAQ;EAClB,CAAC;AACkB,SAEhB,CAAC,GAAI,EAAiB,MAAM,SAAS,EAAE,CAAE,CAAC,MAAM,GAAG,OAChD,EAAE,eAAe,EAAE,WAAW,cAAc,EAAE,eAAe,EAAE,UAAU,CAC3E,EACH,CAAC,EAAiB,KAAK,CACxB;CAED,IAAM,IAA+B,QAC7B,EAAiB,MAAM,SAAS,EAAE,EACxC,CAAC,EAAiB,KAAK,CACxB,EACK,IAAuB,QAAc,EAAa,MAAM,SAAS,EAAE,EAAE,CAAC,EAAa,KAAK,CAAC,EACzF,IAAiC,QAAc,EAAW,QAAQ,EAAE,EAAE,CAAC,EAAW,KAAK,CAAC,EAExF,IAAkB,QAAc;EACpC,IAAM,oBAAM,IAAI,KAAqB;AACrC,OAAK,IAAM,KAAK,EAAS,GAAI,IAAI,EAAE,IAAI,EAAE,MAAM;AAC/C,SAAO;IACN,CAAC,EAAQ,CAAC,EAEP,KAAY,MAA6B,EAAgB,IAAI,EAAS,IAAI,UAE1E,IAAa,QACX,EAAY,QAAQ,MAAM,EAAqB,IAAI,EAAE,OAAO,CAAC,EACnE,CAAC,EAAY,CACd,EACK,IAAY,QACV,EAAY,QAAQ,MAAM,EAAE,WAAW,YAAY,EACzD,CAAC,EAAY,CACd,EAEK,IAAU,QAEP,CAAC,GADK,MAAQ,gBAAgB,IAAa,MAAQ,cAAc,IAAY,EACpE,CAAC,MAAM,GAAG,OACvB,EAAE,gBAAgB,EAAE,YAAY,cAAc,EAAE,gBAAgB,EAAE,WAAW,CAC/E,EACA;EAAC;EAAK;EAAY;EAAW;EAAY,CAAC,EAEvC,IAAqB,QACnB,CAAC,GAAG,EAAa,CAAC,MAAM,GAAG,MAAM,EAAE,SAAS,cAAc,EAAE,SAAS,CAAC,EAC5E,CAAC,EAAa,CACf,EAEK,IAA+B;EACnC;GAAE,OAAO;GAAe,OAAO;GAAe,OAAO,EAAW;GAAQ;EACxE;GAAE,OAAO;GAAa,OAAO;GAAa,OAAO,EAAU;GAAQ;EACnE;GAAE,OAAO;GAAO,OAAO;GAAO,OAAO,EAAY;GAAQ;EAC1D,EAEK,IAAY,EAAQ,MAAe,EAAiB,aAAa,EAAa;AAqMpF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,eAAA;EACA,QAAA;YAEA,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IAAS,OAAM;IAAU,aAAY;cAArC,CACG,KAAa,EAAY,SAAS,KACjC,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD;MAAM,OAAO;MAAM,OAAO;MAAK,UAAU;MAAU,CAAA;KAC/C,CAAA,EA9MT,IASD,IAAkB,kBAAC,GAAD,EAAa,OAAM,6BAA8B,CAAA,GACnE,EAAiB,UAEjB,kBAAC,GAAD;KACE,OAAM;KACN,SACE,EAAiB,iBAAiB,QAAQ,EAAiB,MAAM,UAAU,KAAA;KAE7E,eAAe,EAAiB,SAAS;KACzC,CAAA,GAGF,EAAY,WAAW,IAEvB,kBAAC,GAAD;KACE,cAAa;KACb,OAAM;KACN,aAAY;KACZ,QAAQ,kBAAC,GAAD;MAAQ,eAAe,EAAW,UAAU;gBAAE;MAA4B,CAAA;KAClF,CAAA,GAGF,EAAQ,WAAW,IAQnB,kBAAC,GAAD;KACE,cAAa;KACb,OARF,MAAQ,gBACJ,2BACA,MAAQ,cACN,6BACA;KAKJ,aACE,MAAQ,cACJ,6DACA;KAEN,CAAA,GAIJ,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAQ,KAAK,MACZ,kBAAC,GAAD;MAEE,WAAU;MACV,WAAU;gBAHZ;OAKE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD,EAAY,WAAU,6BAA8B,CAAA;QAChD,CAAA;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,KAAD;WAAG,WAAU;qBAA0C,EAAS,EAAE,SAAS;WAAK,CAAA,EAChF,kBAAC,GAAD,EAAa,QAAQ,EAAE,QAAU,CAAA,CAC7B;;SACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,GAAD;WAAS,OAAO,EAAE;WAAa,WAAU;WAAoB,CAAA,EAC7D,kBAAC,QAAD;WAAM,WAAU;qBAAhB,CACG,KAAK,MAAM,EAAE,eAAe,EAAE,EAAC,IAC3B;aACH;;SACN,kBAAC,KAAD;UAAG,WAAU;oBACV,EAAE,WAAW,eAAe,EAAE,cAC3B,aAAa,EAAmB,EAAE,YAAY,KAC9C,UAAU,EAAmB,EAAE,gBAAgB,EAAE,WAAW;UAC9D,CAAA;SACA;;OACN,kBAAC,GAAD;QACE,SAAQ;QACR,MAAK;QACL,WAAU;QACV,eAAe,EAAW,YAAY,EAAE,KAAK;kBAJ/C,CAMG,EAAE,WAAW,cAAc,WAAW,YACvC,kBAAC,GAAD,EAAY,WAAU,gBAAiB,CAAA,CAChC;;OACC;QAjCL,EAAE,GAiCG,CACZ;KACE,CAAA,GAvFJ,kBAAC,GAAD;KACE,cAAa;KACb,OAAM;KACN,aAAY;KACZ,CAAA,CA2MQ;OAEV,kBAAC,GAAD;IACE,OAAM;IACN,aAAY;IACZ,QACE,kBAAC,GAAD;KAAQ,SAAQ;KAAQ,MAAK;KAAK,eAAe,EAAW,eAAe;eAA3E,CACE,kBAAC,GAAD,EAAe,WAAU,gBAAiB,CAAA,EAAA,oBACnC;;cA3HZ,IACD,EAAW,YAAkB,kBAAC,GAAD,EAAa,OAAM,8BAA+B,CAAA,GAC/E,EAAW,UAEX,kBAAC,GAAD;KACE,OAAM;KACN,SAAS,EAAW,iBAAiB,QAAQ,EAAW,MAAM,UAAU,KAAA;KACxE,eAAe,EAAW,SAAS;KACnC,CAAA,GAGF,EAAmB,WAAW,IAE9B,kBAAC,GAAD;KACE,cAAa;KACb,OAAM;KACN,aAAY;KACZ,CAAA,GAIJ,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAmB,KAAK,MACvB,kBAAC,GAAD;MAAyB,WAAU;MAAQ,WAAU;gBAArD;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD,EAAO,WAAU,6BAA8B,CAAA;SAC3C,CAAA,EACN,kBAAC,GAAD,EAAa,QAAQ,EAAK,QAAU,CAAA,CAChC;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBAA0C,EAAS,EAAK,SAAS;SAAK,CAAA,EACnF,kBAAC,KAAD;SAAG,WAAU;mBAAgD,EAAK;SAAW,CAAA,CACzE;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD,EAAA,UAAA,CAAM,WAAQ,EAAW,EAAK,SAAS,CAAQ,EAAA,CAAA,EAC9C,EAAK,OAAO,kBAAC,GAAD,EAAU,QAAQ,EAAK,KAAK,IAAM,CAAA,GAAG,KAC9C;;OACI;QAfI,EAAK,GAeT,CACZ;KACE,CAAA,GAxCe;IA+HT,CAAA,CACN;;EACK,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillsPage.d.ts","sourceRoot":"","sources":["../../../../src/buildmyiq/pages/skills/SkillsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AA6FhC,eAAO,MAAM,UAAU,EAAE,EA8LxB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubmissionsPage.d.ts","sourceRoot":"","sources":["../../../../src/buildmyiq/pages/submissions/SubmissionsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,EAAE,EAAa,MAAM,OAAO,CAAC;AAmG3C,eAAO,MAAM,eAAe,EAAE,EAyX7B,CAAC"}
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface NavItem {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
path: string;
|
|
7
|
+
icon?: ReactNode;
|
|
8
|
+
badge?: number;
|
|
9
|
+
order?: number;
|
|
10
|
+
group?: string;
|
|
11
|
+
visible?: boolean;
|
|
12
|
+
external?: boolean;
|
|
13
|
+
children?: NavItem[];
|
|
14
|
+
}
|
|
15
|
+
export interface FooterItem {
|
|
16
|
+
id: string;
|
|
17
|
+
label: string;
|
|
18
|
+
icon?: string;
|
|
19
|
+
onClick?: () => void;
|
|
20
|
+
type?: 'status' | 'action' | 'info';
|
|
21
|
+
order?: number;
|
|
22
|
+
badge?: string;
|
|
23
|
+
section?: 'left' | 'center' | 'right';
|
|
24
|
+
visible?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Props for the BuildmyiqRoot component. Host-contract preserving: the app
|
|
28
|
+
* shell spreads `workspaceBaseProps` (basePath, currentUser, workspaceId,
|
|
29
|
+
* tenantId, apiGatewayUrl, authToken, navigate, registerNavItems,
|
|
30
|
+
* registerFooterItems) onto this component.
|
|
31
|
+
*/
|
|
32
|
+
export interface BuildmyiqRootProps {
|
|
33
|
+
basePath?: string;
|
|
34
|
+
workspaceId?: string;
|
|
35
|
+
tenantId?: string;
|
|
36
|
+
apiGatewayUrl?: string;
|
|
37
|
+
authToken?: string;
|
|
38
|
+
navigate?: (path: string) => void;
|
|
39
|
+
currentUser?: {
|
|
40
|
+
id: string;
|
|
41
|
+
email: string;
|
|
42
|
+
firstName?: string;
|
|
43
|
+
lastName?: string;
|
|
44
|
+
avatar?: string;
|
|
45
|
+
username?: string;
|
|
46
|
+
name?: string;
|
|
47
|
+
role?: string;
|
|
48
|
+
} | null;
|
|
49
|
+
registerNavItems?: (items: NavItem | NavItem[]) => () => void;
|
|
50
|
+
registerFooterItems?: (items: FooterItem | FooterItem[]) => () => void;
|
|
51
|
+
}
|
|
52
|
+
export type TrendDirection = 'up' | 'down' | 'neutral';
|
|
53
|
+
/**
|
|
54
|
+
* The svc `PaginationInput` accepts { limit, offset, cursor } but the resolver
|
|
55
|
+
* uses cursor+limit only (offset is a no-op). We drive pages by cursor:
|
|
56
|
+
* pass `pagination.cursor = previous pageInfo.cursor` for the next page. The
|
|
57
|
+
* FIRST page must OMIT cursor entirely (an explicit `cursor: null` is rejected).
|
|
58
|
+
*/
|
|
59
|
+
export interface PaginationInput {
|
|
60
|
+
limit?: number;
|
|
61
|
+
offset?: number;
|
|
62
|
+
cursor?: string | null;
|
|
63
|
+
}
|
|
64
|
+
/** All Bui*PageInfo variants are structurally { cursor, hasMore }. */
|
|
65
|
+
export interface BuiPageInfo {
|
|
66
|
+
cursor?: string | null;
|
|
67
|
+
hasMore: boolean;
|
|
68
|
+
}
|
|
69
|
+
export interface BuiConnection<T> {
|
|
70
|
+
items: T[];
|
|
71
|
+
pageInfo: BuiPageInfo;
|
|
72
|
+
}
|
|
73
|
+
/** A wspace-files-svc File reference resolved for cover/media/certificate. */
|
|
74
|
+
export interface BuiFileRef {
|
|
75
|
+
id: string;
|
|
76
|
+
name?: string | null;
|
|
77
|
+
downloadUrl?: string | null;
|
|
78
|
+
mimeType?: string | null;
|
|
79
|
+
sizeBytes?: number | null;
|
|
80
|
+
}
|
|
81
|
+
export type BuiSkillCategory = 'TECHNICAL' | 'BUSINESS' | 'CREATIVE' | 'COGNITIVE' | 'SOCIAL' | 'LANGUAGE';
|
|
82
|
+
export type BuiCourseLevel = 'BEGINNER' | 'INTERMEDIATE' | 'ADVANCED' | 'EXPERT';
|
|
83
|
+
export type BuiCourseStatus = 'DRAFT' | 'IN_REVIEW' | 'PUBLISHED' | 'ARCHIVED';
|
|
84
|
+
export type BuiLessonType = 'ARTICLE' | 'VIDEO' | 'QUIZ' | 'ASSIGNMENT' | 'INTERACTIVE' | 'LIVE_SESSION';
|
|
85
|
+
export type BuiAssessmentType = 'QUIZ' | 'EXAM' | 'ASSIGNMENT' | 'PRACTICAL' | 'SURVEY';
|
|
86
|
+
export type BuiAssessmentStatus = 'DRAFT' | 'PUBLISHED' | 'ARCHIVED';
|
|
87
|
+
export type BuiQuestionType = 'SINGLE_CHOICE' | 'MULTIPLE_CHOICE' | 'TRUE_FALSE' | 'SHORT_ANSWER' | 'ESSAY' | 'CODE';
|
|
88
|
+
export type BuiSubmissionStatus = 'IN_PROGRESS' | 'SUBMITTED' | 'GRADING' | 'GRADED' | 'RETURNED';
|
|
89
|
+
export type BuiEnrollmentStatus = 'ENROLLED' | 'IN_PROGRESS' | 'COMPLETED' | 'DROPPED' | 'EXPIRED';
|
|
90
|
+
export type BuiProgressStatus = 'NOT_STARTED' | 'IN_PROGRESS' | 'COMPLETED';
|
|
91
|
+
export type BuiCohortStatus = 'SCHEDULED' | 'ENROLLING' | 'ACTIVE' | 'COMPLETED' | 'CANCELLED';
|
|
92
|
+
export type BuiCertificateStatus = 'ISSUED' | 'EXPIRED' | 'REVOKED';
|
|
93
|
+
export interface BuiSkill {
|
|
94
|
+
id: string;
|
|
95
|
+
workspaceId: string;
|
|
96
|
+
name: string;
|
|
97
|
+
category: BuiSkillCategory;
|
|
98
|
+
description?: string | null;
|
|
99
|
+
isActive: boolean;
|
|
100
|
+
createdAt: string;
|
|
101
|
+
updatedAt: string;
|
|
102
|
+
}
|
|
103
|
+
export interface BuiModule {
|
|
104
|
+
id: string;
|
|
105
|
+
workspaceId: string;
|
|
106
|
+
courseId: string;
|
|
107
|
+
title: string;
|
|
108
|
+
description?: string | null;
|
|
109
|
+
position: number;
|
|
110
|
+
lessons: BuiLesson[];
|
|
111
|
+
createdAt: string;
|
|
112
|
+
updatedAt: string;
|
|
113
|
+
}
|
|
114
|
+
export interface BuiLesson {
|
|
115
|
+
id: string;
|
|
116
|
+
workspaceId: string;
|
|
117
|
+
courseId: string;
|
|
118
|
+
moduleId?: string | null;
|
|
119
|
+
title: string;
|
|
120
|
+
type: BuiLessonType;
|
|
121
|
+
content?: string | null;
|
|
122
|
+
media?: BuiFileRef | null;
|
|
123
|
+
durationMin: number;
|
|
124
|
+
position: number;
|
|
125
|
+
isPreview: boolean;
|
|
126
|
+
createdAt: string;
|
|
127
|
+
updatedAt: string;
|
|
128
|
+
}
|
|
129
|
+
export interface BuiCourse {
|
|
130
|
+
id: string;
|
|
131
|
+
workspaceId: string;
|
|
132
|
+
title: string;
|
|
133
|
+
slug: string;
|
|
134
|
+
summary?: string | null;
|
|
135
|
+
description?: string | null;
|
|
136
|
+
status: BuiCourseStatus;
|
|
137
|
+
level: BuiCourseLevel;
|
|
138
|
+
language: string;
|
|
139
|
+
estimatedHours: number;
|
|
140
|
+
isPublic: boolean;
|
|
141
|
+
tags: string[];
|
|
142
|
+
skillId?: string | null;
|
|
143
|
+
skill?: BuiSkill | null;
|
|
144
|
+
instructorId?: string | null;
|
|
145
|
+
cover?: BuiFileRef | null;
|
|
146
|
+
publishedAt?: string | null;
|
|
147
|
+
modules: BuiModule[];
|
|
148
|
+
lessons: BuiLesson[];
|
|
149
|
+
createdAt: string;
|
|
150
|
+
updatedAt: string;
|
|
151
|
+
}
|
|
152
|
+
export interface BuiQuestion {
|
|
153
|
+
id: string;
|
|
154
|
+
workspaceId: string;
|
|
155
|
+
assessmentId: string;
|
|
156
|
+
prompt: string;
|
|
157
|
+
type: BuiQuestionType;
|
|
158
|
+
/**
|
|
159
|
+
* JSON blob — array of `{ id?, label }` choices for choice questions. NOTE:
|
|
160
|
+
* `answerKey` is a CREATE-INPUT field only; it is NOT exposed on the type
|
|
161
|
+
* (never query it in a fragment — GRAPHQL_VALIDATION_FAILED).
|
|
162
|
+
*/
|
|
163
|
+
options?: unknown;
|
|
164
|
+
points: number;
|
|
165
|
+
position: number;
|
|
166
|
+
explanation?: string | null;
|
|
167
|
+
createdAt: string;
|
|
168
|
+
updatedAt: string;
|
|
169
|
+
}
|
|
170
|
+
export interface BuiAssessment {
|
|
171
|
+
id: string;
|
|
172
|
+
workspaceId: string;
|
|
173
|
+
courseId: string;
|
|
174
|
+
title: string;
|
|
175
|
+
description?: string | null;
|
|
176
|
+
type: BuiAssessmentType;
|
|
177
|
+
status: BuiAssessmentStatus;
|
|
178
|
+
passingScore: number;
|
|
179
|
+
maxAttempts: number;
|
|
180
|
+
timeLimitMin: number;
|
|
181
|
+
isGraded: boolean;
|
|
182
|
+
questions: BuiQuestion[];
|
|
183
|
+
createdAt: string;
|
|
184
|
+
updatedAt: string;
|
|
185
|
+
}
|
|
186
|
+
export interface BuiSubmission {
|
|
187
|
+
id: string;
|
|
188
|
+
workspaceId: string;
|
|
189
|
+
assessmentId: string;
|
|
190
|
+
enrollmentId?: string | null;
|
|
191
|
+
learnerId: string;
|
|
192
|
+
attempt: number;
|
|
193
|
+
/** JSON blob — learner answers keyed by questionId. */
|
|
194
|
+
answers?: unknown;
|
|
195
|
+
status: BuiSubmissionStatus;
|
|
196
|
+
score?: number | null;
|
|
197
|
+
passed?: boolean | null;
|
|
198
|
+
feedback?: string | null;
|
|
199
|
+
gradedById?: string | null;
|
|
200
|
+
gradedAt?: string | null;
|
|
201
|
+
submittedAt?: string | null;
|
|
202
|
+
createdAt: string;
|
|
203
|
+
updatedAt: string;
|
|
204
|
+
}
|
|
205
|
+
export interface BuiLessonProgress {
|
|
206
|
+
id: string;
|
|
207
|
+
workspaceId: string;
|
|
208
|
+
enrollmentId: string;
|
|
209
|
+
lessonId: string;
|
|
210
|
+
status: BuiProgressStatus;
|
|
211
|
+
secondsSpent: number;
|
|
212
|
+
completedAt?: string | null;
|
|
213
|
+
createdAt: string;
|
|
214
|
+
updatedAt: string;
|
|
215
|
+
}
|
|
216
|
+
export interface BuiCohort {
|
|
217
|
+
id: string;
|
|
218
|
+
workspaceId: string;
|
|
219
|
+
courseId: string;
|
|
220
|
+
name: string;
|
|
221
|
+
capacity: number;
|
|
222
|
+
facilitatorId?: string | null;
|
|
223
|
+
startDate?: string | null;
|
|
224
|
+
endDate?: string | null;
|
|
225
|
+
status: BuiCohortStatus;
|
|
226
|
+
createdAt: string;
|
|
227
|
+
updatedAt: string;
|
|
228
|
+
}
|
|
229
|
+
export interface BuiEnrollment {
|
|
230
|
+
id: string;
|
|
231
|
+
workspaceId: string;
|
|
232
|
+
courseId: string;
|
|
233
|
+
learnerId: string;
|
|
234
|
+
cohortId?: string | null;
|
|
235
|
+
cohort?: BuiCohort | null;
|
|
236
|
+
status: BuiEnrollmentStatus;
|
|
237
|
+
progressPct: number;
|
|
238
|
+
enrolledAt: string;
|
|
239
|
+
startedAt?: string | null;
|
|
240
|
+
completedAt?: string | null;
|
|
241
|
+
lastActiveAt?: string | null;
|
|
242
|
+
expiresAt?: string | null;
|
|
243
|
+
lessonProgress: BuiLessonProgress[];
|
|
244
|
+
createdAt: string;
|
|
245
|
+
updatedAt: string;
|
|
246
|
+
}
|
|
247
|
+
export interface BuiCertificate {
|
|
248
|
+
id: string;
|
|
249
|
+
workspaceId: string;
|
|
250
|
+
courseId: string;
|
|
251
|
+
learnerId: string;
|
|
252
|
+
enrollmentId?: string | null;
|
|
253
|
+
serial: string;
|
|
254
|
+
status: BuiCertificateStatus;
|
|
255
|
+
issuedAt: string;
|
|
256
|
+
expiresAt?: string | null;
|
|
257
|
+
revokedAt?: string | null;
|
|
258
|
+
finalScore?: number | null;
|
|
259
|
+
file?: BuiFileRef | null;
|
|
260
|
+
createdAt: string;
|
|
261
|
+
updatedAt: string;
|
|
262
|
+
}
|
|
263
|
+
export interface BuiCreateCourseInput {
|
|
264
|
+
title: string;
|
|
265
|
+
slug: string;
|
|
266
|
+
summary?: string;
|
|
267
|
+
description?: string;
|
|
268
|
+
level?: BuiCourseLevel;
|
|
269
|
+
language?: string;
|
|
270
|
+
estimatedHours?: number;
|
|
271
|
+
isPublic?: boolean;
|
|
272
|
+
tags?: string[];
|
|
273
|
+
skillId?: string;
|
|
274
|
+
instructorId?: string;
|
|
275
|
+
coverFileId?: string;
|
|
276
|
+
}
|
|
277
|
+
export interface BuiUpdateCourseInput {
|
|
278
|
+
title?: string;
|
|
279
|
+
summary?: string;
|
|
280
|
+
description?: string;
|
|
281
|
+
level?: BuiCourseLevel;
|
|
282
|
+
language?: string;
|
|
283
|
+
estimatedHours?: number;
|
|
284
|
+
isPublic?: boolean;
|
|
285
|
+
tags?: string[];
|
|
286
|
+
skillId?: string;
|
|
287
|
+
instructorId?: string;
|
|
288
|
+
coverFileId?: string;
|
|
289
|
+
}
|
|
290
|
+
export interface BuiCreateModuleInput {
|
|
291
|
+
courseId: string;
|
|
292
|
+
title: string;
|
|
293
|
+
description?: string;
|
|
294
|
+
position?: number;
|
|
295
|
+
}
|
|
296
|
+
export interface BuiCreateLessonInput {
|
|
297
|
+
courseId: string;
|
|
298
|
+
moduleId?: string;
|
|
299
|
+
title: string;
|
|
300
|
+
type?: BuiLessonType;
|
|
301
|
+
content?: string;
|
|
302
|
+
durationMin?: number;
|
|
303
|
+
position?: number;
|
|
304
|
+
isPreview?: boolean;
|
|
305
|
+
mediaFileId?: string;
|
|
306
|
+
}
|
|
307
|
+
export interface BuiCreateAssessmentInput {
|
|
308
|
+
courseId: string;
|
|
309
|
+
title: string;
|
|
310
|
+
description?: string;
|
|
311
|
+
type?: BuiAssessmentType;
|
|
312
|
+
passingScore?: number;
|
|
313
|
+
maxAttempts?: number;
|
|
314
|
+
timeLimitMin?: number;
|
|
315
|
+
isGraded?: boolean;
|
|
316
|
+
}
|
|
317
|
+
export interface BuiCreateQuestionInput {
|
|
318
|
+
assessmentId: string;
|
|
319
|
+
prompt: string;
|
|
320
|
+
type?: BuiQuestionType;
|
|
321
|
+
options?: unknown;
|
|
322
|
+
answerKey?: unknown;
|
|
323
|
+
points?: number;
|
|
324
|
+
position?: number;
|
|
325
|
+
explanation?: string;
|
|
326
|
+
}
|
|
327
|
+
export interface BuiCreateSkillInput {
|
|
328
|
+
name: string;
|
|
329
|
+
category?: BuiSkillCategory;
|
|
330
|
+
description?: string;
|
|
331
|
+
}
|
|
332
|
+
export interface BuiCreateCohortInput {
|
|
333
|
+
courseId: string;
|
|
334
|
+
name: string;
|
|
335
|
+
capacity?: number;
|
|
336
|
+
facilitatorId?: string;
|
|
337
|
+
startDate?: string;
|
|
338
|
+
endDate?: string;
|
|
339
|
+
}
|
|
340
|
+
export interface BuiEnrollInput {
|
|
341
|
+
courseId: string;
|
|
342
|
+
learnerId?: string;
|
|
343
|
+
cohortId?: string;
|
|
344
|
+
expiresAt?: string;
|
|
345
|
+
}
|
|
346
|
+
export interface BuiRecordLessonProgressInput {
|
|
347
|
+
enrollmentId: string;
|
|
348
|
+
lessonId: string;
|
|
349
|
+
secondsSpent?: number;
|
|
350
|
+
status?: BuiProgressStatus;
|
|
351
|
+
}
|
|
352
|
+
export interface BuiSubmitAssessmentInput {
|
|
353
|
+
assessmentId: string;
|
|
354
|
+
learnerId?: string;
|
|
355
|
+
enrollmentId?: string;
|
|
356
|
+
attempt?: number;
|
|
357
|
+
answers?: unknown;
|
|
358
|
+
}
|
|
359
|
+
export interface BuiGradeSubmissionInput {
|
|
360
|
+
score: number;
|
|
361
|
+
passed?: boolean;
|
|
362
|
+
feedback?: string;
|
|
363
|
+
}
|
|
364
|
+
export interface BuiIssueCertificateInput {
|
|
365
|
+
courseId: string;
|
|
366
|
+
learnerId: string;
|
|
367
|
+
enrollmentId?: string;
|
|
368
|
+
serial: string;
|
|
369
|
+
finalScore?: number;
|
|
370
|
+
expiresAt?: string;
|
|
371
|
+
fileId?: string;
|
|
372
|
+
}
|
|
373
|
+
export declare const COURSE_LEVELS: BuiCourseLevel[];
|
|
374
|
+
export declare const COURSE_STATUSES: BuiCourseStatus[];
|
|
375
|
+
export declare const LESSON_TYPES: BuiLessonType[];
|
|
376
|
+
export declare const ASSESSMENT_TYPES: BuiAssessmentType[];
|
|
377
|
+
export declare const QUESTION_TYPES: BuiQuestionType[];
|
|
378
|
+
export declare const SKILL_CATEGORIES: BuiSkillCategory[];
|
|
379
|
+
export declare const ENROLLMENT_STATUSES: BuiEnrollmentStatus[];
|
|
380
|
+
export declare const COHORT_STATUSES: BuiCohortStatus[];
|
|
381
|
+
export declare const SUBMISSION_STATUSES: BuiSubmissionStatus[];
|
|
382
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/buildmyiq/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cn.d.ts","sourceRoot":"","sources":["../../../src/buildmyiq/utils/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAQ,MAAM,MAAM,CAAC;AAG7C,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formatting utilities for the Buildmyiq microfrontend
|
|
3
|
+
* @module buildmyiq/utils/formatters
|
|
4
|
+
*/
|
|
5
|
+
/** Format a date string or Date into a human-readable date. */
|
|
6
|
+
export declare function formatDate(date: string | Date | null | undefined, options?: Partial<Intl.DateTimeFormatOptions>): string;
|
|
7
|
+
/** Format a date-time into a date + time string. */
|
|
8
|
+
export declare function formatDateTime(date: string | Date | null | undefined, options?: Partial<Intl.DateTimeFormatOptions>): string;
|
|
9
|
+
/** Format a date into a relative time string (e.g. "2 hours ago", "in 3 days"). */
|
|
10
|
+
export declare function formatRelativeTime(date: string | Date | null | undefined): string;
|
|
11
|
+
/** Format a number with locale grouping. */
|
|
12
|
+
export declare function formatNumber(value: number | null | undefined, options?: Partial<Intl.NumberFormatOptions>): string;
|
|
13
|
+
/** Format a quantity with an optional unit suffix (e.g. "1,200 XP"). */
|
|
14
|
+
export declare function formatQuantity(value: number | null | undefined, unit?: string | null): string;
|
|
15
|
+
/** Format a percentage (0–100) into a rounded "%" string. */
|
|
16
|
+
export declare function formatPercent(value: number | null | undefined, fractionDigits?: number): string;
|
|
17
|
+
/**
|
|
18
|
+
* Format a duration in minutes into a compact "1h 30m" / "45m" / "2h" string —
|
|
19
|
+
* used for lesson duration and course estimated hours (× 60).
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatDuration(minutes: number | null | undefined): string;
|
|
22
|
+
/** Format a number of hours into a "12 hrs" / "1 hr" label. */
|
|
23
|
+
export declare function formatHours(hours: number | null | undefined): string;
|
|
24
|
+
/** Turn an ENUM_LIKE_TOKEN into a human "Enum Like Token" label. */
|
|
25
|
+
export declare function formatEnumLabel(value: string | null | undefined): string;
|
|
26
|
+
/** A short display name for a person from a partial identity object. */
|
|
27
|
+
export declare function formatPersonName(person: {
|
|
28
|
+
firstName?: string | null;
|
|
29
|
+
lastName?: string | null;
|
|
30
|
+
name?: string | null;
|
|
31
|
+
email?: string | null;
|
|
32
|
+
} | null | undefined): string;
|
|
33
|
+
//# sourceMappingURL=formatters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../../src/buildmyiq/utils/formatters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+DAA+D;AAC/D,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,EACtC,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAC5C,MAAM,CAUR;AAED,oDAAoD;AACpD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,EACtC,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAC5C,MAAM,CAYR;AAED,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CA4BjF;AAED,4CAA4C;AAC5C,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAC1C,MAAM,CAGR;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAI7F;AAED,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,cAAc,SAAI,GAAG,MAAM,CAG1F;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAOzE;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGpE;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAMxE;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAC9B,MAAM,EACF;IACE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,GACD,IAAI,GACJ,SAAS,GACZ,MAAM,CAIR"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { I18nContextValue } from '../../../../../fe-libs/src/shared/providers/shell/I18nProvider';
|
|
2
|
+
|
|
3
|
+
type TranslationParams = Record<string, string | number>;
|
|
4
|
+
export declare function tWithFallback(t: I18nContextValue['t'], key: string, fallback: string, params?: TranslationParams): string;
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../../src/buildmyiq/utils/i18n.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wDAAwD,CAAC;AAE/F,KAAK,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAazD,wBAAgB,aAAa,CAC3B,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,EACxB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,iBAAiB,GACzB,MAAM,CAOR"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utils index
|
|
3
|
+
* @module buildmyiq/utils
|
|
4
|
+
*/
|
|
5
|
+
export { cn } from './cn';
|
|
6
|
+
export { joinPath } from './navigation';
|
|
7
|
+
export { tWithFallback } from './i18n';
|
|
8
|
+
export { formatDate, formatDateTime, formatRelativeTime, formatNumber, formatQuantity, formatPercent, formatDuration, formatHours, formatEnumLabel, formatPersonName, } from './formatters';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/buildmyiq/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EACL,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,aAAa,EACb,cAAc,EACd,WAAW,EACX,eAAe,EACf,gBAAgB,GACjB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation utilities for the Buildmyiq microfrontend
|
|
3
|
+
* @module buildmyiq/utils
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Join basePath with a relative path, correctly handling slashes.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* joinPath('/buildmyiq', 'sites') // => '/buildmyiq/sites'
|
|
10
|
+
* joinPath('/buildmyiq/', 'sites') // => '/buildmyiq/sites'
|
|
11
|
+
* joinPath('/buildmyiq', '') // => '/buildmyiq'
|
|
12
|
+
*/
|
|
13
|
+
export declare function joinPath(basePath: string, relativePath: string): string;
|
|
14
|
+
//# sourceMappingURL=navigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../src/buildmyiq/utils/navigation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAOvE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/dev/main.tsx"],"names":[],"mappings":"AAIA,OAAO,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-operations.d.ts","sourceRoot":"","sources":["../../src/generated/global-operations.ts"],"names":[],"mappings":""}
|