diff --git a/src/pages/exam/setup/ExamTemplateSetupPage.tsx b/src/pages/exam/setup/ExamTemplateSetupPage.tsx index 48a5633..ba08234 100644 --- a/src/pages/exam/setup/ExamTemplateSetupPage.tsx +++ b/src/pages/exam/setup/ExamTemplateSetupPage.tsx @@ -1,8 +1,9 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useNavigate, useParams } from 'react-router-dom' -import { Alert, Box, Button, Chip, CircularProgress, Divider, Paper, Snackbar, Stack, Tooltip, Typography, useTheme } from '@mui/material' +import { Alert, Box, Button, Chip, CircularProgress, Collapse, Divider, IconButton, Paper, Snackbar, Stack, Tooltip, Typography, useTheme } from '@mui/material' import ArrowBackIcon from '@mui/icons-material/ArrowBack' +import HelpOutlineIcon from '@mui/icons-material/HelpOutline' import SaveIcon from '@mui/icons-material/Save' import MouseIcon from '@mui/icons-material/Mouse' import '@tldraw/tldraw/tldraw.css' @@ -168,6 +169,7 @@ const ExamTemplateSetupInner: React.FC = () => { const [activeTool, setActiveTool] = useState('select') const [pdfStatus, setPdfStatus] = useState<'loading' | 'ready' | 'missing' | 'error'>('loading') const [pdfError, setPdfError] = useState(null) + const [guideOpen, setGuideOpen] = useState(false) const load = useCallback(async () => { if (!templateId) return @@ -269,16 +271,15 @@ const ExamTemplateSetupInner: React.FC = () => { return ( t.zIndex.drawer + 20, bgcolor: 'background.default', display: 'flex', flexDirection: 'column' }}> - {/* Top bar */} - - + {/* Top bar — single compact line */} + + + navigate('/exam-marker')} size="small"> + - - {template?.title ?? 'Template setup'} - Exam Marker › Setup · coloured tools map to persisted regions; boundary start/end pairs can span pages. - + {template?.title ?? 'Template setup'} - + {/* Body row */} @@ -310,26 +311,34 @@ const ExamTemplateSetupInner: React.FC = () => { /> - {/* Guide panel */} - - Setup guide - - 1) Boundary start/end lines define each main question. 2) Draw amber Part boxes for markable sub-questions. 3) Draw coloured Response, Context, Q Number, Mark Area, Reference, and Furniture regions; Save derives parent links by containment. - - - {(['boundary', 'part', 'response', 'context', 'question_number', 'mark_area', 'reference', 'furniture'] as const).map((kind) => { - const p = canvasShapePalette[kind] - return - })} - - - Multi-page boundary pairing - Draw "Q start" on page N, then "Q end" on a later page; save pairs boundaries by reading order into one question span. - Open design choices resolved for v1: labels use "Q start/end"; persistent Attached pills confirm containment; rectangles stay simple for dense multi-column papers; Back button remains explicit. - - PDF backdrop: {pdfStatus === 'ready' ? 'loaded and locked behind regions' : pdfStatus === 'loading' ? 'loading…' : pdfStatus === 'missing' ? 'no source PDF for this template' : pdfError ?? 'failed to load'} - - + {/* Guide toggle */} + + setGuideOpen((v) => !v)} size="small" sx={{ position: 'absolute', right: 16, bottom: 16, zIndex: 1001, bgcolor: 'background.paper', boxShadow: 2, '&:hover': { bgcolor: 'background.paper' } }}> + + + + + {/* Guide panel — collapsible */} + + + Setup guide + + 1) Boundary start/end lines define each main question. 2) Draw amber Part boxes for markable sub-questions. 3) Draw coloured Response, Context, Q Number, Mark Area, Reference, and Furniture regions; Save derives parent links by containment. + + + {(['boundary', 'part', 'response', 'context', 'question_number', 'mark_area', 'reference', 'furniture'] as const).map((kind) => { + const p = canvasShapePalette[kind] + return + })} + + + Multi-page boundary pairing + Draw "Q start" on page N, then "Q end" on a later page; save pairs boundaries by reading order into one question span. + + PDF: {pdfStatus === 'ready' ? 'loaded' : pdfStatus === 'loading' ? 'loading…' : pdfStatus === 'missing' ? 'no source PDF' : pdfError ?? 'failed'} + + + {/* Conflict alert */} {conflict && setConflict(null)}>{conflict}}