@burdenoff/microfe-buildmyiq 2026.730.2 → 2026.731.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/buildmyiq/BuildmyiqRoot.d.ts.map +1 -1
  2. package/dist/buildmyiq/BuildmyiqRoot.js +68 -52
  3. package/dist/buildmyiq/BuildmyiqRoot.js.map +1 -1
  4. package/dist/buildmyiq/BuildmyiqRoutes.d.ts.map +1 -1
  5. package/dist/buildmyiq/BuildmyiqRoutes.js +36 -24
  6. package/dist/buildmyiq/BuildmyiqRoutes.js.map +1 -1
  7. package/dist/buildmyiq/hooks/useBuiPermissions.d.ts +1 -1
  8. package/dist/buildmyiq/hooks/useBuiPermissions.d.ts.map +1 -1
  9. package/dist/buildmyiq/hooks/useBuildmyiqApi.d.ts +38 -1
  10. package/dist/buildmyiq/hooks/useBuildmyiqApi.d.ts.map +1 -1
  11. package/dist/buildmyiq/hooks/useBuildmyiqApi.js +131 -86
  12. package/dist/buildmyiq/hooks/useBuildmyiqApi.js.map +1 -1
  13. package/dist/buildmyiq/pages/authoring/AuthoringPage.d.ts.map +1 -1
  14. package/dist/buildmyiq/pages/authoring/AuthoringPage.js +351 -124
  15. package/dist/buildmyiq/pages/authoring/AuthoringPage.js.map +1 -1
  16. package/dist/buildmyiq/pages/copilot/AdminCopilotPage.d.ts +4 -0
  17. package/dist/buildmyiq/pages/copilot/AdminCopilotPage.d.ts.map +1 -0
  18. package/dist/buildmyiq/pages/copilot/AdminCopilotPage.js +164 -0
  19. package/dist/buildmyiq/pages/copilot/AdminCopilotPage.js.map +1 -0
  20. package/dist/buildmyiq/pages/integrations/LtiPlatformsPage.d.ts +4 -0
  21. package/dist/buildmyiq/pages/integrations/LtiPlatformsPage.d.ts.map +1 -0
  22. package/dist/buildmyiq/pages/integrations/LtiPlatformsPage.js +269 -0
  23. package/dist/buildmyiq/pages/integrations/LtiPlatformsPage.js.map +1 -0
  24. package/dist/buildmyiq/pages/submissions/BulkGradingPage.d.ts +4 -0
  25. package/dist/buildmyiq/pages/submissions/BulkGradingPage.d.ts.map +1 -0
  26. package/dist/buildmyiq/pages/submissions/BulkGradingPage.js +229 -0
  27. package/dist/buildmyiq/pages/submissions/BulkGradingPage.js.map +1 -0
  28. package/dist/buildmyiq/pages/submissions/SubmissionsPage.d.ts.map +1 -1
  29. package/dist/buildmyiq/pages/submissions/SubmissionsPage.js +294 -177
  30. package/dist/buildmyiq/pages/submissions/SubmissionsPage.js.map +1 -1
  31. package/dist/buildmyiq/types/index.d.ts +95 -0
  32. package/dist/buildmyiq/types/index.d.ts.map +1 -1
  33. package/dist/buildmyiq/types/index.js.map +1 -1
  34. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"SubmissionsPage.js","names":[],"sources":["../../../../src/buildmyiq/pages/submissions/SubmissionsPage.tsx"],"sourcesContent":["/**\n * SubmissionsPage — the workspace-wide grading queue.\n * @module buildmyiq/pages/submissions\n *\n * The educator surface for assessment submissions. Reads every submission in the\n * workspace via `useBuiSubmissions` (no `assessmentId` → all assessments),\n * filterable by status, and paginated by cursor. Clicking a row opens a grading\n * slide-over — a right-hand panel on desktop, a bottom-sheet on mobile — that\n * shows the learner's answers read-only (rendered safely from the `answers` JSON\n * blob) under a Submission / Details tab pair, plus a grading form\n * (`useBuiGradeSubmission`: score, passed, feedback). Already-graded rows show\n * their result read-only with a \"Re-grade\" affordance.\n *\n * Every number is derived from live `bui*` data; the KPI row is explicitly scoped\n * to the current page (\"this page\") so it never overstates workspace totals.\n * Learner identity is shown honestly: the signed-in educator's own attempts get\n * their real name + \"You\"; everyone else is a deterministic initials avatar keyed\n * off the opaque learner id — never a fabricated name or stock photo.\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport type { FC, ReactNode } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ClipboardList, Clock, CheckCircle2, Undo2, GraduationCap, BookOpen } from 'lucide-react';\nimport {\n Button,\n Input,\n Label,\n Textarea,\n Switch,\n Sheet,\n SheetContent,\n SheetHeader,\n SheetTitle,\n SheetDescription,\n SheetFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { useMediaQuery } from '@burdenoff/fe-libs/shared/hooks';\nimport {\n PageLayout,\n MetricsCard,\n StatusBadge,\n DataTable,\n Tabs,\n Pagination,\n EmptyState,\n LoadingView,\n ErrorView,\n Avatar,\n type Column,\n type TabItem,\n} from '../../components';\nimport { useBuildmyiq } from '../../context';\nimport {\n useBuiSubmissions,\n useBuiSubmission,\n useBuiGradeSubmission,\n useCursorPager,\n} from '../../hooks';\nimport { formatDate, formatDateTime } from '../../utils/formatters';\nimport type { BuiSubmission, BuiSubmissionStatus } from '../../types';\nimport { BuiPermissionButton } from '../../components/BuiPermissionButton';\n\nconst PAGE_SIZE = 24;\n\ntype StatusFilter = BuiSubmissionStatus | 'ALL';\ntype PanelTab = 'submission' | 'details';\n\nconst STATUS_TABS: TabItem<StatusFilter>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'SUBMITTED', label: 'Submitted' },\n { value: 'GRADING', label: 'Grading' },\n { value: 'GRADED', label: 'Graded' },\n { value: 'RETURNED', label: 'Returned' },\n];\n\nconst PANEL_TABS: TabItem<PanelTab>[] = [\n { value: 'submission', label: 'Submission' },\n { value: 'details', label: 'Details' },\n];\n\n/** Truncate an opaque id for compact display, keeping the full value in `title`. */\nconst shortId = (id: string): string => (id.length > 10 ? `${id.slice(0, 8)}…` : id);\n\n/** Time-only rendering (e.g. \"10:24 AM\") reusing the locale-aware date formatter. */\nconst formatClock = (date: string | null | undefined): string =>\n formatDate(date, {\n day: undefined,\n month: undefined,\n year: undefined,\n hour: 'numeric',\n minute: '2-digit',\n });\n\nconst isPlainRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v);\n\n/** Render a single answer value safely, whatever its JSON shape. */\nconst formatAnswerValue = (v: unknown): string => {\n if (v == null) return '—';\n if (typeof v === 'string') return v;\n if (typeof v === 'number' || typeof v === 'boolean') return String(v);\n return JSON.stringify(v, null, 2);\n};\n\n/** Read-only rendering of a submission's `answers` JSON blob. */\nconst AnswersView: FC<{ answers: unknown }> = ({ answers }) => {\n if (answers == null) {\n return <p className=\"text-sm text-text-secondary\">No answers were submitted.</p>;\n }\n if (isPlainRecord(answers)) {\n const entries = Object.entries(answers);\n if (entries.length === 0) {\n return <p className=\"text-sm text-text-secondary\">No answers were submitted.</p>;\n }\n return (\n <ol className=\"grid gap-2.5\">\n {entries.map(([key, value], i) => (\n <li\n key={key}\n className=\"grid gap-1 rounded-lg border border-border-seam/70 bg-bg-surface/60 p-3 sm:grid-cols-[minmax(0,7rem)_1fr] sm:gap-3\"\n >\n <div className=\"flex items-baseline gap-2 sm:col-span-1\">\n <span className=\"shrink-0 text-xs font-semibold text-[var(--color-accent-teal)] tabular-nums\">\n Q{i + 1}\n </span>\n <span className=\"break-words font-mono text-xs text-text-secondary\">{key}</span>\n </div>\n <span className=\"whitespace-pre-wrap break-words text-sm text-text-primary sm:col-span-1\">\n {formatAnswerValue(value)}\n </span>\n </li>\n ))}\n </ol>\n );\n }\n return (\n <pre className=\"overflow-x-auto whitespace-pre-wrap break-words rounded-lg border border-border-seam/70 bg-bg-surface/60 p-3 text-xs text-text-primary\">\n {JSON.stringify(answers, null, 2)}\n </pre>\n );\n};\n\n/** A labelled read-only field for the submission meta / graded-result panels. */\nconst MetaField: FC<{ label: string; children: ReactNode }> = ({ label, children }) => (\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">{label}</p>\n <div className=\"mt-0.5 text-sm text-text-primary\">{children}</div>\n </div>\n);\n\ninterface GradingPanelBodyProps {\n submission: BuiSubmission;\n currentUser: ReturnType<typeof useBuildmyiq>['currentUser'];\n meName: string | undefined;\n isMe: (learnerId: string) => boolean;\n learnerLabel: (learnerId: string) => string;\n gradeSubmission: ReturnType<typeof useBuiGradeSubmission>;\n onClose: () => void;\n}\n\n/**\n * The grading slide-over's content, for a single fixed `submission`. Rendered\n * with `key={submission.id}` by the parent so switching to a different\n * submission remounts this component — every local (editable) field below\n * initializes fresh from `submission` with no synchronizing effect needed.\n */\nconst GradingPanelBody: FC<GradingPanelBodyProps> = ({\n submission,\n currentUser,\n meName,\n isMe,\n learnerLabel,\n gradeSubmission,\n onClose,\n}) => {\n const [panelTab, setPanelTab] = useState<PanelTab>('submission');\n const [editMode, setEditMode] = useState(false);\n const [scoreInput, setScoreInput] = useState(\n submission.score != null ? String(submission.score) : ''\n );\n const [passed, setPassed] = useState(submission.passed ?? false);\n const [feedback, setFeedback] = useState(submission.feedback ?? '');\n const [formError, setFormError] = useState<string | null>(null);\n\n const gradingAllowed = submission.status === 'SUBMITTED' || submission.status === 'GRADING';\n const alreadyGraded = submission.status === 'GRADED' || submission.status === 'RETURNED';\n const notSubmitted = submission.status === 'IN_PROGRESS';\n const showGradeForm = gradingAllowed || editMode;\n\n const handleGrade = async () => {\n const trimmed = scoreInput.trim();\n const scoreNum = Number(trimmed);\n if (trimmed === '' || Number.isNaN(scoreNum)) {\n setFormError('Enter a numeric score.');\n return;\n }\n if (scoreNum < 0) {\n setFormError('Score cannot be negative.');\n return;\n }\n try {\n await gradeSubmission.mutateAsync({\n id: submission.id,\n input: { score: scoreNum, passed, feedback: feedback.trim() || undefined },\n });\n onClose();\n } catch (err) {\n setFormError(err instanceof Error ? err.message : 'Failed to save grade.');\n }\n };\n\n return (\n <>\n <SheetHeader className=\"border-b border-border-seam p-5 pr-12\">\n <div className=\"flex items-center gap-3\">\n <Avatar\n size=\"md\"\n name={isMe(submission.learnerId) ? meName : undefined}\n seed={submission.learnerId}\n src={isMe(submission.learnerId) ? currentUser?.avatar : undefined}\n />\n <div className=\"min-w-0\">\n <SheetTitle className=\"truncate text-lg\">\n {learnerLabel(submission.learnerId)}\n </SheetTitle>\n <SheetDescription\n className=\"truncate font-mono text-xs\"\n title={submission.assessmentId}\n >\n Assessment {shortId(submission.assessmentId)}\n </SheetDescription>\n </div>\n </div>\n <p className=\"text-xs text-text-secondary\">\n Attempt #{submission.attempt} · Submitted {formatDateTime(submission.submittedAt)}\n </p>\n <div className=\"pt-1\">\n <StatusBadge status={submission.status} />\n </div>\n </SheetHeader>\n\n <div className=\"flex-1 overflow-y-auto px-5 py-4\">\n <Tabs items={PANEL_TABS} value={panelTab} onChange={setPanelTab} className=\"mb-4\" />\n\n {panelTab === 'submission' ? (\n <div>\n <p className=\"mb-2 text-sm font-semibold text-text-primary\">\n Answers <span className=\"font-normal text-text-secondary\">(read-only)</span>\n </p>\n <AnswersView answers={submission.answers} />\n </div>\n ) : (\n <div className=\"grid grid-cols-2 gap-4 rounded-xl bg-bg-sunken/60 p-4\">\n <MetaField label=\"Status\">\n <StatusBadge status={submission.status} />\n </MetaField>\n <MetaField label=\"Attempt\">\n <span className=\"tabular-nums\">#{submission.attempt}</span>\n </MetaField>\n <MetaField label=\"Submitted\">{formatDateTime(submission.submittedAt)}</MetaField>\n <MetaField label=\"Assessment\">\n <span className=\"font-mono text-xs\" title={submission.assessmentId}>\n {shortId(submission.assessmentId)}\n </span>\n </MetaField>\n {submission.enrollmentId && (\n <MetaField label=\"Enrollment\">\n <span className=\"font-mono text-xs\" title={submission.enrollmentId}>\n {shortId(submission.enrollmentId)}\n </span>\n </MetaField>\n )}\n {submission.gradedAt && (\n <MetaField label=\"Graded\">{formatDateTime(submission.gradedAt)}</MetaField>\n )}\n </div>\n )}\n\n {/* Grade / result — persistent below the tab content. */}\n <div className=\"mt-6 border-t border-border-seam pt-5\">\n <p className=\"mb-3 text-sm font-semibold text-text-primary\">Grade</p>\n\n {notSubmitted && (\n <p className=\"rounded-lg bg-bg-sunken/60 px-4 py-3 text-sm text-text-secondary\">\n This attempt is still in progress — there is nothing to grade until the learner\n submits.\n </p>\n )}\n\n {alreadyGraded && !editMode && (\n <div className=\"rounded-xl border border-border-seam p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"grid grid-cols-2 gap-4\">\n <MetaField label=\"Score\">\n <span className=\"tabular-nums font-semibold\">{submission.score ?? '—'}</span>\n </MetaField>\n <MetaField label=\"Result\">\n {submission.passed == null ? (\n <span className=\"text-text-secondary\">—</span>\n ) : (\n <StatusBadge status={submission.passed ? 'GRADED' : 'RETURNED'} />\n )}\n </MetaField>\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setEditMode(true)}>\n Re-grade\n </Button>\n </div>\n <div className=\"mt-3\">\n <MetaField label=\"Feedback\">\n {submission.feedback ? (\n <span className=\"whitespace-pre-wrap\">{submission.feedback}</span>\n ) : (\n <span className=\"text-text-secondary\">No feedback provided.</span>\n )}\n </MetaField>\n </div>\n </div>\n )}\n\n {showGradeForm && (\n <div className=\"grid gap-4\">\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"grade-score\">Score</Label>\n <Input\n id=\"grade-score\"\n type=\"number\"\n min=\"0\"\n step=\"1\"\n value={scoreInput}\n onChange={(e) => setScoreInput(e.target.value)}\n placeholder=\"e.g. 85\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"grade-passed\">Result</Label>\n <div className=\"flex h-10 items-center gap-3\">\n <Switch id=\"grade-passed\" checked={passed} onCheckedChange={setPassed} />\n <span className=\"text-sm text-text-secondary\">\n {passed ? 'Passed' : 'Not passed'}\n </span>\n </div>\n </div>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"grade-feedback\">Feedback</Label>\n <Textarea\n id=\"grade-feedback\"\n value={feedback}\n onChange={(e) => setFeedback(e.target.value)}\n placeholder=\"Notes, corrections or encouragement for the learner (optional).\"\n rows={4}\n />\n </div>\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n )}\n </div>\n </div>\n\n <SheetFooter className=\"flex-row justify-end gap-3 border-t border-border-seam p-4\">\n <Button variant=\"outline\" onClick={onClose}>\n {showGradeForm ? 'Cancel' : 'Close'}\n </Button>\n {showGradeForm && (\n <BuiPermissionButton\n resource=\"buildmyiq-submission\"\n action=\"update\"\n deniedBehavior=\"hide\"\n >\n <Button onClick={handleGrade} disabled={gradeSubmission.isPending}>\n {gradeSubmission.isPending\n ? 'Saving…'\n : alreadyGraded\n ? 'Update grade'\n : 'Grade submission'}\n </Button>\n </BuiPermissionButton>\n )}\n </SheetFooter>\n </>\n );\n};\n\nexport const SubmissionsPage: FC = () => {\n const { currentUser, navigateTo } = useBuildmyiq();\n const { submissionId } = useParams<{ submissionId?: string }>();\n const isDesktop = useMediaQuery('(min-width: 768px)');\n const [statusFilter, setStatusFilter] = useState<StatusFilter>('ALL');\n const pager = useCursorPager();\n\n const { data, isLoading, isError, refetch } = useBuiSubmissions({\n status: statusFilter === 'ALL' ? undefined : statusFilter,\n cursor: pager.cursor,\n limit: PAGE_SIZE,\n });\n const gradeSubmission = useBuiGradeSubmission();\n\n // Deep-link support: /buildmyiq/submissions/:submissionId opens the grading\n // panel directly, independent of which page of the list is currently loaded.\n // The URL is the single source of truth for \"which submission is open\" —\n // there is no separate `selected` state to keep in sync with it.\n const deepLink = useBuiSubmission(submissionId);\n\n const rows = useMemo<BuiSubmission[]>(() => data?.items ?? [], [data]);\n\n const activeId = submissionId ?? null;\n const activeSubmission = useMemo<BuiSubmission | null>(() => {\n if (!activeId) return null;\n return (\n rows.find((r) => r.id === activeId) ?? (deepLink.data?.id === activeId ? deepLink.data : null)\n );\n }, [activeId, rows, deepLink.data]);\n\n // The signed-in educator's own display name (used only for their own rows).\n const meName = useMemo<string | undefined>(() => {\n if (!currentUser) return undefined;\n const full = [currentUser.firstName, currentUser.lastName].filter(Boolean).join(' ').trim();\n return currentUser.name?.trim() || full || currentUser.username || currentUser.email;\n }, [currentUser]);\n\n // Counts are scoped to the loaded page — labelled \"this page\" to stay honest.\n const counts = useMemo(() => {\n const acc = { total: rows.length, awaiting: 0, graded: 0, returned: 0 };\n for (const s of rows) {\n if (s.status === 'SUBMITTED' || s.status === 'GRADING') acc.awaiting += 1;\n else if (s.status === 'GRADED') acc.graded += 1;\n else if (s.status === 'RETURNED') acc.returned += 1;\n }\n return acc;\n }, [rows]);\n\n const isMe = (learnerId: string): boolean => learnerId === currentUser?.id;\n const learnerLabel = (learnerId: string): string =>\n isMe(learnerId) ? 'You' : `Learner ${shortId(learnerId)}`;\n\n /** Row click: push the deep-linkable URL; the panel opens from the route param. */\n const selectSubmission = (s: BuiSubmission) => navigateTo(`submissions/${s.id}`);\n const closePanel = () => navigateTo('submissions');\n\n // If the id in the URL doesn't resolve to a real submission in this\n // workspace (wrong tenant, typo, or one that was later deleted), fall back\n // to the plain list once the lookup has definitively failed. This effect\n // only notifies the router — it never sets this component's own state, so\n // it can't cascade into an extra render loop.\n useEffect(() => {\n if (!activeId || activeSubmission) return;\n if (!deepLink.isLoading && (deepLink.isError || deepLink.data === null)) {\n navigateTo('submissions');\n }\n }, [activeId, activeSubmission, deepLink.isLoading, deepLink.isError, deepLink.data, navigateTo]);\n\n const handleFilterChange = (value: StatusFilter) => {\n setStatusFilter(value);\n pager.reset();\n };\n\n const columns: Column<BuiSubmission>[] = [\n {\n key: 'learner',\n header: 'Learner',\n sortValue: (s) => (isMe(s.learnerId) ? '' : s.learnerId),\n render: (s) => (\n <div className=\"flex items-center gap-3\">\n <Avatar\n size=\"sm\"\n name={isMe(s.learnerId) ? meName : undefined}\n seed={s.learnerId}\n src={isMe(s.learnerId) ? currentUser?.avatar : undefined}\n />\n <div className=\"min-w-0\">\n <span className=\"block truncate font-medium text-text-primary\" title={s.learnerId}>\n {isMe(s.learnerId) ? 'You' : shortId(s.learnerId)}\n </span>\n {isMe(s.learnerId) && meName && (\n <span className=\"block truncate text-xs text-text-secondary\">{meName}</span>\n )}\n </div>\n </div>\n ),\n },\n {\n key: 'assessment',\n header: 'Assessment',\n hideOnMobile: true,\n render: (s) => (\n <span className=\"inline-flex items-center gap-2 text-text-secondary\">\n <BookOpen className=\"h-4 w-4 shrink-0 opacity-70\" />\n <span className=\"font-mono text-xs\" title={s.assessmentId}>\n {shortId(s.assessmentId)}\n </span>\n </span>\n ),\n },\n {\n key: 'attempt',\n header: 'Attempt',\n align: 'right',\n hideOnMobile: true,\n sortValue: (s) => s.attempt,\n render: (s) => <span className=\"tabular-nums text-text-secondary\">#{s.attempt}</span>,\n },\n {\n key: 'status',\n header: 'Status',\n sortValue: (s) => s.status,\n render: (s) => <StatusBadge status={s.status} />,\n },\n {\n key: 'score',\n header: 'Score',\n align: 'right',\n sortValue: (s) => s.score ?? -1,\n render: (s) =>\n s.score == null ? (\n <span className=\"text-text-secondary\">—</span>\n ) : (\n <span className=\"tabular-nums font-semibold text-text-primary\">{s.score}</span>\n ),\n },\n {\n key: 'submittedAt',\n header: 'Submitted',\n align: 'right',\n hideOnMobile: true,\n sortValue: (s) => s.submittedAt ?? s.createdAt,\n render: (s) => (\n <div className=\"whitespace-nowrap text-right\">\n <div className=\"text-text-primary\">{formatDate(s.submittedAt)}</div>\n {s.submittedAt && (\n <div className=\"text-xs text-text-secondary\">{formatClock(s.submittedAt)}</div>\n )}\n </div>\n ),\n },\n ];\n\n return (\n <PageLayout\n title=\"Grading\"\n description=\"Review and grade assessment submissions across every course in your workspace.\"\n titleGradient\n aurora\n >\n <div className=\"flex flex-col gap-6\">\n {/* KPI row — scoped to the current page. */}\n <div className=\"grid grid-cols-2 gap-4 xl:grid-cols-4\">\n <MetricsCard\n icon={<ClipboardList className=\"h-5 w-5\" />}\n value={counts.total}\n label=\"Submissions (this page)\"\n featured\n />\n <MetricsCard\n icon={<Clock className=\"h-5 w-5\" />}\n value={counts.awaiting}\n label=\"Awaiting grade (this page)\"\n accent=\"warning\"\n />\n <MetricsCard\n icon={<CheckCircle2 className=\"h-5 w-5\" />}\n value={counts.graded}\n label=\"Graded (this page)\"\n accent=\"success\"\n />\n <MetricsCard\n icon={<Undo2 className=\"h-5 w-5\" />}\n value={counts.returned}\n label=\"Returned (this page)\"\n />\n </div>\n\n <Tabs items={STATUS_TABS} value={statusFilter} onChange={handleFilterChange} />\n\n {isLoading ? (\n <LoadingView label=\"Loading submissions…\" />\n ) : isError ? (\n <ErrorView\n title=\"Couldn't load submissions\"\n message=\"The grading queue failed to load.\"\n onRetry={() => refetch()}\n />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<GraduationCap className=\"h-10 w-10\" />}\n title={statusFilter === 'ALL' ? 'No submissions yet' : 'Nothing in this status'}\n description={\n statusFilter === 'ALL'\n ? 'When learners submit assessments, their attempts will appear here for grading.'\n : 'No submissions currently match this status filter.'\n }\n />\n ) : (\n <div className=\"flex flex-col gap-4\">\n <DataTable\n columns={columns}\n rows={rows}\n rowKey={(s) => s.id}\n onRowClick={selectSubmission}\n defaultSort={{ key: 'submittedAt', dir: 'desc' }}\n />\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={rows.length}\n hasMore={data?.pageInfo?.hasMore ?? false}\n onPageChange={(target) => pager.onPageChange(target, data?.pageInfo?.cursor)}\n />\n </div>\n )}\n </div>\n\n {/* Grading slide-over — right panel on desktop, bottom-sheet on mobile. */}\n <Sheet\n open={activeId != null}\n onOpenChange={(open) => {\n if (!open) closePanel();\n }}\n >\n <SheetContent\n side={isDesktop ? 'right' : 'bottom'}\n className={\n isDesktop\n ? 'flex w-full max-w-none flex-col gap-0 p-0 sm:max-w-xl'\n : 'flex max-h-[92vh] w-full flex-col gap-0 rounded-t-2xl p-0'\n }\n >\n {activeSubmission ? (\n // Keyed by submission id: remounting on id change gives the panel\n // fresh local (editable) state for free, with no synchronizing effect.\n <GradingPanelBody\n key={activeSubmission.id}\n submission={activeSubmission}\n currentUser={currentUser}\n meName={meName}\n isMe={isMe}\n learnerLabel={learnerLabel}\n gradeSubmission={gradeSubmission}\n onClose={closePanel}\n />\n ) : activeId ? (\n <div className=\"flex min-h-[300px] items-center justify-center p-5\">\n <LoadingView label=\"Loading submission…\" />\n </div>\n ) : null}\n </SheetContent>\n </Sheet>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"SubmissionsPage.js","names":[],"sources":["../../../../src/buildmyiq/pages/submissions/SubmissionsPage.tsx"],"sourcesContent":["/**\n * SubmissionsPage — the workspace-wide grading queue.\n * @module buildmyiq/pages/submissions\n *\n * The educator surface for assessment submissions. Reads every submission in the\n * workspace via `useBuiSubmissions` (no `assessmentId` → all assessments),\n * filterable by status, and paginated by cursor. Clicking a row opens a grading\n * slide-over — a right-hand panel on desktop, a bottom-sheet on mobile — that\n * shows the learner's answers read-only (rendered safely from the `answers` JSON\n * blob) under a Submission / Details tab pair, plus a grading form\n * (`useBuiGradeSubmission`: score, passed, feedback). Already-graded rows show\n * their result read-only with a \"Re-grade\" affordance.\n *\n * Every number is derived from live `bui*` data; the KPI row is explicitly scoped\n * to the current page (\"this page\") so it never overstates workspace totals.\n * Learner identity is shown honestly: the signed-in educator's own attempts get\n * their real name + \"You\"; everyone else is a deterministic initials avatar keyed\n * off the opaque learner id — never a fabricated name or stock photo.\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport type { FC, ReactNode } from 'react';\nimport { useParams } from 'react-router-dom';\nimport {\n ClipboardList,\n Clock,\n CheckCircle2,\n Undo2,\n GraduationCap,\n BookOpen,\n Sparkles,\n Layers,\n} from 'lucide-react';\nimport {\n Button,\n Input,\n Label,\n Textarea,\n Switch,\n Sheet,\n SheetContent,\n SheetHeader,\n SheetTitle,\n SheetDescription,\n SheetFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { useMediaQuery } from '@burdenoff/fe-libs/shared/hooks';\nimport {\n PageLayout,\n MetricsCard,\n StatusBadge,\n DataTable,\n Tabs,\n Pagination,\n EmptyState,\n LoadingView,\n ErrorView,\n Avatar,\n type Column,\n type TabItem,\n} from '../../components';\nimport { useBuildmyiq } from '../../context';\nimport {\n useBuiSubmissions,\n useBuiSubmission,\n useBuiGradeSubmission,\n useBuiSuggestGrade,\n useBuiReviewGradeSuggestion,\n useCursorPager,\n} from '../../hooks';\nimport { formatDate, formatDateTime } from '../../utils/formatters';\nimport type { BuiSubmission, BuiSubmissionStatus, BuiGradeSuggestion } from '../../types';\nimport { BuiPermissionButton } from '../../components/BuiPermissionButton';\n\nconst PAGE_SIZE = 24;\n\ntype StatusFilter = BuiSubmissionStatus | 'ALL';\ntype PanelTab = 'submission' | 'details';\n\nconst STATUS_TABS: TabItem<StatusFilter>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'SUBMITTED', label: 'Submitted' },\n { value: 'GRADING', label: 'Grading' },\n { value: 'GRADED', label: 'Graded' },\n { value: 'RETURNED', label: 'Returned' },\n];\n\nconst PANEL_TABS: TabItem<PanelTab>[] = [\n { value: 'submission', label: 'Submission' },\n { value: 'details', label: 'Details' },\n];\n\n/** Truncate an opaque id for compact display, keeping the full value in `title`. */\nconst shortId = (id: string): string => (id.length > 10 ? `${id.slice(0, 8)}…` : id);\n\n/** Time-only rendering (e.g. \"10:24 AM\") reusing the locale-aware date formatter. */\nconst formatClock = (date: string | null | undefined): string =>\n formatDate(date, {\n day: undefined,\n month: undefined,\n year: undefined,\n hour: 'numeric',\n minute: '2-digit',\n });\n\nconst isPlainRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v);\n\n/** Render a single answer value safely, whatever its JSON shape. */\nconst formatAnswerValue = (v: unknown): string => {\n if (v == null) return '—';\n if (typeof v === 'string') return v;\n if (typeof v === 'number' || typeof v === 'boolean') return String(v);\n return JSON.stringify(v, null, 2);\n};\n\n/** Read-only rendering of a submission's `answers` JSON blob. */\nconst AnswersView: FC<{ answers: unknown }> = ({ answers }) => {\n if (answers == null) {\n return <p className=\"text-sm text-text-secondary\">No answers were submitted.</p>;\n }\n if (isPlainRecord(answers)) {\n const entries = Object.entries(answers);\n if (entries.length === 0) {\n return <p className=\"text-sm text-text-secondary\">No answers were submitted.</p>;\n }\n return (\n <ol className=\"grid gap-2.5\">\n {entries.map(([key, value], i) => (\n <li\n key={key}\n className=\"grid gap-1 rounded-lg border border-border-seam/70 bg-bg-surface/60 p-3 sm:grid-cols-[minmax(0,7rem)_1fr] sm:gap-3\"\n >\n <div className=\"flex items-baseline gap-2 sm:col-span-1\">\n <span className=\"shrink-0 text-xs font-semibold text-[var(--color-accent-teal)] tabular-nums\">\n Q{i + 1}\n </span>\n <span className=\"break-words font-mono text-xs text-text-secondary\">{key}</span>\n </div>\n <span className=\"whitespace-pre-wrap break-words text-sm text-text-primary sm:col-span-1\">\n {formatAnswerValue(value)}\n </span>\n </li>\n ))}\n </ol>\n );\n }\n return (\n <pre className=\"overflow-x-auto whitespace-pre-wrap break-words rounded-lg border border-border-seam/70 bg-bg-surface/60 p-3 text-xs text-text-primary\">\n {JSON.stringify(answers, null, 2)}\n </pre>\n );\n};\n\n/** A labelled read-only field for the submission meta / graded-result panels. */\nconst MetaField: FC<{ label: string; children: ReactNode }> = ({ label, children }) => (\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">{label}</p>\n <div className=\"mt-0.5 text-sm text-text-primary\">{children}</div>\n </div>\n);\n\n/**\n * AI-assisted grading (BOFF-4429). Calls `buiSuggestGrade`, which proposes a\n * score + per-question feedback for the submission's open-ended questions\n * (deterministic scoring for objective ones folded in) but NEVER writes the\n * submission — this panel only offers to PREFILL the grade form below with\n * the suggestion; the instructor still reviews and hits \"Grade submission\"\n * to commit it. Fails honestly (visible error, no silent fallback) when the\n * backend has no LLM provider configured or the assessment has no\n * open-ended questions to assist with.\n */\nconst AiGradeSuggestionPanel: FC<{\n submissionId: string;\n onUseSuggestion: (proposedScore: number, feedback: string) => void;\n}> = ({ submissionId, onUseSuggestion }) => {\n const suggestGrade = useBuiSuggestGrade();\n const reviewSuggestion = useBuiReviewGradeSuggestion();\n const [suggestion, setSuggestion] = useState<BuiGradeSuggestion | null>(null);\n const [dismissed, setDismissed] = useState(false);\n\n const handleSuggest = async () => {\n setDismissed(false);\n try {\n const result = await suggestGrade.mutateAsync(submissionId);\n setSuggestion(result);\n } catch {\n // error surfaced below via suggestGrade.isError / suggestGrade.error\n }\n };\n\n const handleUse = () => {\n if (!suggestion) return;\n const feedback = suggestion.perQuestionFeedback\n .map((f, i) => `Q${i + 1}: ${f.feedback}`)\n .join('\\n');\n onUseSuggestion(Math.round(suggestion.proposedScore), feedback);\n reviewSuggestion.mutate({ id: suggestion.id, outcome: 'ACCEPTED' });\n setDismissed(true);\n };\n\n const handleDismiss = () => {\n if (suggestion) reviewSuggestion.mutate({ id: suggestion.id, outcome: 'REJECTED' });\n setSuggestion(null);\n setDismissed(true);\n };\n\n if (dismissed && !suggestion) {\n return null;\n }\n\n if (!suggestion) {\n return (\n <div className=\"mb-4 rounded-xl border border-dashed border-border-seam bg-bg-sunken/40 p-3\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={handleSuggest}\n disabled={suggestGrade.isPending}\n >\n <Sparkles className=\"mr-1.5 h-4 w-4\" />\n {suggestGrade.isPending ? 'Asking the AI grader…' : 'Suggest with AI'}\n </Button>\n {suggestGrade.isError && (\n <p className=\"mt-2 text-xs text-status-error-text\">\n {suggestGrade.error instanceof Error\n ? suggestGrade.error.message\n : 'The AI grading assistant is unavailable right now.'}\n </p>\n )}\n <p className=\"mt-1.5 text-xs text-text-tertiary\">\n Proposes a score + feedback for open-ended answers. You always review before it counts.\n </p>\n </div>\n );\n }\n\n return (\n <div className=\"mb-4 rounded-xl border border-[var(--color-accent-teal)]/30 bg-[color-mix(in_srgb,var(--color-accent-teal)_8%,transparent)] p-3.5\">\n <div className=\"mb-2 flex items-center gap-2\">\n <Sparkles className=\"h-4 w-4 shrink-0 text-[var(--color-accent-teal)]\" />\n <p className=\"text-sm font-semibold text-text-primary\">\n AI-suggested score:{' '}\n <span className=\"tabular-nums\">{suggestion.proposedScore.toFixed(1)}</span>\n </p>\n <span className=\"ml-auto text-xs text-text-tertiary\">\n {Math.round(suggestion.confidence * 100)}% confidence\n </span>\n </div>\n {suggestion.perQuestionFeedback.length > 0 && (\n <ul className=\"mb-3 flex flex-col gap-1.5\">\n {suggestion.perQuestionFeedback.map((f, i) => (\n <li key={f.questionId} className=\"text-xs text-text-secondary\">\n <span className=\"font-medium text-text-primary\">Q{i + 1}</span>\n {f.suggestedPoints != null && (\n <span className=\"tabular-nums\"> ({f.suggestedPoints} pts)</span>\n )}\n : {f.feedback}\n </li>\n ))}\n </ul>\n )}\n <p className=\"mb-3 text-xs text-text-tertiary\">\n This is a suggestion, not a grade — nothing is saved until you review it and click\n &ldquo;Grade submission&rdquo; below.\n </p>\n <div className=\"flex gap-2\">\n <Button type=\"button\" size=\"sm\" onClick={handleUse}>\n Use this suggestion\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={handleDismiss}>\n Dismiss\n </Button>\n </div>\n </div>\n );\n};\n\ninterface GradingPanelBodyProps {\n submission: BuiSubmission;\n currentUser: ReturnType<typeof useBuildmyiq>['currentUser'];\n meName: string | undefined;\n isMe: (learnerId: string) => boolean;\n learnerLabel: (learnerId: string) => string;\n gradeSubmission: ReturnType<typeof useBuiGradeSubmission>;\n onClose: () => void;\n}\n\n/**\n * The grading slide-over's content, for a single fixed `submission`. Rendered\n * with `key={submission.id}` by the parent so switching to a different\n * submission remounts this component — every local (editable) field below\n * initializes fresh from `submission` with no synchronizing effect needed.\n */\nconst GradingPanelBody: FC<GradingPanelBodyProps> = ({\n submission,\n currentUser,\n meName,\n isMe,\n learnerLabel,\n gradeSubmission,\n onClose,\n}) => {\n const [panelTab, setPanelTab] = useState<PanelTab>('submission');\n const [editMode, setEditMode] = useState(false);\n const [scoreInput, setScoreInput] = useState(\n submission.score != null ? String(submission.score) : ''\n );\n const [passed, setPassed] = useState(submission.passed ?? false);\n const [feedback, setFeedback] = useState(submission.feedback ?? '');\n const [formError, setFormError] = useState<string | null>(null);\n\n const gradingAllowed = submission.status === 'SUBMITTED' || submission.status === 'GRADING';\n const alreadyGraded = submission.status === 'GRADED' || submission.status === 'RETURNED';\n const notSubmitted = submission.status === 'IN_PROGRESS';\n const showGradeForm = gradingAllowed || editMode;\n\n const handleGrade = async () => {\n const trimmed = scoreInput.trim();\n const scoreNum = Number(trimmed);\n if (trimmed === '' || Number.isNaN(scoreNum)) {\n setFormError('Enter a numeric score.');\n return;\n }\n if (scoreNum < 0) {\n setFormError('Score cannot be negative.');\n return;\n }\n try {\n await gradeSubmission.mutateAsync({\n id: submission.id,\n input: { score: scoreNum, passed, feedback: feedback.trim() || undefined },\n });\n onClose();\n } catch (err) {\n setFormError(err instanceof Error ? err.message : 'Failed to save grade.');\n }\n };\n\n return (\n <>\n <SheetHeader className=\"border-b border-border-seam p-5 pr-12\">\n <div className=\"flex items-center gap-3\">\n <Avatar\n size=\"md\"\n name={isMe(submission.learnerId) ? meName : undefined}\n seed={submission.learnerId}\n src={isMe(submission.learnerId) ? currentUser?.avatar : undefined}\n />\n <div className=\"min-w-0\">\n <SheetTitle className=\"truncate text-lg\">\n {learnerLabel(submission.learnerId)}\n </SheetTitle>\n <SheetDescription\n className=\"truncate font-mono text-xs\"\n title={submission.assessmentId}\n >\n Assessment {shortId(submission.assessmentId)}\n </SheetDescription>\n </div>\n </div>\n <p className=\"text-xs text-text-secondary\">\n Attempt #{submission.attempt} · Submitted {formatDateTime(submission.submittedAt)}\n </p>\n <div className=\"pt-1\">\n <StatusBadge status={submission.status} />\n </div>\n </SheetHeader>\n\n <div className=\"flex-1 overflow-y-auto px-5 py-4\">\n <Tabs items={PANEL_TABS} value={panelTab} onChange={setPanelTab} className=\"mb-4\" />\n\n {panelTab === 'submission' ? (\n <div>\n <p className=\"mb-2 text-sm font-semibold text-text-primary\">\n Answers <span className=\"font-normal text-text-secondary\">(read-only)</span>\n </p>\n <AnswersView answers={submission.answers} />\n </div>\n ) : (\n <div className=\"grid grid-cols-2 gap-4 rounded-xl bg-bg-sunken/60 p-4\">\n <MetaField label=\"Status\">\n <StatusBadge status={submission.status} />\n </MetaField>\n <MetaField label=\"Attempt\">\n <span className=\"tabular-nums\">#{submission.attempt}</span>\n </MetaField>\n <MetaField label=\"Submitted\">{formatDateTime(submission.submittedAt)}</MetaField>\n <MetaField label=\"Assessment\">\n <span className=\"font-mono text-xs\" title={submission.assessmentId}>\n {shortId(submission.assessmentId)}\n </span>\n </MetaField>\n {submission.enrollmentId && (\n <MetaField label=\"Enrollment\">\n <span className=\"font-mono text-xs\" title={submission.enrollmentId}>\n {shortId(submission.enrollmentId)}\n </span>\n </MetaField>\n )}\n {submission.gradedAt && (\n <MetaField label=\"Graded\">{formatDateTime(submission.gradedAt)}</MetaField>\n )}\n </div>\n )}\n\n {/* Grade / result — persistent below the tab content. */}\n <div className=\"mt-6 border-t border-border-seam pt-5\">\n <p className=\"mb-3 text-sm font-semibold text-text-primary\">Grade</p>\n\n {notSubmitted && (\n <p className=\"rounded-lg bg-bg-sunken/60 px-4 py-3 text-sm text-text-secondary\">\n This attempt is still in progress — there is nothing to grade until the learner\n submits.\n </p>\n )}\n\n {alreadyGraded && !editMode && (\n <div className=\"rounded-xl border border-border-seam p-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"grid grid-cols-2 gap-4\">\n <MetaField label=\"Score\">\n <span className=\"tabular-nums font-semibold\">{submission.score ?? '—'}</span>\n </MetaField>\n <MetaField label=\"Result\">\n {submission.passed == null ? (\n <span className=\"text-text-secondary\">—</span>\n ) : (\n <StatusBadge status={submission.passed ? 'GRADED' : 'RETURNED'} />\n )}\n </MetaField>\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setEditMode(true)}>\n Re-grade\n </Button>\n </div>\n <div className=\"mt-3\">\n <MetaField label=\"Feedback\">\n {submission.feedback ? (\n <span className=\"whitespace-pre-wrap\">{submission.feedback}</span>\n ) : (\n <span className=\"text-text-secondary\">No feedback provided.</span>\n )}\n </MetaField>\n </div>\n </div>\n )}\n\n {showGradeForm && (\n <div className=\"grid gap-4\">\n <AiGradeSuggestionPanel\n submissionId={submission.id}\n onUseSuggestion={(proposedScore, aiFeedback) => {\n setScoreInput(String(proposedScore));\n setFeedback(aiFeedback);\n }}\n />\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"grade-score\">Score</Label>\n <Input\n id=\"grade-score\"\n type=\"number\"\n min=\"0\"\n step=\"1\"\n value={scoreInput}\n onChange={(e) => setScoreInput(e.target.value)}\n placeholder=\"e.g. 85\"\n />\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"grade-passed\">Result</Label>\n <div className=\"flex h-10 items-center gap-3\">\n <Switch id=\"grade-passed\" checked={passed} onCheckedChange={setPassed} />\n <span className=\"text-sm text-text-secondary\">\n {passed ? 'Passed' : 'Not passed'}\n </span>\n </div>\n </div>\n </div>\n <div className=\"grid gap-1.5\">\n <Label htmlFor=\"grade-feedback\">Feedback</Label>\n <Textarea\n id=\"grade-feedback\"\n value={feedback}\n onChange={(e) => setFeedback(e.target.value)}\n placeholder=\"Notes, corrections or encouragement for the learner (optional).\"\n rows={4}\n />\n </div>\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n )}\n </div>\n </div>\n\n <SheetFooter className=\"flex-row justify-end gap-3 border-t border-border-seam p-4\">\n <Button variant=\"outline\" onClick={onClose}>\n {showGradeForm ? 'Cancel' : 'Close'}\n </Button>\n {showGradeForm && (\n <BuiPermissionButton\n resource=\"buildmyiq-submission\"\n action=\"update\"\n deniedBehavior=\"hide\"\n >\n <Button onClick={handleGrade} disabled={gradeSubmission.isPending}>\n {gradeSubmission.isPending\n ? 'Saving…'\n : alreadyGraded\n ? 'Update grade'\n : 'Grade submission'}\n </Button>\n </BuiPermissionButton>\n )}\n </SheetFooter>\n </>\n );\n};\n\nexport const SubmissionsPage: FC = () => {\n const { currentUser, navigateTo } = useBuildmyiq();\n const { submissionId } = useParams<{ submissionId?: string }>();\n const isDesktop = useMediaQuery('(min-width: 768px)');\n const [statusFilter, setStatusFilter] = useState<StatusFilter>('ALL');\n const pager = useCursorPager();\n\n const { data, isLoading, isError, refetch } = useBuiSubmissions({\n status: statusFilter === 'ALL' ? undefined : statusFilter,\n cursor: pager.cursor,\n limit: PAGE_SIZE,\n });\n const gradeSubmission = useBuiGradeSubmission();\n\n // Deep-link support: /buildmyiq/submissions/:submissionId opens the grading\n // panel directly, independent of which page of the list is currently loaded.\n // The URL is the single source of truth for \"which submission is open\" —\n // there is no separate `selected` state to keep in sync with it.\n const deepLink = useBuiSubmission(submissionId);\n\n const rows = useMemo<BuiSubmission[]>(() => data?.items ?? [], [data]);\n\n const activeId = submissionId ?? null;\n const activeSubmission = useMemo<BuiSubmission | null>(() => {\n if (!activeId) return null;\n return (\n rows.find((r) => r.id === activeId) ?? (deepLink.data?.id === activeId ? deepLink.data : null)\n );\n }, [activeId, rows, deepLink.data]);\n\n // The signed-in educator's own display name (used only for their own rows).\n const meName = useMemo<string | undefined>(() => {\n if (!currentUser) return undefined;\n const full = [currentUser.firstName, currentUser.lastName].filter(Boolean).join(' ').trim();\n return currentUser.name?.trim() || full || currentUser.username || currentUser.email;\n }, [currentUser]);\n\n // Counts are scoped to the loaded page — labelled \"this page\" to stay honest.\n const counts = useMemo(() => {\n const acc = { total: rows.length, awaiting: 0, graded: 0, returned: 0 };\n for (const s of rows) {\n if (s.status === 'SUBMITTED' || s.status === 'GRADING') acc.awaiting += 1;\n else if (s.status === 'GRADED') acc.graded += 1;\n else if (s.status === 'RETURNED') acc.returned += 1;\n }\n return acc;\n }, [rows]);\n\n const isMe = (learnerId: string): boolean => learnerId === currentUser?.id;\n const learnerLabel = (learnerId: string): string =>\n isMe(learnerId) ? 'You' : `Learner ${shortId(learnerId)}`;\n\n /** Row click: push the deep-linkable URL; the panel opens from the route param. */\n const selectSubmission = (s: BuiSubmission) => navigateTo(`submissions/${s.id}`);\n const closePanel = () => navigateTo('submissions');\n\n // If the id in the URL doesn't resolve to a real submission in this\n // workspace (wrong tenant, typo, or one that was later deleted), fall back\n // to the plain list once the lookup has definitively failed. This effect\n // only notifies the router — it never sets this component's own state, so\n // it can't cascade into an extra render loop.\n useEffect(() => {\n if (!activeId || activeSubmission) return;\n if (!deepLink.isLoading && (deepLink.isError || deepLink.data === null)) {\n navigateTo('submissions');\n }\n }, [activeId, activeSubmission, deepLink.isLoading, deepLink.isError, deepLink.data, navigateTo]);\n\n const handleFilterChange = (value: StatusFilter) => {\n setStatusFilter(value);\n pager.reset();\n };\n\n const columns: Column<BuiSubmission>[] = [\n {\n key: 'learner',\n header: 'Learner',\n sortValue: (s) => (isMe(s.learnerId) ? '' : s.learnerId),\n render: (s) => (\n <div className=\"flex items-center gap-3\">\n <Avatar\n size=\"sm\"\n name={isMe(s.learnerId) ? meName : undefined}\n seed={s.learnerId}\n src={isMe(s.learnerId) ? currentUser?.avatar : undefined}\n />\n <div className=\"min-w-0\">\n <span className=\"block truncate font-medium text-text-primary\" title={s.learnerId}>\n {isMe(s.learnerId) ? 'You' : shortId(s.learnerId)}\n </span>\n {isMe(s.learnerId) && meName && (\n <span className=\"block truncate text-xs text-text-secondary\">{meName}</span>\n )}\n </div>\n </div>\n ),\n },\n {\n key: 'assessment',\n header: 'Assessment',\n hideOnMobile: true,\n render: (s) => (\n <span className=\"inline-flex items-center gap-2 text-text-secondary\">\n <BookOpen className=\"h-4 w-4 shrink-0 opacity-70\" />\n <span className=\"font-mono text-xs\" title={s.assessmentId}>\n {shortId(s.assessmentId)}\n </span>\n </span>\n ),\n },\n {\n key: 'attempt',\n header: 'Attempt',\n align: 'right',\n hideOnMobile: true,\n sortValue: (s) => s.attempt,\n render: (s) => <span className=\"tabular-nums text-text-secondary\">#{s.attempt}</span>,\n },\n {\n key: 'status',\n header: 'Status',\n sortValue: (s) => s.status,\n render: (s) => <StatusBadge status={s.status} />,\n },\n {\n key: 'score',\n header: 'Score',\n align: 'right',\n sortValue: (s) => s.score ?? -1,\n render: (s) =>\n s.score == null ? (\n <span className=\"text-text-secondary\">—</span>\n ) : (\n <span className=\"tabular-nums font-semibold text-text-primary\">{s.score}</span>\n ),\n },\n {\n key: 'submittedAt',\n header: 'Submitted',\n align: 'right',\n hideOnMobile: true,\n sortValue: (s) => s.submittedAt ?? s.createdAt,\n render: (s) => (\n <div className=\"whitespace-nowrap text-right\">\n <div className=\"text-text-primary\">{formatDate(s.submittedAt)}</div>\n {s.submittedAt && (\n <div className=\"text-xs text-text-secondary\">{formatClock(s.submittedAt)}</div>\n )}\n </div>\n ),\n },\n ];\n\n return (\n <PageLayout\n title=\"Grading\"\n description=\"Review and grade assessment submissions across every course in your workspace.\"\n titleGradient\n aurora\n actions={\n <Button variant=\"outline\" onClick={() => navigateTo('submissions/bulk')}>\n <Layers className=\"mr-1.5 h-4 w-4\" /> Bulk grade\n </Button>\n }\n >\n <div className=\"flex flex-col gap-6\">\n {/* KPI row — scoped to the current page. */}\n <div className=\"grid grid-cols-2 gap-4 xl:grid-cols-4\">\n <MetricsCard\n icon={<ClipboardList className=\"h-5 w-5\" />}\n value={counts.total}\n label=\"Submissions (this page)\"\n featured\n />\n <MetricsCard\n icon={<Clock className=\"h-5 w-5\" />}\n value={counts.awaiting}\n label=\"Awaiting grade (this page)\"\n accent=\"warning\"\n />\n <MetricsCard\n icon={<CheckCircle2 className=\"h-5 w-5\" />}\n value={counts.graded}\n label=\"Graded (this page)\"\n accent=\"success\"\n />\n <MetricsCard\n icon={<Undo2 className=\"h-5 w-5\" />}\n value={counts.returned}\n label=\"Returned (this page)\"\n />\n </div>\n\n <Tabs items={STATUS_TABS} value={statusFilter} onChange={handleFilterChange} />\n\n {isLoading ? (\n <LoadingView label=\"Loading submissions…\" />\n ) : isError ? (\n <ErrorView\n title=\"Couldn't load submissions\"\n message=\"The grading queue failed to load.\"\n onRetry={() => refetch()}\n />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<GraduationCap className=\"h-10 w-10\" />}\n title={statusFilter === 'ALL' ? 'No submissions yet' : 'Nothing in this status'}\n description={\n statusFilter === 'ALL'\n ? 'When learners submit assessments, their attempts will appear here for grading.'\n : 'No submissions currently match this status filter.'\n }\n />\n ) : (\n <div className=\"flex flex-col gap-4\">\n <DataTable\n columns={columns}\n rows={rows}\n rowKey={(s) => s.id}\n onRowClick={selectSubmission}\n defaultSort={{ key: 'submittedAt', dir: 'desc' }}\n />\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={rows.length}\n hasMore={data?.pageInfo?.hasMore ?? false}\n onPageChange={(target) => pager.onPageChange(target, data?.pageInfo?.cursor)}\n />\n </div>\n )}\n </div>\n\n {/* Grading slide-over — right panel on desktop, bottom-sheet on mobile. */}\n <Sheet\n open={activeId != null}\n onOpenChange={(open) => {\n if (!open) closePanel();\n }}\n >\n <SheetContent\n side={isDesktop ? 'right' : 'bottom'}\n className={\n isDesktop\n ? 'flex w-full max-w-none flex-col gap-0 p-0 sm:max-w-xl'\n : 'flex max-h-[92vh] w-full flex-col gap-0 rounded-t-2xl p-0'\n }\n >\n {activeSubmission ? (\n // Keyed by submission id: remounting on id change gives the panel\n // fresh local (editable) state for free, with no synchronizing effect.\n <GradingPanelBody\n key={activeSubmission.id}\n submission={activeSubmission}\n currentUser={currentUser}\n meName={meName}\n isMe={isMe}\n learnerLabel={learnerLabel}\n gradeSubmission={gradeSubmission}\n onClose={closePanel}\n />\n ) : activeId ? (\n <div className=\"flex min-h-[300px] items-center justify-center p-5\">\n <LoadingView label=\"Loading submission…\" />\n </div>\n ) : null}\n </SheetContent>\n </Sheet>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -282,6 +282,101 @@ export interface BuiTutorSession {
282
282
  createdAt: string;
283
283
  updatedAt: string;
284
284
  }
285
+ export type BuiPacingHint = 'SLOW_DOWN' | 'STEADY' | 'ACCELERATE';
286
+ export type BuiAiSuggestionOutcome = 'PENDING' | 'ACCEPTED' | 'REJECTED';
287
+ export interface BuiQuestionFeedback {
288
+ questionId: string;
289
+ feedback: string;
290
+ suggestedPoints?: number | null;
291
+ }
292
+ export interface BuiGradeSuggestion {
293
+ id: string;
294
+ submissionId: string;
295
+ proposedScore: number;
296
+ perQuestionFeedback: BuiQuestionFeedback[];
297
+ rubricRefs: string[];
298
+ confidence: number;
299
+ inputRefs: string[];
300
+ outcome: BuiAiSuggestionOutcome;
301
+ createdAt: string;
302
+ }
303
+ export interface BuiNextLessonSuggestion {
304
+ id: string;
305
+ enrollmentId: string;
306
+ lessonId: string;
307
+ lessonTitle: string;
308
+ moduleId?: string | null;
309
+ moduleTitle?: string | null;
310
+ rationale: string;
311
+ confidence: number;
312
+ pacingHint: BuiPacingHint;
313
+ inputRefs: string[];
314
+ outcome: BuiAiSuggestionOutcome;
315
+ createdAt: string;
316
+ }
317
+ export interface BuiCourseOutlineLesson {
318
+ title: string;
319
+ description?: string | null;
320
+ }
321
+ export interface BuiCourseOutlineModule {
322
+ title: string;
323
+ description?: string | null;
324
+ lessons: BuiCourseOutlineLesson[];
325
+ }
326
+ export interface BuiCourseOutlineSuggestion {
327
+ rationale: string;
328
+ confidence: number;
329
+ modules: BuiCourseOutlineModule[];
330
+ }
331
+ export interface BuiCourseOutlineLessonInput {
332
+ title: string;
333
+ description?: string;
334
+ }
335
+ export interface BuiCourseOutlineModuleInput {
336
+ title: string;
337
+ description?: string;
338
+ lessons: BuiCourseOutlineLessonInput[];
339
+ }
340
+ export interface BuiApplyCourseOutlineInput {
341
+ title: string;
342
+ slug: string;
343
+ summary?: string;
344
+ level?: BuiCourseLevel;
345
+ modules: BuiCourseOutlineModuleInput[];
346
+ }
347
+ export type BuiAdminCopilotRole = 'USER' | 'ASSISTANT';
348
+ export interface BuiAdminCopilotTurnInput {
349
+ role: BuiAdminCopilotRole;
350
+ content: string;
351
+ }
352
+ export interface BuiAdminCopilotAnswer {
353
+ answer: string;
354
+ contextCourseIds: string[];
355
+ generatedAt: string;
356
+ }
357
+ export interface BuiLtiPlatform {
358
+ id: string;
359
+ workspaceId: string;
360
+ name: string;
361
+ issuer: string;
362
+ clientId: string;
363
+ deploymentIds: string[];
364
+ authLoginUrl: string;
365
+ authTokenUrl: string;
366
+ keySetUrl: string;
367
+ active: boolean;
368
+ createdAt: string;
369
+ updatedAt: string;
370
+ }
371
+ export interface BuiRegisterLtiPlatformInput {
372
+ name: string;
373
+ issuer: string;
374
+ clientId: string;
375
+ deploymentIds?: string[];
376
+ authLoginUrl: string;
377
+ authTokenUrl: string;
378
+ keySetUrl: string;
379
+ }
285
380
  export interface BuiCreateCourseInput {
286
381
  title: string;
287
382
  slug: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/buildmyiq/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/buildmyiq/types/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/buildmyiq/types/index.ts"],"sourcesContent":["/**\n * Buildmyiq Microfrontend — TypeScript Type Definitions\n *\n * Buildmyiq — the AI-native education, learning & development system of record.\n * Domain pillars, each 1:1 with a `wspace-buildmyiq-svc` capability:\n * - Catalog & authoring: courses → modules → lessons, skills taxonomy\n * - Assessment: assessments → questions → submissions → grading\n * - Enrolment & progress: enrollments, lesson progress, cohorts\n * - Credentialing: certificates\n *\n * All server-facing types below mirror the `wspace-buildmyiq-svc` federated\n * GraphQL contract exactly (the `Bui*` types, `bui*` root fields). No mock data.\n *\n * @module buildmyiq/types\n */\n\nimport type { ReactNode } from 'react';\n\n// ============================================================================\n// Shell Integration Types\n// ============================================================================\n\nexport interface NavItem {\n id: string;\n label: string;\n path: string;\n icon?: ReactNode;\n badge?: number;\n order?: number;\n group?: string;\n visible?: boolean;\n external?: boolean;\n children?: NavItem[];\n}\n\nexport interface FooterItem {\n id: string;\n label: string;\n icon?: string;\n onClick?: () => void;\n type?: 'status' | 'action' | 'info';\n order?: number;\n badge?: string;\n section?: 'left' | 'center' | 'right';\n visible?: boolean;\n}\n\n/**\n * Props for the BuildmyiqRoot component. Host-contract preserving: the app\n * shell spreads `workspaceBaseProps` (basePath, currentUser, workspaceId,\n * tenantId, apiGatewayUrl, authToken, navigate, registerNavItems,\n * registerFooterItems) onto this component.\n */\nexport interface BuildmyiqRootProps {\n basePath?: string;\n workspaceId?: string;\n tenantId?: string;\n apiGatewayUrl?: string;\n authToken?: string;\n navigate?: (path: string) => void;\n currentUser?: {\n id: string;\n email: string;\n firstName?: string;\n lastName?: string;\n avatar?: string;\n username?: string;\n name?: string;\n role?: string;\n } | null;\n registerNavItems?: (items: NavItem | NavItem[]) => () => void;\n registerFooterItems?: (items: FooterItem | FooterItem[]) => () => void;\n}\n\nexport type TrendDirection = 'up' | 'down' | 'neutral';\n\n// ============================================================================\n// Pagination (mirror svc PaginationInput / Bui*PageInfo)\n// ============================================================================\n\n/**\n * The svc `PaginationInput` accepts { limit, offset, cursor } but the resolver\n * uses cursor+limit only (offset is a no-op). We drive pages by cursor:\n * pass `pagination.cursor = previous pageInfo.cursor` for the next page. The\n * FIRST page must OMIT cursor entirely (an explicit `cursor: null` is rejected).\n */\nexport interface PaginationInput {\n limit?: number;\n offset?: number;\n cursor?: string | null;\n}\n\n/** All Bui*PageInfo variants are structurally { cursor, hasMore }. */\nexport interface BuiPageInfo {\n cursor?: string | null;\n hasMore: boolean;\n}\n\nexport interface BuiConnection<T> {\n items: T[];\n pageInfo: BuiPageInfo;\n}\n\n// ============================================================================\n// Federated stubs (owned by other subgraphs — wspace-files-svc)\n// ============================================================================\n\n/** A wspace-files-svc File reference resolved for cover/media/certificate. */\nexport interface BuiFileRef {\n id: string;\n name?: string | null;\n downloadUrl?: string | null;\n mimeType?: string | null;\n sizeBytes?: number | null;\n}\n\n// ============================================================================\n// Domain enums (mirror wspace-buildmyiq-svc .hive-schema.graphql exactly)\n// ============================================================================\n\nexport type BuiSkillCategory =\n 'TECHNICAL' | 'BUSINESS' | 'CREATIVE' | 'COGNITIVE' | 'SOCIAL' | 'LANGUAGE';\n\nexport type BuiCourseLevel = 'BEGINNER' | 'INTERMEDIATE' | 'ADVANCED' | 'EXPERT';\n\nexport type BuiCourseStatus = 'DRAFT' | 'IN_REVIEW' | 'PUBLISHED' | 'ARCHIVED';\n\nexport type BuiLessonType =\n 'ARTICLE' | 'VIDEO' | 'QUIZ' | 'ASSIGNMENT' | 'INTERACTIVE' | 'LIVE_SESSION';\n\nexport type BuiAssessmentType = 'QUIZ' | 'EXAM' | 'ASSIGNMENT' | 'PRACTICAL' | 'SURVEY';\n\nexport type BuiAssessmentStatus = 'DRAFT' | 'PUBLISHED' | 'ARCHIVED';\n\nexport type BuiQuestionType =\n 'SINGLE_CHOICE' | 'MULTIPLE_CHOICE' | 'TRUE_FALSE' | 'SHORT_ANSWER' | 'ESSAY' | 'CODE';\n\nexport type BuiSubmissionStatus = 'IN_PROGRESS' | 'SUBMITTED' | 'GRADING' | 'GRADED' | 'RETURNED';\n\nexport type BuiEnrollmentStatus = 'ENROLLED' | 'IN_PROGRESS' | 'COMPLETED' | 'DROPPED' | 'EXPIRED';\n\nexport type BuiProgressStatus = 'NOT_STARTED' | 'IN_PROGRESS' | 'COMPLETED';\n\nexport type BuiCohortStatus = 'SCHEDULED' | 'ENROLLING' | 'ACTIVE' | 'COMPLETED' | 'CANCELLED';\n\nexport type BuiCertificateStatus = 'ISSUED' | 'EXPIRED' | 'REVOKED';\n\nexport type BuiTutorMessageRole = 'USER' | 'ASSISTANT';\n\nexport type BuiTutorAdaptiveLevel = 'STRUGGLING' | 'ON_TRACK' | 'ADVANCED';\n\n// ============================================================================\n// Domain entity types (mirror the `Bui*` GraphQL types exactly)\n// ============================================================================\n\nexport interface BuiSkill {\n id: string;\n workspaceId: string;\n name: string;\n category: BuiSkillCategory;\n description?: string | null;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiModule {\n id: string;\n workspaceId: string;\n courseId: string;\n title: string;\n description?: string | null;\n position: number;\n lessons: BuiLesson[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiLesson {\n id: string;\n workspaceId: string;\n courseId: string;\n moduleId?: string | null;\n title: string;\n type: BuiLessonType;\n content?: string | null;\n media?: BuiFileRef | null;\n durationMin: number;\n position: number;\n isPreview: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiCourse {\n id: string;\n workspaceId: string;\n title: string;\n slug: string;\n summary?: string | null;\n description?: string | null;\n status: BuiCourseStatus;\n level: BuiCourseLevel;\n language: string;\n estimatedHours: number;\n isPublic: boolean;\n tags: string[];\n skillId?: string | null;\n skill?: BuiSkill | null;\n instructorId?: string | null;\n cover?: BuiFileRef | null;\n publishedAt?: string | null;\n modules: BuiModule[];\n lessons: BuiLesson[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiQuestion {\n id: string;\n workspaceId: string;\n assessmentId: string;\n prompt: string;\n type: BuiQuestionType;\n /**\n * JSON blob — array of `{ id?, label }` choices for choice questions. NOTE:\n * `answerKey` is a CREATE-INPUT field only; it is NOT exposed on the type\n * (never query it in a fragment — GRAPHQL_VALIDATION_FAILED).\n */\n options?: unknown;\n points: number;\n position: number;\n explanation?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiAssessment {\n id: string;\n workspaceId: string;\n courseId: string;\n title: string;\n description?: string | null;\n type: BuiAssessmentType;\n status: BuiAssessmentStatus;\n passingScore: number;\n maxAttempts: number;\n timeLimitMin: number;\n isGraded: boolean;\n questions: BuiQuestion[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiSubmission {\n id: string;\n workspaceId: string;\n assessmentId: string;\n enrollmentId?: string | null;\n learnerId: string;\n attempt: number;\n /** JSON blob — learner answers keyed by questionId. */\n answers?: unknown;\n status: BuiSubmissionStatus;\n score?: number | null;\n passed?: boolean | null;\n feedback?: string | null;\n gradedById?: string | null;\n gradedAt?: string | null;\n submittedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiLessonProgress {\n id: string;\n workspaceId: string;\n enrollmentId: string;\n lessonId: string;\n status: BuiProgressStatus;\n secondsSpent: number;\n completedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiCohort {\n id: string;\n workspaceId: string;\n courseId: string;\n name: string;\n capacity: number;\n facilitatorId?: string | null;\n startDate?: string | null;\n endDate?: string | null;\n status: BuiCohortStatus;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiEnrollment {\n id: string;\n workspaceId: string;\n courseId: string;\n learnerId: string;\n cohortId?: string | null;\n cohort?: BuiCohort | null;\n status: BuiEnrollmentStatus;\n progressPct: number;\n enrolledAt: string;\n startedAt?: string | null;\n completedAt?: string | null;\n lastActiveAt?: string | null;\n expiresAt?: string | null;\n lessonProgress: BuiLessonProgress[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiCertificate {\n id: string;\n workspaceId: string;\n courseId: string;\n learnerId: string;\n enrollmentId?: string | null;\n serial: string;\n status: BuiCertificateStatus;\n issuedAt: string;\n expiresAt?: string | null;\n revokedAt?: string | null;\n finalScore?: number | null;\n file?: BuiFileRef | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiTutorMessage {\n id: string;\n workspaceId: string;\n sessionId: string;\n role: BuiTutorMessageRole;\n content: string;\n groundingLessonIds: string[];\n adaptiveLevel?: BuiTutorAdaptiveLevel | null;\n createdAt: string;\n}\n\nexport interface BuiTutorSession {\n id: string;\n workspaceId: string;\n courseId: string;\n lessonId: string;\n learnerId: string;\n messages: BuiTutorMessage[];\n createdAt: string;\n updatedAt: string;\n}\n\n// ============================================================================\n// Mutation input types (mirror the svc `Bui*Input` shapes)\n// ============================================================================\n\nexport interface BuiCreateCourseInput {\n title: string;\n slug: string;\n summary?: string;\n description?: string;\n level?: BuiCourseLevel;\n language?: string;\n estimatedHours?: number;\n isPublic?: boolean;\n tags?: string[];\n skillId?: string;\n instructorId?: string;\n coverFileId?: string;\n}\n\nexport interface BuiUpdateCourseInput {\n title?: string;\n summary?: string;\n description?: string;\n level?: BuiCourseLevel;\n language?: string;\n estimatedHours?: number;\n isPublic?: boolean;\n tags?: string[];\n skillId?: string;\n instructorId?: string;\n coverFileId?: string;\n}\n\nexport interface BuiCreateModuleInput {\n courseId: string;\n title: string;\n description?: string;\n position?: number;\n}\n\nexport interface BuiCreateLessonInput {\n courseId: string;\n moduleId?: string;\n title: string;\n type?: BuiLessonType;\n content?: string;\n durationMin?: number;\n position?: number;\n isPreview?: boolean;\n mediaFileId?: string;\n}\n\nexport interface BuiCreateAssessmentInput {\n courseId: string;\n title: string;\n description?: string;\n type?: BuiAssessmentType;\n passingScore?: number;\n maxAttempts?: number;\n timeLimitMin?: number;\n isGraded?: boolean;\n}\n\nexport interface BuiCreateQuestionInput {\n assessmentId: string;\n prompt: string;\n type?: BuiQuestionType;\n options?: unknown;\n answerKey?: unknown;\n points?: number;\n position?: number;\n explanation?: string;\n}\n\nexport interface BuiCreateSkillInput {\n name: string;\n category?: BuiSkillCategory;\n description?: string;\n}\n\nexport interface BuiCreateCohortInput {\n courseId: string;\n name: string;\n capacity?: number;\n facilitatorId?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface BuiEnrollInput {\n courseId: string;\n learnerId?: string;\n cohortId?: string;\n expiresAt?: string;\n}\n\nexport interface BuiRecordLessonProgressInput {\n enrollmentId: string;\n lessonId: string;\n secondsSpent?: number;\n status?: BuiProgressStatus;\n}\n\nexport interface BuiSubmitAssessmentInput {\n assessmentId: string;\n learnerId?: string;\n enrollmentId?: string;\n attempt?: number;\n answers?: unknown;\n}\n\nexport interface BuiGradeSubmissionInput {\n score: number;\n passed?: boolean;\n feedback?: string;\n}\n\nexport interface BuiIssueCertificateInput {\n courseId: string;\n learnerId: string;\n enrollmentId?: string;\n serial: string;\n finalScore?: number;\n expiresAt?: string;\n fileId?: string;\n}\n\nexport interface BuiTutorAskInput {\n lessonId: string;\n question: string;\n sessionId?: string;\n}\n\nexport interface BuiTutorAskPayload {\n session: BuiTutorSession;\n answer: BuiTutorMessage;\n}\n\n// ============================================================================\n// Convenience option lists (for select controls in authoring UIs)\n// ============================================================================\n\nexport const COURSE_LEVELS: BuiCourseLevel[] = ['BEGINNER', 'INTERMEDIATE', 'ADVANCED', 'EXPERT'];\nexport const COURSE_STATUSES: BuiCourseStatus[] = ['DRAFT', 'IN_REVIEW', 'PUBLISHED', 'ARCHIVED'];\nexport const LESSON_TYPES: BuiLessonType[] = [\n 'ARTICLE',\n 'VIDEO',\n 'QUIZ',\n 'ASSIGNMENT',\n 'INTERACTIVE',\n 'LIVE_SESSION',\n];\nexport const ASSESSMENT_TYPES: BuiAssessmentType[] = [\n 'QUIZ',\n 'EXAM',\n 'ASSIGNMENT',\n 'PRACTICAL',\n 'SURVEY',\n];\nexport const QUESTION_TYPES: BuiQuestionType[] = [\n 'SINGLE_CHOICE',\n 'MULTIPLE_CHOICE',\n 'TRUE_FALSE',\n 'SHORT_ANSWER',\n 'ESSAY',\n 'CODE',\n];\nexport const SKILL_CATEGORIES: BuiSkillCategory[] = [\n 'TECHNICAL',\n 'BUSINESS',\n 'CREATIVE',\n 'COGNITIVE',\n 'SOCIAL',\n 'LANGUAGE',\n];\nexport const ENROLLMENT_STATUSES: BuiEnrollmentStatus[] = [\n 'ENROLLED',\n 'IN_PROGRESS',\n 'COMPLETED',\n 'DROPPED',\n 'EXPIRED',\n];\nexport const COHORT_STATUSES: BuiCohortStatus[] = [\n 'SCHEDULED',\n 'ENROLLING',\n 'ACTIVE',\n 'COMPLETED',\n 'CANCELLED',\n];\nexport const SUBMISSION_STATUSES: BuiSubmissionStatus[] = [\n 'IN_PROGRESS',\n 'SUBMITTED',\n 'GRADING',\n 'GRADED',\n 'RETURNED',\n];\n"],"mappings":";AAofA,IAAa,IAAkC;CAAC;CAAY;CAAgB;CAAY;AAAQ,GAEnF,IAAgC;CAC3C;CACA;CACA;CACA;CACA;CACA;AACF,GACa,IAAwC;CACnD;CACA;CACA;CACA;CACA;AACF,GACa,IAAoC;CAC/C;CACA;CACA;CACA;CACA;CACA;AACF,GACa,IAAuC;CAClD;CACA;CACA;CACA;CACA;CACA;AACF,GAQa,IAAqC;CAChD;CACA;CACA;CACA;CACA;AACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/buildmyiq/types/index.ts"],"sourcesContent":["/**\n * Buildmyiq Microfrontend — TypeScript Type Definitions\n *\n * Buildmyiq — the AI-native education, learning & development system of record.\n * Domain pillars, each 1:1 with a `wspace-buildmyiq-svc` capability:\n * - Catalog & authoring: courses → modules → lessons, skills taxonomy\n * - Assessment: assessments → questions → submissions → grading\n * - Enrolment & progress: enrollments, lesson progress, cohorts\n * - Credentialing: certificates\n *\n * All server-facing types below mirror the `wspace-buildmyiq-svc` federated\n * GraphQL contract exactly (the `Bui*` types, `bui*` root fields). No mock data.\n *\n * @module buildmyiq/types\n */\n\nimport type { ReactNode } from 'react';\n\n// ============================================================================\n// Shell Integration Types\n// ============================================================================\n\nexport interface NavItem {\n id: string;\n label: string;\n path: string;\n icon?: ReactNode;\n badge?: number;\n order?: number;\n group?: string;\n visible?: boolean;\n external?: boolean;\n children?: NavItem[];\n}\n\nexport interface FooterItem {\n id: string;\n label: string;\n icon?: string;\n onClick?: () => void;\n type?: 'status' | 'action' | 'info';\n order?: number;\n badge?: string;\n section?: 'left' | 'center' | 'right';\n visible?: boolean;\n}\n\n/**\n * Props for the BuildmyiqRoot component. Host-contract preserving: the app\n * shell spreads `workspaceBaseProps` (basePath, currentUser, workspaceId,\n * tenantId, apiGatewayUrl, authToken, navigate, registerNavItems,\n * registerFooterItems) onto this component.\n */\nexport interface BuildmyiqRootProps {\n basePath?: string;\n workspaceId?: string;\n tenantId?: string;\n apiGatewayUrl?: string;\n authToken?: string;\n navigate?: (path: string) => void;\n currentUser?: {\n id: string;\n email: string;\n firstName?: string;\n lastName?: string;\n avatar?: string;\n username?: string;\n name?: string;\n role?: string;\n } | null;\n registerNavItems?: (items: NavItem | NavItem[]) => () => void;\n registerFooterItems?: (items: FooterItem | FooterItem[]) => () => void;\n}\n\nexport type TrendDirection = 'up' | 'down' | 'neutral';\n\n// ============================================================================\n// Pagination (mirror svc PaginationInput / Bui*PageInfo)\n// ============================================================================\n\n/**\n * The svc `PaginationInput` accepts { limit, offset, cursor } but the resolver\n * uses cursor+limit only (offset is a no-op). We drive pages by cursor:\n * pass `pagination.cursor = previous pageInfo.cursor` for the next page. The\n * FIRST page must OMIT cursor entirely (an explicit `cursor: null` is rejected).\n */\nexport interface PaginationInput {\n limit?: number;\n offset?: number;\n cursor?: string | null;\n}\n\n/** All Bui*PageInfo variants are structurally { cursor, hasMore }. */\nexport interface BuiPageInfo {\n cursor?: string | null;\n hasMore: boolean;\n}\n\nexport interface BuiConnection<T> {\n items: T[];\n pageInfo: BuiPageInfo;\n}\n\n// ============================================================================\n// Federated stubs (owned by other subgraphs — wspace-files-svc)\n// ============================================================================\n\n/** A wspace-files-svc File reference resolved for cover/media/certificate. */\nexport interface BuiFileRef {\n id: string;\n name?: string | null;\n downloadUrl?: string | null;\n mimeType?: string | null;\n sizeBytes?: number | null;\n}\n\n// ============================================================================\n// Domain enums (mirror wspace-buildmyiq-svc .hive-schema.graphql exactly)\n// ============================================================================\n\nexport type BuiSkillCategory =\n 'TECHNICAL' | 'BUSINESS' | 'CREATIVE' | 'COGNITIVE' | 'SOCIAL' | 'LANGUAGE';\n\nexport type BuiCourseLevel = 'BEGINNER' | 'INTERMEDIATE' | 'ADVANCED' | 'EXPERT';\n\nexport type BuiCourseStatus = 'DRAFT' | 'IN_REVIEW' | 'PUBLISHED' | 'ARCHIVED';\n\nexport type BuiLessonType =\n 'ARTICLE' | 'VIDEO' | 'QUIZ' | 'ASSIGNMENT' | 'INTERACTIVE' | 'LIVE_SESSION';\n\nexport type BuiAssessmentType = 'QUIZ' | 'EXAM' | 'ASSIGNMENT' | 'PRACTICAL' | 'SURVEY';\n\nexport type BuiAssessmentStatus = 'DRAFT' | 'PUBLISHED' | 'ARCHIVED';\n\nexport type BuiQuestionType =\n 'SINGLE_CHOICE' | 'MULTIPLE_CHOICE' | 'TRUE_FALSE' | 'SHORT_ANSWER' | 'ESSAY' | 'CODE';\n\nexport type BuiSubmissionStatus = 'IN_PROGRESS' | 'SUBMITTED' | 'GRADING' | 'GRADED' | 'RETURNED';\n\nexport type BuiEnrollmentStatus = 'ENROLLED' | 'IN_PROGRESS' | 'COMPLETED' | 'DROPPED' | 'EXPIRED';\n\nexport type BuiProgressStatus = 'NOT_STARTED' | 'IN_PROGRESS' | 'COMPLETED';\n\nexport type BuiCohortStatus = 'SCHEDULED' | 'ENROLLING' | 'ACTIVE' | 'COMPLETED' | 'CANCELLED';\n\nexport type BuiCertificateStatus = 'ISSUED' | 'EXPIRED' | 'REVOKED';\n\nexport type BuiTutorMessageRole = 'USER' | 'ASSISTANT';\n\nexport type BuiTutorAdaptiveLevel = 'STRUGGLING' | 'ON_TRACK' | 'ADVANCED';\n\n// ============================================================================\n// Domain entity types (mirror the `Bui*` GraphQL types exactly)\n// ============================================================================\n\nexport interface BuiSkill {\n id: string;\n workspaceId: string;\n name: string;\n category: BuiSkillCategory;\n description?: string | null;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiModule {\n id: string;\n workspaceId: string;\n courseId: string;\n title: string;\n description?: string | null;\n position: number;\n lessons: BuiLesson[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiLesson {\n id: string;\n workspaceId: string;\n courseId: string;\n moduleId?: string | null;\n title: string;\n type: BuiLessonType;\n content?: string | null;\n media?: BuiFileRef | null;\n durationMin: number;\n position: number;\n isPreview: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiCourse {\n id: string;\n workspaceId: string;\n title: string;\n slug: string;\n summary?: string | null;\n description?: string | null;\n status: BuiCourseStatus;\n level: BuiCourseLevel;\n language: string;\n estimatedHours: number;\n isPublic: boolean;\n tags: string[];\n skillId?: string | null;\n skill?: BuiSkill | null;\n instructorId?: string | null;\n cover?: BuiFileRef | null;\n publishedAt?: string | null;\n modules: BuiModule[];\n lessons: BuiLesson[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiQuestion {\n id: string;\n workspaceId: string;\n assessmentId: string;\n prompt: string;\n type: BuiQuestionType;\n /**\n * JSON blob — array of `{ id?, label }` choices for choice questions. NOTE:\n * `answerKey` is a CREATE-INPUT field only; it is NOT exposed on the type\n * (never query it in a fragment — GRAPHQL_VALIDATION_FAILED).\n */\n options?: unknown;\n points: number;\n position: number;\n explanation?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiAssessment {\n id: string;\n workspaceId: string;\n courseId: string;\n title: string;\n description?: string | null;\n type: BuiAssessmentType;\n status: BuiAssessmentStatus;\n passingScore: number;\n maxAttempts: number;\n timeLimitMin: number;\n isGraded: boolean;\n questions: BuiQuestion[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiSubmission {\n id: string;\n workspaceId: string;\n assessmentId: string;\n enrollmentId?: string | null;\n learnerId: string;\n attempt: number;\n /** JSON blob — learner answers keyed by questionId. */\n answers?: unknown;\n status: BuiSubmissionStatus;\n score?: number | null;\n passed?: boolean | null;\n feedback?: string | null;\n gradedById?: string | null;\n gradedAt?: string | null;\n submittedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiLessonProgress {\n id: string;\n workspaceId: string;\n enrollmentId: string;\n lessonId: string;\n status: BuiProgressStatus;\n secondsSpent: number;\n completedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiCohort {\n id: string;\n workspaceId: string;\n courseId: string;\n name: string;\n capacity: number;\n facilitatorId?: string | null;\n startDate?: string | null;\n endDate?: string | null;\n status: BuiCohortStatus;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiEnrollment {\n id: string;\n workspaceId: string;\n courseId: string;\n learnerId: string;\n cohortId?: string | null;\n cohort?: BuiCohort | null;\n status: BuiEnrollmentStatus;\n progressPct: number;\n enrolledAt: string;\n startedAt?: string | null;\n completedAt?: string | null;\n lastActiveAt?: string | null;\n expiresAt?: string | null;\n lessonProgress: BuiLessonProgress[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiCertificate {\n id: string;\n workspaceId: string;\n courseId: string;\n learnerId: string;\n enrollmentId?: string | null;\n serial: string;\n status: BuiCertificateStatus;\n issuedAt: string;\n expiresAt?: string | null;\n revokedAt?: string | null;\n finalScore?: number | null;\n file?: BuiFileRef | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiTutorMessage {\n id: string;\n workspaceId: string;\n sessionId: string;\n role: BuiTutorMessageRole;\n content: string;\n groundingLessonIds: string[];\n adaptiveLevel?: BuiTutorAdaptiveLevel | null;\n createdAt: string;\n}\n\nexport interface BuiTutorSession {\n id: string;\n workspaceId: string;\n courseId: string;\n lessonId: string;\n learnerId: string;\n messages: BuiTutorMessage[];\n createdAt: string;\n updatedAt: string;\n}\n\n// ============================================================================\n// Intelligence domain (BOFF-3724 / BOFF-4429 / BOFF-4434) — AI decision engine\n// ============================================================================\n\nexport type BuiPacingHint = 'SLOW_DOWN' | 'STEADY' | 'ACCELERATE';\nexport type BuiAiSuggestionOutcome = 'PENDING' | 'ACCEPTED' | 'REJECTED';\n\nexport interface BuiQuestionFeedback {\n questionId: string;\n feedback: string;\n suggestedPoints?: number | null;\n}\n\nexport interface BuiGradeSuggestion {\n id: string;\n submissionId: string;\n proposedScore: number;\n perQuestionFeedback: BuiQuestionFeedback[];\n rubricRefs: string[];\n confidence: number;\n inputRefs: string[];\n outcome: BuiAiSuggestionOutcome;\n createdAt: string;\n}\n\nexport interface BuiNextLessonSuggestion {\n id: string;\n enrollmentId: string;\n lessonId: string;\n lessonTitle: string;\n moduleId?: string | null;\n moduleTitle?: string | null;\n rationale: string;\n confidence: number;\n pacingHint: BuiPacingHint;\n inputRefs: string[];\n outcome: BuiAiSuggestionOutcome;\n createdAt: string;\n}\n\nexport interface BuiCourseOutlineLesson {\n title: string;\n description?: string | null;\n}\n\nexport interface BuiCourseOutlineModule {\n title: string;\n description?: string | null;\n lessons: BuiCourseOutlineLesson[];\n}\n\nexport interface BuiCourseOutlineSuggestion {\n rationale: string;\n confidence: number;\n modules: BuiCourseOutlineModule[];\n}\n\nexport interface BuiCourseOutlineLessonInput {\n title: string;\n description?: string;\n}\n\nexport interface BuiCourseOutlineModuleInput {\n title: string;\n description?: string;\n lessons: BuiCourseOutlineLessonInput[];\n}\n\nexport interface BuiApplyCourseOutlineInput {\n title: string;\n slug: string;\n summary?: string;\n level?: BuiCourseLevel;\n modules: BuiCourseOutlineModuleInput[];\n}\n\nexport type BuiAdminCopilotRole = 'USER' | 'ASSISTANT';\n\nexport interface BuiAdminCopilotTurnInput {\n role: BuiAdminCopilotRole;\n content: string;\n}\n\nexport interface BuiAdminCopilotAnswer {\n answer: string;\n contextCourseIds: string[];\n generatedAt: string;\n}\n\n// ============================================================================\n// LTI 1.3 Advantage domain (BOFF-4419)\n// ============================================================================\n\nexport interface BuiLtiPlatform {\n id: string;\n workspaceId: string;\n name: string;\n issuer: string;\n clientId: string;\n deploymentIds: string[];\n authLoginUrl: string;\n authTokenUrl: string;\n keySetUrl: string;\n active: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface BuiRegisterLtiPlatformInput {\n name: string;\n issuer: string;\n clientId: string;\n deploymentIds?: string[];\n authLoginUrl: string;\n authTokenUrl: string;\n keySetUrl: string;\n}\n\n// ============================================================================\n// Mutation input types (mirror the svc `Bui*Input` shapes)\n// ============================================================================\n\nexport interface BuiCreateCourseInput {\n title: string;\n slug: string;\n summary?: string;\n description?: string;\n level?: BuiCourseLevel;\n language?: string;\n estimatedHours?: number;\n isPublic?: boolean;\n tags?: string[];\n skillId?: string;\n instructorId?: string;\n coverFileId?: string;\n}\n\nexport interface BuiUpdateCourseInput {\n title?: string;\n summary?: string;\n description?: string;\n level?: BuiCourseLevel;\n language?: string;\n estimatedHours?: number;\n isPublic?: boolean;\n tags?: string[];\n skillId?: string;\n instructorId?: string;\n coverFileId?: string;\n}\n\nexport interface BuiCreateModuleInput {\n courseId: string;\n title: string;\n description?: string;\n position?: number;\n}\n\nexport interface BuiCreateLessonInput {\n courseId: string;\n moduleId?: string;\n title: string;\n type?: BuiLessonType;\n content?: string;\n durationMin?: number;\n position?: number;\n isPreview?: boolean;\n mediaFileId?: string;\n}\n\nexport interface BuiCreateAssessmentInput {\n courseId: string;\n title: string;\n description?: string;\n type?: BuiAssessmentType;\n passingScore?: number;\n maxAttempts?: number;\n timeLimitMin?: number;\n isGraded?: boolean;\n}\n\nexport interface BuiCreateQuestionInput {\n assessmentId: string;\n prompt: string;\n type?: BuiQuestionType;\n options?: unknown;\n answerKey?: unknown;\n points?: number;\n position?: number;\n explanation?: string;\n}\n\nexport interface BuiCreateSkillInput {\n name: string;\n category?: BuiSkillCategory;\n description?: string;\n}\n\nexport interface BuiCreateCohortInput {\n courseId: string;\n name: string;\n capacity?: number;\n facilitatorId?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface BuiEnrollInput {\n courseId: string;\n learnerId?: string;\n cohortId?: string;\n expiresAt?: string;\n}\n\nexport interface BuiRecordLessonProgressInput {\n enrollmentId: string;\n lessonId: string;\n secondsSpent?: number;\n status?: BuiProgressStatus;\n}\n\nexport interface BuiSubmitAssessmentInput {\n assessmentId: string;\n learnerId?: string;\n enrollmentId?: string;\n attempt?: number;\n answers?: unknown;\n}\n\nexport interface BuiGradeSubmissionInput {\n score: number;\n passed?: boolean;\n feedback?: string;\n}\n\nexport interface BuiIssueCertificateInput {\n courseId: string;\n learnerId: string;\n enrollmentId?: string;\n serial: string;\n finalScore?: number;\n expiresAt?: string;\n fileId?: string;\n}\n\nexport interface BuiTutorAskInput {\n lessonId: string;\n question: string;\n sessionId?: string;\n}\n\nexport interface BuiTutorAskPayload {\n session: BuiTutorSession;\n answer: BuiTutorMessage;\n}\n\n// ============================================================================\n// Convenience option lists (for select controls in authoring UIs)\n// ============================================================================\n\nexport const COURSE_LEVELS: BuiCourseLevel[] = ['BEGINNER', 'INTERMEDIATE', 'ADVANCED', 'EXPERT'];\nexport const COURSE_STATUSES: BuiCourseStatus[] = ['DRAFT', 'IN_REVIEW', 'PUBLISHED', 'ARCHIVED'];\nexport const LESSON_TYPES: BuiLessonType[] = [\n 'ARTICLE',\n 'VIDEO',\n 'QUIZ',\n 'ASSIGNMENT',\n 'INTERACTIVE',\n 'LIVE_SESSION',\n];\nexport const ASSESSMENT_TYPES: BuiAssessmentType[] = [\n 'QUIZ',\n 'EXAM',\n 'ASSIGNMENT',\n 'PRACTICAL',\n 'SURVEY',\n];\nexport const QUESTION_TYPES: BuiQuestionType[] = [\n 'SINGLE_CHOICE',\n 'MULTIPLE_CHOICE',\n 'TRUE_FALSE',\n 'SHORT_ANSWER',\n 'ESSAY',\n 'CODE',\n];\nexport const SKILL_CATEGORIES: BuiSkillCategory[] = [\n 'TECHNICAL',\n 'BUSINESS',\n 'CREATIVE',\n 'COGNITIVE',\n 'SOCIAL',\n 'LANGUAGE',\n];\nexport const ENROLLMENT_STATUSES: BuiEnrollmentStatus[] = [\n 'ENROLLED',\n 'IN_PROGRESS',\n 'COMPLETED',\n 'DROPPED',\n 'EXPIRED',\n];\nexport const COHORT_STATUSES: BuiCohortStatus[] = [\n 'SCHEDULED',\n 'ENROLLING',\n 'ACTIVE',\n 'COMPLETED',\n 'CANCELLED',\n];\nexport const SUBMISSION_STATUSES: BuiSubmissionStatus[] = [\n 'IN_PROGRESS',\n 'SUBMITTED',\n 'GRADING',\n 'GRADED',\n 'RETURNED',\n];\n"],"mappings":";AA0mBA,IAAa,IAAkC;CAAC;CAAY;CAAgB;CAAY;AAAQ,GAEnF,IAAgC;CAC3C;CACA;CACA;CACA;CACA;CACA;AACF,GACa,IAAwC;CACnD;CACA;CACA;CACA;CACA;AACF,GACa,IAAoC;CAC/C;CACA;CACA;CACA;CACA;CACA;AACF,GACa,IAAuC;CAClD;CACA;CACA;CACA;CACA;CACA;AACF,GAQa,IAAqC;CAChD;CACA;CACA;CACA;CACA;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-buildmyiq",
3
- "version": "2026.730.2",
3
+ "version": "2026.731.2",
4
4
  "description": "Burdenoff BuildMyIQ Microfrontend — education, learning & development",
5
5
  "type": "module",
6
6
  "files": [
@@ -26,14 +26,14 @@
26
26
  "types": "./dist/index.d.ts",
27
27
  "scripts": {
28
28
  "dev": "vite",
29
- "build": "tsc && vite build",
29
+ "build": "tsc && bash scripts/build-limits.sh --gate vite build",
30
30
  "lint": "eslint .",
31
31
  "format": "prettier --write \"src/**/*.{ts,tsx}\"",
32
- "type:check": "tsc --noEmit",
32
+ "type:check": "bash scripts/build-limits.sh tsc --noEmit",
33
33
  "storybook": "storybook dev -p 6006",
34
34
  "build-storybook": "storybook build",
35
35
  "test:storybook": "test-storybook",
36
- "sanity": "bun run codegen && bun run lint && bun run format && bun run type:check && bun run build && bun run build-storybook",
36
+ "sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run codegen && bun run lint && bun run format && bun run type:check && bun run build && bun run build-storybook'",
37
37
  "schema:pull": "graphql-codegen --project schema-wspace && graphql-codegen --project schema-global",
38
38
  "codegen": "graphql-codegen --project wspace && graphql-codegen --project global",
39
39
  "codegen:all": "bun run schema:pull && bun run codegen",