@burdenoff/microfe-technospam 2026.1102.1 → 2026.1102.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.
- package/dist/generated/wspace-types.d.ts +7468 -141
- package/dist/generated/wspace-types.d.ts.map +1 -1
- package/dist/node_modules/@codemirror/autocomplete/dist/index.js +527 -0
- package/dist/node_modules/@codemirror/autocomplete/dist/index.js.map +1 -0
- package/dist/node_modules/@codemirror/commands/dist/index.js +1108 -0
- package/dist/node_modules/@codemirror/commands/dist/index.js.map +1 -0
- package/dist/node_modules/@codemirror/lang-go/dist/index.js +206 -0
- package/dist/node_modules/@codemirror/lang-go/dist/index.js.map +1 -0
- package/dist/node_modules/@codemirror/lang-javascript/dist/index.js +321 -0
- package/dist/node_modules/@codemirror/lang-javascript/dist/index.js.map +1 -0
- package/dist/node_modules/@codemirror/lang-python/dist/index.js +265 -0
- package/dist/node_modules/@codemirror/lang-python/dist/index.js.map +1 -0
- package/dist/node_modules/@codemirror/language/dist/index.js +957 -0
- package/dist/node_modules/@codemirror/language/dist/index.js.map +1 -0
- package/dist/node_modules/@codemirror/legacy-modes/mode/ruby.js +164 -0
- package/dist/node_modules/@codemirror/legacy-modes/mode/ruby.js.map +1 -0
- package/dist/node_modules/@codemirror/legacy-modes/mode/shell.js +109 -0
- package/dist/node_modules/@codemirror/legacy-modes/mode/shell.js.map +1 -0
- package/dist/node_modules/@codemirror/state/dist/index.js +1739 -0
- package/dist/node_modules/@codemirror/state/dist/index.js.map +1 -0
- package/dist/node_modules/@codemirror/streamparser/dist/index.js +70 -0
- package/dist/node_modules/@codemirror/streamparser/dist/index.js.map +1 -0
- package/dist/node_modules/@codemirror/view/dist/index.js +5427 -0
- package/dist/node_modules/@codemirror/view/dist/index.js.map +1 -0
- package/dist/node_modules/@lezer/common/dist/index.js +896 -0
- package/dist/node_modules/@lezer/common/dist/index.js.map +1 -0
- package/dist/node_modules/@lezer/go/dist/index.js +215 -0
- package/dist/node_modules/@lezer/go/dist/index.js.map +1 -0
- package/dist/node_modules/@lezer/highlight/dist/index.js +395 -0
- package/dist/node_modules/@lezer/highlight/dist/index.js.map +1 -0
- package/dist/node_modules/@lezer/javascript/dist/index.js +437 -0
- package/dist/node_modules/@lezer/javascript/dist/index.js.map +1 -0
- package/dist/node_modules/@lezer/lr/dist/index.js +842 -0
- package/dist/node_modules/@lezer/lr/dist/index.js.map +1 -0
- package/dist/node_modules/@lezer/python/dist/index.js +352 -0
- package/dist/node_modules/@lezer/python/dist/index.js.map +1 -0
- package/dist/node_modules/@marijn/find-cluster-break/src/index.js +66 -0
- package/dist/node_modules/@marijn/find-cluster-break/src/index.js.map +1 -0
- package/dist/node_modules/style-mod/src/style-mod.js +74 -0
- package/dist/node_modules/style-mod/src/style-mod.js.map +1 -0
- package/dist/node_modules/w3c-keyname/index.js +90 -0
- package/dist/node_modules/w3c-keyname/index.js.map +1 -0
- package/dist/stories/fixtures/technospamFixtures.d.ts.map +1 -1
- package/dist/stories/journeys/Problems.stories.d.ts.map +1 -1
- package/dist/technospam/api/technospamApi.d.ts +39 -0
- package/dist/technospam/api/technospamApi.d.ts.map +1 -1
- package/dist/technospam/api/technospamApi.js +120 -86
- package/dist/technospam/api/technospamApi.js.map +1 -1
- package/dist/technospam/components/SubmissionViews.d.ts +6 -2
- package/dist/technospam/components/SubmissionViews.d.ts.map +1 -1
- package/dist/technospam/components/SubmissionViews.js +6 -5
- package/dist/technospam/components/SubmissionViews.js.map +1 -1
- package/dist/technospam/components/TechnoSpamErrorBoundary.d.ts +6 -0
- package/dist/technospam/components/TechnoSpamErrorBoundary.d.ts.map +1 -1
- package/dist/technospam/components/TechnoSpamErrorBoundary.js +2 -2
- package/dist/technospam/components/TechnoSpamErrorBoundary.js.map +1 -1
- package/dist/technospam/components/editor/CodeEditor.d.ts +26 -0
- package/dist/technospam/components/editor/CodeEditor.d.ts.map +1 -0
- package/dist/technospam/components/editor/CodeEditor.js +102 -0
- package/dist/technospam/components/editor/CodeEditor.js.map +1 -0
- package/dist/technospam/components/editor/RunOutputPanel.d.ts +14 -0
- package/dist/technospam/components/editor/RunOutputPanel.d.ts.map +1 -0
- package/dist/technospam/components/editor/RunOutputPanel.js +127 -0
- package/dist/technospam/components/editor/RunOutputPanel.js.map +1 -0
- package/dist/technospam/components/editor/editorLanguages.d.ts +11 -0
- package/dist/technospam/components/editor/editorLanguages.d.ts.map +1 -0
- package/dist/technospam/components/editor/editorLanguages.js +30 -0
- package/dist/technospam/components/editor/editorLanguages.js.map +1 -0
- package/dist/technospam/components/editor/editorTheme.d.ts +11 -0
- package/dist/technospam/components/editor/editorTheme.d.ts.map +1 -0
- package/dist/technospam/components/editor/editorTheme.js +120 -0
- package/dist/technospam/components/editor/editorTheme.js.map +1 -0
- package/dist/technospam/hooks/useSolutionRunner.d.ts +35 -0
- package/dist/technospam/hooks/useSolutionRunner.d.ts.map +1 -0
- package/dist/technospam/hooks/useSolutionRunner.js +66 -0
- package/dist/technospam/hooks/useSolutionRunner.js.map +1 -0
- package/dist/technospam/hooks/useTechnoSpamAnalytics.d.ts +1 -1
- package/dist/technospam/hooks/useTechnoSpamAnalytics.d.ts.map +1 -1
- package/dist/technospam/hooks/useTechnoSpamAnalytics.js.map +1 -1
- package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.d.ts.map +1 -1
- package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.js +416 -263
- package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.js.map +1 -1
- package/package.json +14 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationsProblemDetailsPagePage.js","names":[],"sources":["../../../src/technospam/pages/ApplicationsProblemDetailsPagePage.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\nimport { useSearchParams } from 'react-router';\nimport {\n Clock,\n Code2,\n FileText,\n FlaskConical,\n Layers,\n RefreshCw,\n Send,\n Sparkles,\n Tag,\n Trophy,\n} from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Skeleton,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport {\n CodePanel,\n EmptyView,\n ErrorView,\n IoBlock,\n LoadingRows,\n PageLayout,\n PremiumBadge,\n StatCard,\n StatusBadge,\n SubmissionReviewPanel,\n TagStrip,\n TestResultsPanel,\n UpgradeGate,\n} from '../components';\nimport { useTechnoSpam, useTechnoSpamNavigate } from '../providers/TechnoSpamProvider';\nimport {\n useProblemQuery,\n useRegradeSubmission,\n useSubmissionsQuery,\n useSubmitSolution,\n type TecSubmission,\n} from '../api/technospamApi';\nimport { formatDateTime, humanizeEnum } from '../utils/format';\nimport { notify } from '../lib/toast';\nimport { useTechnoSpamAnalytics } from '../hooks/useTechnoSpamAnalytics';\nimport {\n FOCUSED_CARD_CLASS,\n focusableCardProps,\n useFocusedRecordParam,\n} from '../hooks/useFocusedRecordParam';\nimport { FOCUS_PARAMS } from '../utils/pageContext';\nimport { cn } from '../utils/cn';\n\nconst FALLBACK_LANGUAGES = ['javascript', 'python', 'typescript'];\n\n/**\n * A submission made while the grading sandbox is cold comes back PENDING and is\n * graded in the background (BOFF-4414). Poll the submissions list until the\n * verdict lands, giving up after a few minutes so a genuinely failed grade\n * falls back to the manual re-run button.\n */\nconst PENDING_POLL_INTERVAL_MS = 3_000;\nconst PENDING_POLL_MAX_MS = 3 * 60_000;\n\nfunction SubmissionRow({\n s,\n focused,\n onToggle,\n}: {\n s: TecSubmission;\n /** The focused submission (`?submissionId=`) is the one the assistant acts on. */\n focused: boolean;\n onToggle: () => void;\n}) {\n return (\n <div\n className={cn(\n 'cursor-pointer rounded-lg border border-transparent px-2 py-3 transition-colors hover:border-border-seam hover:bg-bg-sunken',\n focused && FOCUSED_CARD_CLASS\n )}\n {...focusableCardProps(focused, onToggle)}\n >\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1\">\n <button\n type=\"button\"\n aria-pressed={focused}\n aria-label={`Focus submission from ${formatDateTime(s.createdAt)}`}\n onClick={onToggle}\n className=\"rounded-full\"\n >\n <StatusBadge status={s.verdict} />\n </button>\n <span className=\"inline-flex items-center gap-1 text-sm font-medium text-text-primary\">\n <Code2 size={13} /> {humanizeEnum(s.language)}\n </span>\n <span className=\"inline-flex items-center gap-1 text-xs text-text-muted\">\n <Clock size={12} /> {s.runtimeMs} ms\n </span>\n <span className=\"inline-flex items-center gap-1 text-xs text-text-muted\">\n <Trophy size={12} /> {s.pointsAwarded} pts\n </span>\n <span className=\"ml-auto text-xs text-text-muted\">{formatDateTime(s.createdAt)}</span>\n </div>\n {s.totalCount > 0 ? (\n <p className=\"mt-1 px-0.5 text-xs text-text-muted\">\n Passed {s.passedCount} of {s.totalCount} test cases\n </p>\n ) : null}\n </div>\n );\n}\n\nexport function ApplicationsProblemDetailsPagePage() {\n const [params] = useSearchParams();\n const id = params.get('id') ?? '';\n // The focused submission lives in `?submissionId=` so the assistant's page\n // context names it (\"explain this submission\").\n const [focusedSubmissionId, setFocusedSubmissionId] = useFocusedRecordParam(\n FOCUS_PARAMS.submission\n );\n const { currentUser, workspaceId } = useTechnoSpam();\n const navigate = useTechnoSpamNavigate();\n const learnerId = currentUser?.id;\n const { emit } = useTechnoSpamAnalytics();\n\n const { data, loading, error, refetch } = useProblemQuery(id);\n\n useEffect(() => {\n if (id) {\n emit('technospam.problem.viewed', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n });\n }\n }, [id, workspaceId, emit]);\n const {\n data: subsData,\n loading: subsLoading,\n error: subsError,\n refetch: refetchSubs,\n } = useSubmissionsQuery({ ...(learnerId ? { learnerId } : {}), problemId: id });\n const [submit, { loading: submitting }] = useSubmitSolution();\n const [regrade, { loading: regrading }] = useRegradeSubmission();\n\n const problem = data?.tecProblem ?? null;\n\n const languages = useMemo(\n () => (problem?.languages?.length ? problem.languages : FALLBACK_LANGUAGES),\n [problem]\n );\n\n const [language, setLanguage] = useState('');\n const [code, setCode] = useState('');\n const initedRef = useRef(false);\n\n useEffect(() => {\n if (problem && !initedRef.current) {\n setLanguage(problem.languages[0] ?? FALLBACK_LANGUAGES[0]!);\n setCode(problem.starterCode ?? '');\n initedRef.current = true;\n }\n }, [problem]);\n\n const submissions = useMemo(\n () =>\n [...(subsData?.tecListSubmissions?.items ?? [])].sort(\n (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n ),\n [subsData]\n );\n\n const handleSubmit = async () => {\n if (!id) return;\n if (!language) {\n notify.error('Pick a language', 'Choose a language before submitting.');\n return;\n }\n if (!code.trim()) {\n notify.error('Add your solution', 'Write some code before submitting.');\n return;\n }\n emit('technospam.problem.submit_clicked', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n language,\n });\n const res = await submit({ variables: { input: { problemId: id, language, code } } });\n if (res.data?.tecSubmitSolution) {\n emit('technospam.problem.submitted', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n submissionId: res.data.tecSubmitSolution.id,\n });\n const graded = res.data.tecSubmitSolution;\n if (graded.verdict === 'PENDING') {\n notify.info(\n 'Solution submitted',\n 'Grading has started — your verdict will appear here in a moment.'\n );\n } else if (graded.verdict === 'ACCEPTED') {\n notify.success('Accepted', `Passed all ${graded.totalCount} test cases.`);\n } else {\n notify.error(\n humanizeEnum(graded.verdict),\n `Passed ${graded.passedCount} of ${graded.totalCount} test cases.`\n );\n }\n await Promise.all([refetch(), refetchSubs()]);\n }\n };\n\n const handleRegrade = async (submissionId: string) => {\n const res = await regrade({ variables: { id: submissionId } });\n const graded = res.data?.tecRegradeSubmission;\n if (!graded) return;\n if (graded.verdict === 'PENDING') {\n notify.error('Still pending', 'The grader is not available yet. Please try again shortly.');\n } else {\n notify.success('Grading complete', `Verdict: ${humanizeEnum(graded.verdict)}.`);\n }\n await Promise.all([refetch(), refetchSubs()]);\n };\n\n /** Most recent submission that actually carries grading detail. */\n const latestGraded = submissions.find((s) => (s.testResults?.length ?? 0) > 0) ?? null;\n const latestSubmission = submissions[0] ?? null;\n const pendingId = latestSubmission?.verdict === 'PENDING' ? latestSubmission.id : null;\n\n // Poll while the newest submission is still being graded in the background.\n const [pollExpiredFor, setPollExpiredFor] = useState<string | null>(null);\n const polling = pendingId !== null && pollExpiredFor !== pendingId;\n useEffect(() => {\n if (!pendingId || pollExpiredFor === pendingId) return undefined;\n const startedAt = Date.now();\n const timer = window.setInterval(() => {\n if (Date.now() - startedAt > PENDING_POLL_MAX_MS) {\n window.clearInterval(timer);\n setPollExpiredFor(pendingId);\n return;\n }\n void refetchSubs();\n }, PENDING_POLL_INTERVAL_MS);\n return () => window.clearInterval(timer);\n }, [pendingId, pollExpiredFor, refetchSubs]);\n\n // Announce the verdict once a background-graded submission settles.\n const awaitedIdRef = useRef<string | null>(null);\n useEffect(() => {\n if (pendingId) {\n awaitedIdRef.current = pendingId;\n return;\n }\n const awaitedId = awaitedIdRef.current;\n if (!awaitedId) return;\n const settled = submissions.find((s) => s.id === awaitedId);\n if (!settled || settled.verdict === 'PENDING') return;\n awaitedIdRef.current = null;\n if (settled.verdict === 'ACCEPTED') {\n notify.success('Accepted', `Passed all ${settled.totalCount} test cases.`);\n } else {\n notify.error(\n humanizeEnum(settled.verdict),\n `Passed ${settled.passedCount} of ${settled.totalCount} test cases.`\n );\n }\n void refetch();\n }, [pendingId, submissions, refetch]);\n\n if (loading && !problem) {\n return (\n <PageLayout title=\"Problem\" backPath=\"/applications/problems-page\">\n <Skeleton className=\"mb-4 h-28 w-full rounded-xl\" />\n <Skeleton className=\"h-72 w-full rounded-xl\" />\n </PageLayout>\n );\n }\n\n if (error || !problem) {\n return (\n <PageLayout title=\"Problem\" backPath=\"/applications/problems-page\">\n {error ? (\n <ErrorView title=\"Couldn't load problem\" error={error} />\n ) : (\n <EmptyView\n title=\"Problem not found\"\n description=\"This problem may have been unpublished.\"\n />\n )}\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n hero\n backPath=\"/applications/problems-page\"\n title={problem.title}\n description={problem.topic ?? undefined}\n >\n <div className=\"mb-5 flex flex-wrap items-center gap-2\">\n <StatusBadge status={problem.difficulty} kind=\"level\" />\n <StatusBadge status={problem.status} />\n {problem.topic ? (\n <Badge variant=\"outline\" className=\"gap-1\">\n <Layers size={12} /> {problem.topic}\n </Badge>\n ) : null}\n {problem.isPremiumOnly ? <PremiumBadge locked={problem.isLocked} /> : null}\n <TagStrip tags={problem.tags} />\n </div>\n\n <div className=\"mb-6 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <StatCard label=\"Points\" value={problem.points} icon={Trophy} tone=\"amber\" />\n <StatCard label=\"Languages\" value={languages.length} icon={Code2} tone=\"blue\" />\n <StatCard\n label=\"Difficulty\"\n value={humanizeEnum(problem.difficulty)}\n icon={Layers}\n tone=\"purple\"\n />\n <StatCard label=\"My submissions\" value={submissions.length} icon={FileText} tone=\"teal\" />\n </div>\n\n <div className=\"grid grid-cols-1 gap-5 lg:grid-cols-3\">\n <div className=\"space-y-5 lg:col-span-2\">\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-2 text-base font-semibold text-text-primary\">Problem statement</h2>\n {problem.isLocked ? (\n // BOFF-4416: the API already nulled `statement` for a locked\n // premium problem — this explains why, rather than showing the\n // generic \"being prepared\" message used for a real content gap.\n <UpgradeGate description=\"This problem's statement is part of a paid TechnoSpam plan. Ask a workspace admin to upgrade to unlock it.\" />\n ) : problem.statement ? (\n <p className=\"whitespace-pre-wrap text-sm leading-relaxed text-text-secondary\">\n {problem.statement}\n </p>\n ) : (\n <p className=\"py-4 text-center text-sm text-text-muted\">\n The statement for this problem is being prepared.\n </p>\n )}\n </GlassCard>\n\n {problem.isLocked ? (\n <UpgradeGate\n compact\n description=\"Starter code and sample test cases unlock with a paid TechnoSpam plan.\"\n />\n ) : problem.starterCode ? (\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 text-base font-semibold text-text-primary\">Starter code</h2>\n <CodePanel label={humanizeEnum(languages[0] ?? 'code')} bodyClassName=\"max-h-72\">\n {problem.starterCode}\n </CodePanel>\n </GlassCard>\n ) : null}\n\n <GlassCard className=\"p-5\">\n <div className=\"mb-3 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n <h2 className=\"text-base font-semibold text-text-primary\">Submit a solution</h2>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-text-secondary\">Language</span>\n <Select value={language} onValueChange={setLanguage}>\n <SelectTrigger className=\"w-full sm:w-48\" aria-label=\"Language\">\n <SelectValue placeholder=\"Choose a language\" />\n </SelectTrigger>\n <SelectContent>\n {languages.map((l) => (\n <SelectItem key={l} value={l}>\n {humanizeEnum(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"overflow-hidden rounded-xl border border-border-strong bg-bg-sunken shadow-sm\">\n <div className=\"flex items-center justify-between gap-2 border-b border-border-seam bg-bg-canvas/40 px-4 py-2\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-error-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-warning-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-success-border\" />\n </div>\n <span className=\"inline-flex items-center gap-1.5 font-mono text-xs text-text-secondary\">\n <Code2 size={13} /> {language ? humanizeEnum(language) : 'solution'}\n </span>\n </div>\n <Textarea\n value={code}\n onChange={(e) => setCode(e.target.value)}\n placeholder=\"Write your solution…\"\n className=\"min-h-[280px] resize-y rounded-none border-0 bg-transparent font-mono text-xs leading-relaxed focus-visible:ring-0 focus-visible:ring-offset-0\"\n spellCheck={false}\n />\n </div>\n\n <Button\n className=\"mt-4 w-full\"\n onClick={handleSubmit}\n disabled={submitting || !code.trim()}\n >\n <Send size={16} /> {submitting ? 'Running test cases…' : 'Run & submit'}\n </Button>\n <p className=\"mt-2 text-center text-xs text-text-muted\">\n Your code runs against this problem's test cases in an isolated sandbox.\n </p>\n </GlassCard>\n\n {problem.publicTestCases?.length ? (\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-1 flex items-center gap-2 text-base font-semibold text-text-primary\">\n <FlaskConical size={16} /> Sample test cases\n </h2>\n <p className=\"mb-3 text-sm text-text-secondary\">\n Your solution reads each input from stdin and must print the expected output. Hidden\n test cases are also run when you submit.\n </p>\n <div className=\"space-y-3\">\n {problem.publicTestCases.map((testCase) => (\n <div key={testCase.id} className=\"rounded-xl border border-border-seam p-3\">\n <div className=\"mb-2 flex flex-wrap items-center gap-x-3 gap-y-1\">\n <span className=\"text-sm font-medium text-text-primary\">{testCase.name}</span>\n <span className=\"inline-flex items-center gap-1 text-xs text-text-muted\">\n <Clock size={12} /> {testCase.timeLimitMs} ms limit\n </span>\n </div>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <IoBlock label=\"Input\" value={testCase.input} />\n <IoBlock label=\"Expected output\" value={testCase.expectedOutput} />\n </div>\n </div>\n ))}\n </div>\n </GlassCard>\n ) : null}\n\n {pendingId ? (\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-2 text-base font-semibold text-text-primary\">Latest run</h2>\n {polling ? (\n <p className=\"mb-3 inline-flex items-center gap-2 text-sm text-text-secondary\">\n <RefreshCw size={14} className=\"animate-spin\" />\n Grading your submission — the grader is starting up. Your verdict will appear here\n automatically.\n </p>\n ) : (\n <p className=\"mb-3 text-sm text-text-secondary\">\n Your most recent submission has not been graded yet — the grader was unavailable.\n You can re-run it without resubmitting your code.\n </p>\n )}\n <Button\n variant=\"outline\"\n onClick={() => void handleRegrade(pendingId)}\n disabled={regrading}\n >\n <RefreshCw size={16} /> {regrading ? 'Re-running…' : 'Re-run grader'}\n </Button>\n </GlassCard>\n ) : latestGraded ? (\n <>\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 text-base font-semibold text-text-primary\">Latest run</h2>\n <TestResultsPanel submission={latestGraded} />\n </GlassCard>\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 flex items-center gap-2 text-base font-semibold text-text-primary\">\n <Sparkles size={16} /> TechnoSage review\n </h2>\n <SubmissionReviewPanel\n submission={latestGraded}\n onOpenProblem={(problemId) =>\n navigate(`/applications/problem-details-page?id=${problemId}`)\n }\n />\n </GlassCard>\n </>\n ) : null}\n </div>\n\n <div className=\"lg:col-span-1\">\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 text-base font-semibold text-text-primary\">My submissions</h2>\n {subsLoading && !submissions.length ? (\n <LoadingRows count={3} height=\"h-12\" />\n ) : subsError ? (\n <ErrorView title=\"Couldn't load submissions\" error={subsError} />\n ) : submissions.length === 0 ? (\n <EmptyView\n icon={<FileText size={24} />}\n title=\"No submissions yet\"\n description=\"Submit a solution above to see your verdicts and points here.\"\n />\n ) : (\n <div className=\"space-y-1\">\n {submissions.map((s) => (\n <SubmissionRow\n key={s.id}\n s={s}\n focused={focusedSubmissionId === s.id}\n onToggle={() =>\n setFocusedSubmissionId(focusedSubmissionId === s.id ? null : s.id)\n }\n />\n ))}\n </div>\n )}\n </GlassCard>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ApplicationsProblemDetailsPagePage.js","names":[],"sources":["../../../src/technospam/pages/ApplicationsProblemDetailsPagePage.tsx"],"sourcesContent":["import { Suspense, lazy, useEffect, useMemo, useRef, useState } from 'react';\nimport { useSearchParams } from 'react-router';\nimport {\n Clock,\n Code2,\n FileText,\n FlaskConical,\n BookOpen,\n Layers,\n Play,\n RefreshCw,\n RotateCcw,\n Send,\n Terminal,\n Sparkles,\n Trophy,\n} from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Skeleton,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport {\n CodePanel,\n EmptyView,\n ErrorView,\n IoBlock,\n LoadingRows,\n PageLayout,\n PremiumBadge,\n StatCard,\n StatusBadge,\n SubmissionReviewPanel,\n TagStrip,\n TestResultsPanel,\n TechnoSpamErrorBoundary,\n UpgradeGate,\n} from '../components';\nimport { useTechnoSpam, useTechnoSpamNavigate } from '../providers/TechnoSpamProvider';\nimport {\n useProblemQuery,\n useRegradeSubmission,\n useSubmissionsQuery,\n useSubmitSolution,\n type TecSubmission,\n} from '../api/technospamApi';\nimport { formatDateTime, humanizeEnum } from '../utils/format';\nimport { notify } from '../lib/toast';\nimport { useTechnoSpamAnalytics } from '../hooks/useTechnoSpamAnalytics';\nimport { useSolutionRunner } from '../hooks/useSolutionRunner';\nimport { RunOutputPanel } from '../components/editor/RunOutputPanel';\nimport {\n FOCUSED_CARD_CLASS,\n focusableCardProps,\n useFocusedRecordParam,\n} from '../hooks/useFocusedRecordParam';\nimport { FOCUS_PARAMS } from '../utils/pageContext';\nimport { cn } from '../utils/cn';\n\nconst FALLBACK_LANGUAGES = ['javascript', 'python', 'typescript'];\n\n/**\n * The CodeMirror editor is the heaviest part of this page, so it loads as its\n * own chunk; the textarea-sized skeleton holds its place meanwhile.\n */\nconst CodeEditor = lazy(() => import('../components/editor/CodeEditor'));\n\n/** Which half of the page is visible below the `lg` breakpoint (mock 22). */\ntype MobilePane = 'description' | 'solution';\n\n/**\n * A submission made while the grading sandbox is cold comes back PENDING and is\n * graded in the background (BOFF-4414). Poll the submissions list until the\n * verdict lands, giving up after a few minutes so a genuinely failed grade\n * falls back to the manual re-run button.\n */\nconst PENDING_POLL_INTERVAL_MS = 3_000;\nconst PENDING_POLL_MAX_MS = 3 * 60_000;\n\nfunction SubmissionRow({\n s,\n focused,\n onToggle,\n}: {\n s: TecSubmission;\n /** The focused submission (`?submissionId=`) is the one the assistant acts on. */\n focused: boolean;\n onToggle: () => void;\n}) {\n return (\n <div\n className={cn(\n 'cursor-pointer rounded-lg border border-transparent px-2 py-3 transition-colors hover:border-border-seam hover:bg-bg-sunken',\n focused && FOCUSED_CARD_CLASS\n )}\n {...focusableCardProps(focused, onToggle)}\n >\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1\">\n <button\n type=\"button\"\n aria-pressed={focused}\n aria-label={`Focus submission from ${formatDateTime(s.createdAt)}`}\n onClick={onToggle}\n className=\"rounded-full\"\n >\n <StatusBadge status={s.verdict} />\n </button>\n <span className=\"inline-flex items-center gap-1 text-sm font-medium text-text-primary\">\n <Code2 size={13} /> {humanizeEnum(s.language)}\n </span>\n <span className=\"inline-flex items-center gap-1 text-xs text-text-muted\">\n <Clock size={12} /> {s.runtimeMs} ms\n </span>\n <span className=\"inline-flex items-center gap-1 text-xs text-text-muted\">\n <Trophy size={12} /> {s.pointsAwarded} pts\n </span>\n <span className=\"ml-auto text-xs text-text-muted\">{formatDateTime(s.createdAt)}</span>\n </div>\n {s.totalCount > 0 ? (\n <p className=\"mt-1 px-0.5 text-xs text-text-muted\">\n Passed {s.passedCount} of {s.totalCount} test cases\n </p>\n ) : null}\n </div>\n );\n}\n\nexport function ApplicationsProblemDetailsPagePage() {\n const [params] = useSearchParams();\n const id = params.get('id') ?? '';\n // The focused submission lives in `?submissionId=` so the assistant's page\n // context names it (\"explain this submission\").\n const [focusedSubmissionId, setFocusedSubmissionId] = useFocusedRecordParam(\n FOCUS_PARAMS.submission\n );\n const { currentUser, workspaceId } = useTechnoSpam();\n const navigate = useTechnoSpamNavigate();\n const learnerId = currentUser?.id;\n const { emit } = useTechnoSpamAnalytics();\n\n const { data, loading, error, refetch } = useProblemQuery(id);\n\n useEffect(() => {\n if (id) {\n emit('technospam.problem.viewed', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n });\n }\n }, [id, workspaceId, emit]);\n const {\n data: subsData,\n loading: subsLoading,\n error: subsError,\n refetch: refetchSubs,\n } = useSubmissionsQuery({ ...(learnerId ? { learnerId } : {}), problemId: id });\n const [submit, { loading: submitting }] = useSubmitSolution();\n const [regrade, { loading: regrading }] = useRegradeSubmission();\n\n const problem = data?.tecProblem ?? null;\n\n const languages = useMemo(\n () => (problem?.languages?.length ? problem.languages : FALLBACK_LANGUAGES),\n [problem]\n );\n\n const [language, setLanguage] = useState('');\n const [code, setCode] = useState('');\n const [useCustomInput, setUseCustomInput] = useState(false);\n const [customInput, setCustomInput] = useState('');\n const [mobilePane, setMobilePane] = useState<MobilePane>('description');\n const runner = useSolutionRunner();\n // The id of the problem the editor state was initialised for. Navigating to\n // another problem (?id= changes without unmounting) must re-seed the language,\n // starter code and custom input, and drop the previous problem's run output.\n const initedForRef = useRef<string | null>(null);\n const resetRunner = runner.reset;\n\n useEffect(() => {\n if (problem && initedForRef.current !== problem.id) {\n setLanguage(problem.languages[0] ?? FALLBACK_LANGUAGES[0]!);\n setCode(problem.starterCode ?? '');\n setCustomInput(problem.publicTestCases?.[0]?.input ?? '');\n setUseCustomInput(false);\n resetRunner();\n initedForRef.current = problem.id;\n }\n }, [problem, resetRunner]);\n\n const handleLanguageChange = (next: string) => {\n setLanguage(next);\n // Run output belongs to the language it was produced with.\n runner.reset();\n };\n\n const submissions = useMemo(\n () =>\n [...(subsData?.tecListSubmissions?.items ?? [])].sort(\n (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n ),\n [subsData]\n );\n\n const handleRun = () => {\n if (!id || runner.running || runner.warming || problem?.isLocked) return;\n if (!language) {\n notify.error('Pick a language', 'Choose a language before running your code.');\n return;\n }\n if (!code.trim()) {\n notify.error('Add your solution', 'Write some code before running it.');\n return;\n }\n emit('technospam.problem.run_clicked', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n language,\n customInput: useCustomInput,\n });\n runner.execute({\n problemId: id,\n language,\n code,\n stdin: useCustomInput ? customInput : null,\n });\n };\n\n const handleResetCode = () => {\n setCode(problem?.starterCode ?? '');\n runner.reset();\n };\n\n const handleSubmit = async () => {\n if (!id || submitting || problem?.isLocked) return;\n if (!language) {\n notify.error('Pick a language', 'Choose a language before submitting.');\n return;\n }\n if (!code.trim()) {\n notify.error('Add your solution', 'Write some code before submitting.');\n return;\n }\n emit('technospam.problem.submit_clicked', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n language,\n });\n const res = await submit({ variables: { input: { problemId: id, language, code } } });\n if (res.data?.tecSubmitSolution) {\n emit('technospam.problem.submitted', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n submissionId: res.data.tecSubmitSolution.id,\n });\n const graded = res.data.tecSubmitSolution;\n if (graded.verdict === 'PENDING') {\n notify.info(\n 'Solution submitted',\n 'Grading has started — your verdict will appear here in a moment.'\n );\n } else if (graded.verdict === 'ACCEPTED') {\n notify.success('Accepted', `Passed all ${graded.totalCount} test cases.`);\n } else {\n notify.error(\n humanizeEnum(graded.verdict),\n `Passed ${graded.passedCount} of ${graded.totalCount} test cases.`\n );\n }\n await Promise.all([refetch(), refetchSubs()]);\n }\n };\n\n const handleRegrade = async (submissionId: string) => {\n const res = await regrade({ variables: { id: submissionId } });\n const graded = res.data?.tecRegradeSubmission;\n if (!graded) return;\n if (graded.verdict === 'PENDING') {\n notify.error('Still pending', 'The grader is not available yet. Please try again shortly.');\n } else {\n notify.success('Grading complete', `Verdict: ${humanizeEnum(graded.verdict)}.`);\n }\n await Promise.all([refetch(), refetchSubs()]);\n };\n\n /** Most recent submission that actually carries grading detail. */\n const latestGraded = submissions.find((s) => (s.testResults?.length ?? 0) > 0) ?? null;\n const latestSubmission = submissions[0] ?? null;\n const pendingId = latestSubmission?.verdict === 'PENDING' ? latestSubmission.id : null;\n\n // Poll while the newest submission is still being graded in the background.\n const [pollExpiredFor, setPollExpiredFor] = useState<string | null>(null);\n const polling = pendingId !== null && pollExpiredFor !== pendingId;\n useEffect(() => {\n if (!pendingId || pollExpiredFor === pendingId) return undefined;\n const startedAt = Date.now();\n const timer = window.setInterval(() => {\n if (Date.now() - startedAt > PENDING_POLL_MAX_MS) {\n window.clearInterval(timer);\n setPollExpiredFor(pendingId);\n return;\n }\n void refetchSubs();\n }, PENDING_POLL_INTERVAL_MS);\n return () => window.clearInterval(timer);\n }, [pendingId, pollExpiredFor, refetchSubs]);\n\n // Announce the verdict once a background-graded submission settles.\n const awaitedIdRef = useRef<string | null>(null);\n useEffect(() => {\n if (pendingId) {\n awaitedIdRef.current = pendingId;\n return;\n }\n const awaitedId = awaitedIdRef.current;\n if (!awaitedId) return;\n const settled = submissions.find((s) => s.id === awaitedId);\n if (!settled || settled.verdict === 'PENDING') return;\n awaitedIdRef.current = null;\n if (settled.verdict === 'ACCEPTED') {\n notify.success('Accepted', `Passed all ${settled.totalCount} test cases.`);\n } else {\n notify.error(\n humanizeEnum(settled.verdict),\n `Passed ${settled.passedCount} of ${settled.totalCount} test cases.`\n );\n }\n void refetch();\n }, [pendingId, submissions, refetch]);\n\n if (loading && !problem) {\n return (\n <PageLayout title=\"Problem\" backPath=\"/applications/problems-page\">\n <Skeleton className=\"mb-4 h-28 w-full rounded-xl\" />\n <Skeleton className=\"h-72 w-full rounded-xl\" />\n </PageLayout>\n );\n }\n\n if (error || !problem) {\n return (\n <PageLayout title=\"Problem\" backPath=\"/applications/problems-page\">\n {error ? (\n <ErrorView title=\"Couldn't load problem\" error={error} />\n ) : (\n <EmptyView\n title=\"Problem not found\"\n description=\"This problem may have been unpublished.\"\n />\n )}\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n hero\n backPath=\"/applications/problems-page\"\n title={problem.title}\n description={problem.topic ?? undefined}\n >\n <div className=\"mb-5 flex flex-wrap items-center gap-2\">\n <StatusBadge status={problem.difficulty} kind=\"level\" />\n <StatusBadge status={problem.status} />\n {problem.topic ? (\n <Badge variant=\"outline\" className=\"gap-1\">\n <Layers size={12} /> {problem.topic}\n </Badge>\n ) : null}\n {problem.isPremiumOnly ? <PremiumBadge locked={problem.isLocked} /> : null}\n <TagStrip tags={problem.tags} />\n </div>\n\n <div className=\"mb-6 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <StatCard label=\"Points\" value={problem.points} icon={Trophy} tone=\"amber\" />\n <StatCard label=\"Languages\" value={languages.length} icon={Code2} tone=\"blue\" />\n <StatCard\n label=\"Difficulty\"\n value={humanizeEnum(problem.difficulty)}\n icon={Layers}\n tone=\"purple\"\n />\n <StatCard label=\"My submissions\" value={submissions.length} icon={FileText} tone=\"teal\" />\n </div>\n\n {/* Below lg the page is two tabs (mock 22); at lg both panes sit side by side. */}\n <div\n role=\"tablist\"\n aria-label=\"Problem sections\"\n className=\"mb-4 grid grid-cols-2 gap-1 rounded-xl border border-border-seam bg-bg-sunken p-1 lg:hidden\"\n >\n {(\n [\n { pane: 'description', label: 'Description', icon: BookOpen },\n { pane: 'solution', label: 'Solution', icon: Code2 },\n ] as const\n ).map(({ pane, label, icon: Icon }) => (\n <button\n key={pane}\n type=\"button\"\n role=\"tab\"\n id={`problem-tab-${pane}`}\n aria-selected={mobilePane === pane}\n aria-controls={`problem-pane-${pane}`}\n onClick={() => setMobilePane(pane)}\n className={cn(\n 'inline-flex items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus',\n mobilePane === pane\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n )}\n >\n <Icon size={14} /> {label}\n </button>\n ))}\n </div>\n\n <div className=\"grid grid-cols-1 gap-5 lg:grid-cols-2\">\n <div\n id=\"problem-pane-description\"\n role=\"tabpanel\"\n aria-labelledby=\"problem-tab-description\"\n className={cn('min-w-0 space-y-5', mobilePane !== 'description' && 'hidden lg:block')}\n >\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-2 text-base font-semibold text-text-primary\">Problem statement</h2>\n {problem.isLocked ? (\n // BOFF-4416: the API already nulled `statement` for a locked\n // premium problem — this explains why, rather than showing the\n // generic \"being prepared\" message used for a real content gap.\n <UpgradeGate description=\"This problem's statement is part of a paid TechnoSpam plan. Ask a workspace admin to upgrade to unlock it.\" />\n ) : problem.statement ? (\n <p className=\"whitespace-pre-wrap text-sm leading-relaxed text-text-secondary\">\n {problem.statement}\n </p>\n ) : (\n <p className=\"py-4 text-center text-sm text-text-muted\">\n The statement for this problem is being prepared.\n </p>\n )}\n </GlassCard>\n\n {problem.isLocked ? (\n <UpgradeGate\n compact\n description=\"Starter code and sample test cases unlock with a paid TechnoSpam plan.\"\n />\n ) : null}\n\n {problem.publicTestCases?.length ? (\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-1 flex items-center gap-2 text-base font-semibold text-text-primary\">\n <FlaskConical size={16} /> Sample test cases\n </h2>\n <p className=\"mb-3 text-sm text-text-secondary\">\n Your solution reads each input from stdin and must print the expected output.\n <strong className=\"font-medium text-text-primary\"> Run</strong> checks these\n samples; <strong className=\"font-medium text-text-primary\">Submit</strong> also runs\n the hidden test cases.\n </p>\n <div className=\"space-y-3\">\n {problem.publicTestCases.map((testCase) => (\n <div key={testCase.id} className=\"rounded-xl border border-border-seam p-3\">\n <div className=\"mb-2 flex flex-wrap items-center gap-x-3 gap-y-1\">\n <span className=\"text-sm font-medium text-text-primary\">{testCase.name}</span>\n <span className=\"inline-flex items-center gap-1 text-xs text-text-muted\">\n <Clock size={12} /> {testCase.timeLimitMs} ms limit\n </span>\n </div>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <IoBlock label=\"Input\" value={testCase.input} />\n <IoBlock label=\"Expected output\" value={testCase.expectedOutput} />\n </div>\n </div>\n ))}\n </div>\n </GlassCard>\n ) : null}\n\n {!problem.isLocked && problem.starterCode ? (\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 text-base font-semibold text-text-primary\">Starter code</h2>\n <CodePanel label={humanizeEnum(languages[0] ?? 'code')} bodyClassName=\"max-h-72\">\n {problem.starterCode}\n </CodePanel>\n </GlassCard>\n ) : null}\n </div>\n\n <div\n id=\"problem-pane-solution\"\n role=\"tabpanel\"\n aria-labelledby=\"problem-tab-solution\"\n className={cn('min-w-0 space-y-5', mobilePane !== 'solution' && 'hidden lg:block')}\n >\n <GlassCard className=\"p-5\">\n <div className=\"mb-3 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n <h2 className=\"inline-flex items-center gap-2 text-base font-semibold text-text-primary\">\n <Code2 size={16} /> Solve\n </h2>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-text-secondary\">Language</span>\n <Select value={language} onValueChange={handleLanguageChange}>\n <SelectTrigger className=\"w-full sm:w-44\" aria-label=\"Language\">\n <SelectValue placeholder=\"Choose a language\" />\n </SelectTrigger>\n <SelectContent>\n {languages.map((l) => (\n <SelectItem key={l} value={l}>\n {humanizeEnum(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleResetCode}\n aria-label=\"Reset to starter code\"\n title=\"Reset to starter code\"\n >\n <RotateCcw size={16} />\n </Button>\n </div>\n </div>\n\n <div className=\"overflow-hidden rounded-xl border border-border-strong bg-bg-sunken shadow-sm focus-within:ring-2 focus-within:ring-border-focus\">\n <div className=\"flex items-center justify-between gap-2 border-b border-border-seam bg-bg-canvas/40 px-4 py-2\">\n <div className=\"flex items-center gap-1.5\" aria-hidden=\"true\">\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-error-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-warning-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-success-border\" />\n </div>\n <span className=\"inline-flex items-center gap-1.5 font-mono text-xs text-text-secondary\">\n <Code2 size={13} /> {language ? humanizeEnum(language) : 'solution'}\n </span>\n </div>\n <TechnoSpamErrorBoundary\n fallback={\n // The editor chunk failed to load (flaky network, or a deploy\n // replaced it). A plain textarea keeps the learner working.\n <Textarea\n value={code}\n onChange={(e) => setCode(e.target.value)}\n aria-label={`Solution code${language ? ` (${humanizeEnum(language)})` : ''}`}\n placeholder=\"Write your solution…\"\n spellCheck={false}\n className=\"h-[360px] resize-none rounded-none border-0 font-mono text-xs lg:h-[440px]\"\n />\n }\n >\n <Suspense\n fallback={<Skeleton className=\"h-[360px] w-full rounded-none lg:h-[440px]\" />}\n >\n <CodeEditor\n value={code}\n onChange={setCode}\n language={language}\n ariaLabel={`Solution code${language ? ` (${humanizeEnum(language)})` : ''}`}\n placeholder=\"Write your solution…\"\n onRun={handleRun}\n onSubmit={() => void handleSubmit()}\n className=\"h-[360px] text-xs lg:h-[440px]\"\n />\n </Suspense>\n </TechnoSpamErrorBoundary>\n </div>\n\n <div className=\"mt-3\">\n <label className=\"inline-flex cursor-pointer items-center gap-2 text-sm text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={useCustomInput}\n onChange={(e) => setUseCustomInput(e.target.checked)}\n className=\"h-4 w-4 rounded border-border-strong accent-current\"\n />\n <Terminal size={14} /> Run with custom input\n </label>\n {useCustomInput ? (\n <Textarea\n value={customInput}\n onChange={(e) => setCustomInput(e.target.value)}\n aria-label=\"Custom input (stdin)\"\n placeholder=\"Input passed to your program on stdin\"\n className=\"mt-2 min-h-[88px] font-mono text-xs\"\n spellCheck={false}\n />\n ) : null}\n </div>\n\n <div className=\"mt-4 grid grid-cols-2 gap-2\">\n <Button\n variant=\"outline\"\n onClick={handleRun}\n disabled={\n runner.running || runner.warming || !code.trim() || Boolean(problem.isLocked)\n }\n >\n <Play size={16} />{' '}\n {runner.warming ? 'Starting…' : runner.running ? 'Running…' : 'Run'}\n </Button>\n <Button\n onClick={() => void handleSubmit()}\n disabled={submitting || !code.trim() || Boolean(problem.isLocked)}\n >\n <Send size={16} /> {submitting ? 'Submitting…' : 'Submit'}\n </Button>\n </div>\n <p className=\"mt-2 text-center text-xs text-text-muted\">\n Code runs in an isolated sandbox. Ctrl/⌘+Enter runs, Ctrl/⌘+Shift+Enter submits; press\n Esc then Tab to leave the editor.\n </p>\n </GlassCard>\n\n <GlassCard className=\"p-5\" aria-live=\"polite\">\n <h2 className=\"mb-3 flex items-center gap-2 text-base font-semibold text-text-primary\">\n <Terminal size={16} /> Run output\n </h2>\n <RunOutputPanel\n run={runner.run}\n running={runner.running}\n warming={runner.warming}\n error={runner.error}\n />\n </GlassCard>\n\n {pendingId ? (\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-2 text-base font-semibold text-text-primary\">Latest submission</h2>\n {polling ? (\n <p className=\"mb-3 inline-flex items-center gap-2 text-sm text-text-secondary\">\n <RefreshCw size={14} className=\"animate-spin\" />\n Grading your submission — the grader is starting up. Your verdict will appear here\n automatically.\n </p>\n ) : (\n <p className=\"mb-3 text-sm text-text-secondary\">\n Your most recent submission has not been graded yet — the grader was unavailable.\n You can re-run it without resubmitting your code.\n </p>\n )}\n <Button\n variant=\"outline\"\n onClick={() => void handleRegrade(pendingId)}\n disabled={regrading}\n >\n <RefreshCw size={16} /> {regrading ? 'Re-running…' : 'Re-run grader'}\n </Button>\n </GlassCard>\n ) : latestGraded ? (\n <>\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 text-base font-semibold text-text-primary\">\n Latest submission\n </h2>\n <TestResultsPanel submission={latestGraded} />\n </GlassCard>\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 flex items-center gap-2 text-base font-semibold text-text-primary\">\n <Sparkles size={16} /> TechnoSage review\n </h2>\n <SubmissionReviewPanel\n submission={latestGraded}\n onOpenProblem={(problemId) =>\n navigate(`/applications/problem-details-page?id=${problemId}`)\n }\n />\n </GlassCard>\n </>\n ) : null}\n\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 text-base font-semibold text-text-primary\">My submissions</h2>\n {subsLoading && !submissions.length ? (\n <LoadingRows count={3} height=\"h-12\" />\n ) : subsError ? (\n <ErrorView title=\"Couldn't load submissions\" error={subsError} />\n ) : submissions.length === 0 ? (\n <EmptyView\n icon={<FileText size={24} />}\n title=\"No submissions yet\"\n description=\"Submit a solution to see your verdicts and points here.\"\n />\n ) : (\n <div className=\"space-y-1\">\n {submissions.map((s) => (\n <SubmissionRow\n key={s.id}\n s={s}\n focused={focusedSubmissionId === s.id}\n onToggle={() =>\n setFocusedSubmissionId(focusedSubmissionId === s.id ? null : s.id)\n }\n />\n ))}\n </div>\n )}\n </GlassCard>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-technospam",
|
|
3
|
-
"version": "2026.1102.
|
|
3
|
+
"version": "2026.1102.2",
|
|
4
4
|
"description": "Burdenoff TechnoSpam Microfrontend",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -52,17 +52,27 @@
|
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@apollo/client": "^4.0.11",
|
|
54
54
|
"@burdenoff/fe-libs": "2026.801.1",
|
|
55
|
+
"@codemirror/autocomplete": "6.20.3",
|
|
56
|
+
"@codemirror/commands": "6.11.1",
|
|
57
|
+
"@codemirror/lang-go": "6.0.1",
|
|
58
|
+
"@codemirror/lang-javascript": "6.2.5",
|
|
59
|
+
"@codemirror/lang-python": "6.2.1",
|
|
60
|
+
"@codemirror/language": "6.13.1",
|
|
61
|
+
"@codemirror/legacy-modes": "6.5.5",
|
|
62
|
+
"@codemirror/state": "6.7.6",
|
|
63
|
+
"@codemirror/view": "6.43.14",
|
|
64
|
+
"@lezer/highlight": "1.2.5",
|
|
55
65
|
"@tanstack/react-query": "^5.90.16",
|
|
56
66
|
"clsx": "^2.1.1",
|
|
67
|
+
"framer-motion": "^12.0.0",
|
|
57
68
|
"graphql": "^16.10.0",
|
|
58
69
|
"lucide-react": "^0.468.0",
|
|
59
70
|
"react": "^19.0.0",
|
|
60
71
|
"react-dom": "^19.0.0",
|
|
61
72
|
"react-router": "^8.3.0",
|
|
62
|
-
"tailwind-merge": "^3.4.0",
|
|
63
|
-
"zustand": "^5.0.3",
|
|
64
73
|
"recharts": "^2.15.0",
|
|
65
|
-
"
|
|
74
|
+
"tailwind-merge": "^3.4.0",
|
|
75
|
+
"zustand": "^5.0.3"
|
|
66
76
|
},
|
|
67
77
|
"devDependencies": {
|
|
68
78
|
"@axe-core/playwright": "4.11.0",
|