diff --git a/src/AppRoutes.admin.test.tsx b/src/AppRoutes.admin.test.tsx
index a4346e5..d7ea7f3 100644
--- a/src/AppRoutes.admin.test.tsx
+++ b/src/AppRoutes.admin.test.tsx
@@ -35,6 +35,7 @@ vi.mock('./pages/exam', () => ({ ExamDashboardPage: () =>
Exam Marker
vi.mock('./pages/user/calendarPage', () => ({ default: () => Calendar
}));
vi.mock('./pages/user/settingsPage', () => ({ default: () => Settings
}));
vi.mock('./pages/tldraw/devPlayerPage', () => ({ default: () => TLDraw Dev
}));
+vi.mock('./pages/tldraw/ExamMarkerSpikePage', () => ({ default: () => Exam Marker Spike
}));
vi.mock('./pages/tldraw/devPage', () => ({ default: () => Dev
}));
vi.mock('./pages/react-flow/teacherPlanner', () => ({ default: () => Teacher Planner
}));
vi.mock('./pages/morphicPage', () => ({ default: () => Morphic
}));
diff --git a/src/AppRoutes.tsx b/src/AppRoutes.tsx
index f091bfb..93da209 100644
--- a/src/AppRoutes.tsx
+++ b/src/AppRoutes.tsx
@@ -16,6 +16,7 @@ import AdminDashboard from './pages/auth/adminPage';
import PlatformAdminPage from './pages/auth/PlatformAdminPage';
import TLDrawDevPage from './pages/tldraw/devPlayerPage';
import DevPage from './pages/tldraw/devPage';
+import ExamMarkerSpikePage from './pages/tldraw/ExamMarkerSpikePage';
import TeacherPlanner from './pages/react-flow/teacherPlanner';
import MorphicPage from './pages/morphicPage';
import NotFound from './pages/user/NotFound';
@@ -186,6 +187,7 @@ const AppRoutes: React.FC = () => {
} />
} />
} />
+ } />
} />
} />
} />
diff --git a/src/pages/exam/ExamDashboardPage.tsx b/src/pages/exam/ExamDashboardPage.tsx
index 500c45f..c3b339a 100644
--- a/src/pages/exam/ExamDashboardPage.tsx
+++ b/src/pages/exam/ExamDashboardPage.tsx
@@ -46,6 +46,7 @@ const ExamDashboardPage: React.FC = () => {
const [createOpen, setCreateOpen] = useState(false);
const [title, setTitle] = useState('');
const [subject, setSubject] = useState('');
+ const [sourcePdf, setSourcePdf] = useState(null);
const [saving, setSaving] = useState(false);
const load = useCallback(async () => {
@@ -66,6 +67,18 @@ const ExamDashboardPage: React.FC = () => {
void load();
}, [load, instituteId]);
+ const handleOpenCreate = () => {
+ setCreateOpen(true);
+ };
+
+ const handleCloseCreate = () => {
+ if (saving) return;
+ setCreateOpen(false);
+ setTitle('');
+ setSubject('');
+ setSourcePdf(null);
+ };
+
const handleCreate = async () => {
if (!title.trim()) return;
setSaving(true);
@@ -74,10 +87,12 @@ const ExamDashboardPage: React.FC = () => {
title: title.trim(),
subject: subject.trim() || undefined,
institute_id: instituteId,
+ source_pdf: sourcePdf,
});
setCreateOpen(false);
setTitle('');
setSubject('');
+ setSourcePdf(null);
navigate(`/exam-marker/${created.id}/setup`);
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
@@ -112,7 +127,7 @@ const ExamDashboardPage: React.FC = () => {
Build a template for an exam paper, then run marking batches against your classes.
- } onClick={() => setCreateOpen(true)}>
+ } onClick={handleOpenCreate}>
New template
@@ -134,7 +149,7 @@ const ExamDashboardPage: React.FC = () => {
Create your first template to start mapping an exam paper.
- } onClick={() => setCreateOpen(true)}>
+ } onClick={handleOpenCreate}>
New template
@@ -144,8 +159,16 @@ const ExamDashboardPage: React.FC = () => {
navigate(`/exam-marker/${t.id}/setup`)}
>
@@ -175,7 +198,7 @@ const ExamDashboardPage: React.FC = () => {
)}
-