A modern, feature-complete client-side quiz application built with React, focused on clean architecture, predictable state management, verified implementation quality, and controlled incremental hardening.
This repository now represents v1.2 – Quality & Stability Hardening.
- Feature complete
- Structurally verified
- Architecture aligned with internal context document
- Accessibility improvements implemented (non-visual)
- Performance audited
- Unit and integration tests passing
- Basic happy-path smoke test coverage added
- No backend / no server-side persistence
This version serves as a stable, hardened baseline for future controlled development.
- Consistent
weakQuestionsaccumulation - Deterministic retry cleanup behavior
- Guarded against corrupted
weakQuestionsstate - Dedicated unit tests added
- Full retry flow covered:
- finish quiz → retry wrong → complete retry → result
- Validated mode transitions (
normal→retry→normal) - Ensured
lastResultis never overwritten during retry
- Empty question pools handled safely
- Invalid category/difficulty combinations guarded
- Corrupted
localStorageparsing hardened instatsSlice - Defensive guards added in
quizSlice - No silent crashes allowed
- ARIA labels added to:
- Icon-only buttons
- Modal overlay
- ESC closes modal
- Enter confirms focused button action
- No visual redesign
- Audited Zustand state updates for minimal mutation
- Removed unnecessary function recreation in header
- Verified no redundant
localStoragewrites - Prevented unnecessary header re-renders
- No behavioral changes introduced
- Strengthened unit coverage
- Retry integration coverage added
- Basic happy-path smoke test:
- Start quiz → answer → finish → result
- Start → questions → result
- Multiple-choice questions
- Score & accuracy calculation
- Result screen on completion
- Deterministic retry mode
- Difficulty selection (easy / normal / hard)
- Question count per quiz
- Sound toggle
- Timer toggle
- Adjustable time per question
- Progress bar
- Per-question timer
- Streak indicator
- Last result modal
- Light / Dark theme (persistent)
- Best score tracking
- Accuracy calculation
- Difficulty-based statistics
- Streak tracking
- Persistent last result
- Weak question tracking
- React
- Vite
- Zustand
- JavaScript (ES6+)
- localStorage (validated & hardened)
┌────────────────────┐
│ React UI │
│--------------------│
│ Header / Question │
│ Settings / Modals │
│ Progress / Footer │
└─────────┬──────────┘
│
▼
┌────────────────────┐
│ useQuizStore │
│ (Zustand Store) │
└─────────┬──────────┘
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
quizSlice settingsSlice statsSlice (quiz flow) (user config) (history, persistence)
▼
uiSlice
(UI flags / modals)
- Single source of truth:
useQuizStore - Slice isolation (no accidental cross-mutation)
- Retry mode as controlled state machine extension
- localStorage treated as non-trustworthy input
- Deterministic state transitions only
- No silent runtime crashes
Global state is composed of isolated slices:
quizSlice– quiz flow logicsettingsSlice– user-configurable optionsstatsSlice– statistics and historical datauiSlice– UI flags and modal control
All state transitions are explicit and validated.
src/
├─ components/
│ ├─ header/
│ ├─ footer/
│ ├─ question/
│ │ └─ tests/
│ ├─ settings/
│ ├─ progress/
│ ├─ pages/
│ └─ store/
│ ├─ slices/
│ └─ tests/
├─ styles/
│ ├─ base/
│ ├─ layout/
│ ├─ components/
├─ utils/
├─ App.jsx
└─ main.jsx
All directories are explicitly verified.
- Node.js (LTS recommended)
- npm
npm installStart the development server:
npm run dev- Current release: v1.2
- Previous stable baseline: v1.1
- Controlled incremental releases
- No uncontrolled refactors
Unit and integration tests are implemented at:
- Store level
- Component level
Covered areas:
- Quiz flow logic
- Timer behavior
- Retry mode transitions
- weakQuestions handling
- lastResult structure validation
- Modal rendering
- QuestionCard interaction
- Basic happy-path smoke test
Run tests:
npm testTwo supported data sources:
- Local question data (src/data/questions.jsx)
- Public Trivia API (Open Trivia Database)
If API category is unsupported:
- Error is handled gracefully
- No crash occurs
-
Avoid architectural refactors without discussion
-
Maintain slice isolation
-
Preserve invariants:
- Stable lastResult structure
- Retry mode isolation
- Safe localStorage parsing
- No state corruption
-
All changes must be deterministic
This project is maintained by Duško Vokić. You can reach out via:
- GitHub: https://github.com/D-vokic
- Website: https://duskovokic.com
This project is licensed under the MIT License.
- React community for best practices and tooling
- Zustand for lightweight state management
- Vitest for fast and reliable testing