Skip to content

Commit 4c89de4

Browse files
committed
Add URL handler for question ID
1 parent 2937cc7 commit 4c89de4

File tree

4 files changed

+81
-10
lines changed

4 files changed

+81
-10
lines changed

package-lock.json

Lines changed: 54 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"react": "^19.1.1",
2020
"react-dom": "^19.1.1",
2121
"react-markdown": "^10.1.0",
22+
"react-router-dom": "^7.9.3",
2223
"react-syntax-highlighter": "^15.6.6",
2324
"zustand": "^5.0.8"
2425
},

src/App.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { useState } from 'react';
1+
import { useEffect } from 'react';
22
import { Box, Button, Paper, Typography } from '@mui/material';
3+
import { useSearchParams } from 'react-router-dom';
34
import './App.css';
45
import { QuizQuestion } from './components/QuizQuestion';
56
import { QuizStats } from './components/QuizStats';
@@ -11,20 +12,32 @@ export function App() {
1112
const correctQuestions = useQuizStore((state) => state.correctQuestions);
1213
const resetProgress = useQuizStore((state) => state.resetProgress);
1314

14-
const [currentQuestionId, setCurrentQuestionId] = useState(
15-
() => selectNextQuestion(answeredQuestions, correctQuestions) ?? questionIds[0],
16-
);
15+
const [searchParams, setSearchParams] = useSearchParams();
16+
17+
const urlQuestionId = searchParams.get('q');
18+
const validUrlQuestionId = urlQuestionId && questionIds.includes(urlQuestionId) ? urlQuestionId : null;
19+
20+
const currentQuestionId =
21+
validUrlQuestionId ?? selectNextQuestion(answeredQuestions, correctQuestions) ?? questionIds[0];
22+
23+
// Sync URL with current question
24+
useEffect(() => {
25+
if (searchParams.get('q') !== currentQuestionId) {
26+
setSearchParams({ q: currentQuestionId }, { replace: true });
27+
}
28+
}, [currentQuestionId, searchParams, setSearchParams]);
1729

1830
const handleNextQuestion = () => {
1931
const nextId = selectNextQuestion(answeredQuestions, correctQuestions);
2032
if (nextId) {
21-
setCurrentQuestionId(nextId);
33+
setSearchParams({ q: nextId }, { replace: true });
2234
}
2335
};
2436

2537
const handlePlayAgain = () => {
2638
resetProgress();
27-
setCurrentQuestionId(questionIds[Math.floor(Math.random() * questionIds.length)]);
39+
const randomId = questionIds[Math.floor(Math.random() * questionIds.length)];
40+
setSearchParams({ q: randomId }, { replace: true });
2841
};
2942

3043
const allQuestionsCorrect = correctQuestions.length === questionIds.length;

src/main.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import { CssBaseline } from '@mui/material';
22
import { StrictMode } from 'react';
33
import { createRoot } from 'react-dom/client';
4+
import { BrowserRouter } from 'react-router-dom';
45
import { App } from './App';
56
import { Theme } from './components/Theme';
67
import './index.css';
78

89
createRoot(document.getElementById('root') as HTMLElement).render(
910
<StrictMode>
10-
<Theme>
11-
<CssBaseline />
12-
<App />
13-
</Theme>
11+
<BrowserRouter>
12+
<Theme>
13+
<CssBaseline />
14+
<App />
15+
</Theme>
16+
</BrowserRouter>
1417
</StrictMode>,
1518
);

0 commit comments

Comments
 (0)