Skip to content

Latest commit

 

History

History
250 lines (211 loc) · 9.03 KB

File metadata and controls

250 lines (211 loc) · 9.03 KB

JavaScript Quiz SPA - Implementation Plan

Overview

Create a pure SPA quiz application for JavaScript with three difficulty levels (easy, intermediate, hard), deployed to GitHub Pages at godmar.github.io/jsquiz.

Tech Stack:

  • Vite 7 (build tool) - modern, fast, recommended over deprecated CRA
  • React 19 (plain JavaScript, no TypeScript)
  • Material UI 7 (styling)
  • React Router 7 with HashRouter (GitHub Pages compatible)

Project Structure

jsquiz/
├── .github/workflows/deploy.yml   # GitHub Actions deployment
├── public/
├── src/
│   ├── components/
│   │   ├── Quiz/
│   │   │   ├── Quiz.jsx           # Main quiz container
│   │   │   ├── StartScreen.jsx    # Welcome + difficulty selection
│   │   │   ├── Question.jsx       # Single question display
│   │   │   └── Results.jsx        # Score + review
│   │   └── common/
│   │       └── Header.jsx         # App header (dynamic difficulty badge)
│   ├── context/
│   │   └── QuizContext.jsx        # Quiz state management
│   ├── data/
│   │   ├── index.js               # Question set exports
│   │   ├── easyQuestions.js       # 10 easy questions
│   │   ├── questions.js           # 10 intermediate questions
│   │   └── hardQuestions.js       # 10 hard questions
│   ├── theme/
│   │   └── theme.js               # MUI theme (JS yellow colors)
│   ├── App.jsx                    # Routes configuration
│   └── main.jsx                   # Entry point with providers
├── index.html
├── package.json
├── vite.config.js                 # base: '/jsquiz/' for GH Pages
└── PLAN.md

Implementation Steps

1. Initialize Project

npm create vite@latest . -- --template react
npm install @mui/material @emotion/react @emotion/styled @mui/icons-material react-router-dom

2. Configure Vite for GitHub Pages

vite.config.js:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  base: '/jsquiz/',  // Critical for GH Pages subdirectory
});

3. Set Up HashRouter

src/main.jsx:

import { HashRouter } from 'react-router-dom';
// URLs will be: godmar.github.io/jsquiz/#/easy/1

4. Create Quiz Data Structure

Question Sets:

  • Easy (easyQuestions.js): Basics - types, arrays, functions, operators
  • Intermediate (questions.js): Closures, promises, event loop, hoisting
  • Hard (hardQuestions.js): Edge cases, generators, proxies, TDZ

Each question format:

{
  id: 1,
  question: "What is the output?",
  code: `console.log(typeof null);`,
  options: [
    { id: 'a', text: '"null"' },
    { id: 'b', text: '"object"' },
    // ...
  ],
  correctAnswer: 'b',
  explanation: "This is a known JavaScript bug..."
}

5. Implement Quiz Context

State management for:

  • User answers (object: {questionId: answerId})
  • Score calculation (function that takes questions array)
  • Submit and reset

6. Build Components

  • StartScreen: Instructions, three difficulty buttons (Easy/Intermediate/Hard)
  • Quiz: Progress bar, Question component, nav buttons
  • Question: Code block, radio group for options
  • Results: Score display, difficulty badge, question review with explanations
  • Header: Dynamic difficulty badge, clickable title linking to home

7. Create GitHub Actions Workflow

.github/workflows/deploy.yml:

name: Deploy to GitHub Pages
on:
  push:
    branches: ['master']
permissions:
  contents: read
  pages: write
  id-token: write
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npm run build
      - uses: actions/configure-pages@v4
      - uses: actions/upload-pages-artifact@v3
        with:
          path: './dist'
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/deploy-pages@v4
        id: deployment

Quiz UX Flow

  1. Start Screen (/#/) - Instructions, difficulty selection (Easy/Intermediate/Hard buttons)
  2. Quiz (/#/easy/1, /#/intermediate/5, /#/hard/3, etc.) - One question at a time, progress bar, prev/next nav
  3. Results (/#/easy/results, /#/intermediate/results, /#/hard/results) - Score, percentage, difficulty badge, full review with explanations

All routes are bookmarkable - refreshing preserves the current question.


Key MUI Components

  • Container, Card, CardContent - Layout
  • Typography - Text styling
  • Button, Stack - Actions and difficulty selection
  • RadioGroup, Radio, FormControlLabel - Answer selection
  • LinearProgress - Progress indicator
  • AppBar, Toolbar, Chip - Header with difficulty badge
  • Box - Spacing and layout

Repository Setup (Manual Steps)

After pushing code:

  1. Go to repo Settings > Pages
  2. Under "Build and deployment", select GitHub Actions as source
  3. Push to master branch triggers deployment

Caching Note

GitHub Pages has fixed cache headers (~10 minutes). Vite generates hashed asset filenames for cache busting, but index.html may be cached by the CDN. For immediate updates during development, test locally with npm run dev.


Verification

  1. Run npm run dev - test locally at localhost:5173/jsquiz/
  2. Test all routes work with HashRouter (easy/intermediate/hard, question numbers, results)
  3. Test bookmarkability - refresh should stay on current question
  4. Push to GitHub, verify Actions workflow runs
  5. Check deployed site at godmar.github.io/jsquiz

Implementation Log

Commit 1: c3c09c3 - Add JavaScript Quiz SPA

Initial implementation of the complete quiz application:

  • Initialized npm project and installed dependencies (Vite, React, MUI, React Router)
  • Created vite.config.js with base: '/jsquiz/' for GitHub Pages
  • Created index.html entry point
  • Set up project directory structure
  • Implemented all components:
    • src/main.jsx - Entry point with HashRouter, ThemeProvider, QuizProvider
    • src/App.jsx - Route configuration
    • src/theme/theme.js - MUI dark theme with JavaScript yellow (#f7df1e)
    • src/context/QuizContext.jsx - Quiz state management
    • src/data/questions.js - 10 intermediate JavaScript questions
    • src/components/common/Header.jsx - App header with logo
    • src/components/Quiz/Quiz.jsx - Main quiz container
    • src/components/Quiz/StartScreen.jsx - Welcome screen with instructions
    • src/components/Quiz/Question.jsx - Question display with code block and options
    • src/components/Quiz/Results.jsx - Score and review with explanations
  • Created .github/workflows/deploy.yml for GitHub Actions deployment
  • Created .gitignore to exclude node_modules and dist

Commit 2: 3c2555b - Add JavaScript version note to start screen

  • Added note clarifying that questions assume ES6+ (ECMAScript 2015+) in strict mode
  • Styled as a highlighted callout box on the start screen

Commit 3: 2322d1d - Use URL-based routing for each question

  • Changed routing so each question has its own URL (/#/1, /#/2, etc.)
  • Updated App.jsx to use /:questionNum route parameter
  • Updated Quiz.jsx to read question number from URL and navigate between questions
  • Simplified QuizContext.jsx by removing currentIndex state (now URL-driven)

Commit 4: f081d9a - Fix page refresh losing quiz state

  • Removed isStarted state requirement - URL now determines which question to show
  • Page refresh now correctly stays on the current question
  • Direct linking to specific questions works (e.g., /#/3 shows question 3)
  • Simplified context by removing isStarted and startQuiz function

Commit 5: 8247aff - Add implementation plan and log

  • Created PLAN.md documenting the implementation plan and commit history

Commit 6: c430b3d - Update PLAN.md with actual dependency versions

  • Corrected tech stack to reflect React 19, MUI 7, React Router 7, Vite 7

Commit 7: f363a77 - Add easy and hard difficulty levels

  • Created src/data/easyQuestions.js with 10 basic JavaScript questions
  • Created src/data/hardQuestions.js with 10 advanced JavaScript questions
  • Created src/data/index.js to export question sets and utilities
  • Updated routing to /:difficulty/:questionNum pattern
  • Updated StartScreen with three difficulty buttons (Easy/Intermediate/Hard)
  • Updated Header to show dynamic difficulty badge based on current route
  • Made Header title clickable to return to landing page
  • Updated Results to show difficulty badge
  • Updated QuizContext to accept questions as parameter for score/percentage/isComplete

Commit 8: 4998635 - Add cache control meta tags to index.html

  • Added Cache-Control, Pragma, and Expires meta tags
  • Note: Limited effectiveness due to GitHub Pages CDN caching (~10 minutes)