Public Access
fix: final review fixes — key props, fetch guard, highlightCode placeholder strategy
- Add key={q.id} to QuestionRenderer in ExamRunner and Results to reset
component state (Match activeLeft, OrderQuestion init) between questions
- Add r.ok check in Landing.loadSample to surface HTTP errors before JSON parse
- Add validateExam call in loadSample (was missing — could pass malformed JSON)
- Rewrite highlightCode with placeholder strategy: extract comment/string spans
before applying keyword/number/fn regexes so later passes don't corrupt
previously-injected span attributes; use PUA char + word-wrapped index
to avoid SonarLint S6324 and prevent digit regex matching index numbers
- Change Landing dropzone from div[role=button] to native button (S6819)
- Change sample cards from div[onClick] to button elements (S6848/S1082)
- Wrap Landing Props in Readonly<> (S6759)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
2b12223da6
commit
8420e6cae0
4 files changed
+28
-11
No files matched your search
@@ -18,7 +18,7 @@ const SAMPLES = [
|
||||
{ path: '/samples/mixed-demo.json', title: 'Mixed Demo — Every Question Type', meta: '4 questions · Untimed · Media', mark: '◇' },
|
||||
]
|
||||
|
||||
export default function Landing({ onLoadExam, history, onResume, onClearHistory, onReviewAttempt }: Props) {
|
||||
export default function Landing({ onLoadExam, history, onResume, onClearHistory, onReviewAttempt }: Readonly<Props>) {
|
||||
const [err, setErr] = useState<string | null>(null)
|
||||
const [dragOver, setDragOver] = useState(false)
|
||||
const fileRef = useRef<HTMLInputElement>(null)
|
||||
@@ -40,6 +40,7 @@ export default function Landing({ onLoadExam, history, onResume, onClearHistory,
|
||||
setErr(null)
|
||||
try {
|
||||
const r = await fetch(path)
|
||||
if (!r.ok) throw new Error(`${r.status} ${r.statusText}`)
|
||||
const data = await r.json() as unknown
|
||||
const msg = validateExam(data)
|
||||
if (msg) throw new Error(msg)
|
||||
@@ -112,14 +113,14 @@ export default function Landing({ onLoadExam, history, onResume, onClearHistory,
|
||||
<div className="samples">
|
||||
<h4>Try a sample</h4>
|
||||
{SAMPLES.map((s) => (
|
||||
<div key={s.path} className="sample" onClick={() => void loadSample(s.path)}>
|
||||
<button key={s.path} type="button" className="sample" onClick={() => void loadSample(s.path)}>
|
||||
<div className="sample-mark serif" style={{ fontSize: 18 }}>{s.mark}</div>
|
||||
<div className="sample-body">
|
||||
<div className="sample-title">{s.title}</div>
|
||||
<div className="sample-meta">{s.meta}</div>
|
||||
</div>
|
||||
<div className="sample-arrow">→</div>
|
||||
</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user