Przejdź do głównej zawartości

09. Platforma quizów

Zbudujesz platformę do quizów — użytkownik może przeglądać dostępne quizy (lub je tworzyć), rozwiązywać je pytanie po pytaniu i zobaczyć wynik końcowy z podsumowaniem odpowiedzi.

Czego się nauczycie?

  • Wieloetapowy flow (ekrany: lista → intro → pytanie → wynik)
  • Zarządzanie stanem gry (bieżące pytanie, wybrane odpowiedzi, wynik)
  • Losowanie kolejności pytań i odpowiedzi
  • Licznik czasu (wariant B/C)
  • Praca zespołowa — jeden robi tworzenie quizów, drugi rozwiązywanie i wyniki
  1. Lista quizów — karty z tematem, liczbą pytań i trudnością

  2. Intro quizu — opis, liczba pytań, czas (jeśli jest), przycisk “Startuj”

  3. Rozwiązywanie — jedno pytanie naraz, wybór jednej z 4 odpowiedzi, pasek postępu

  4. Wynik końcowy — punktacja, procent poprawnych, lista pytań z zaznaczeniem co było dobre/złe

  5. Historia wyników — poprzednie podejścia zapisane w localStorage

{
"id": "quiz-001",
"title": "JavaScript Podstawy",
"category": "Programowanie",
"difficulty": "medium",
"timeLimit": 300,
"questions": [
{
"id": "q-001",
"text": "Co zwraca typeof null w JavaScript?",
"answers": [
{ "id": "a", "text": "null", "correct": false },
{ "id": "b", "text": "object", "correct": true },
{ "id": "c", "text": "undefined", "correct": false },
{ "id": "d", "text": "string", "correct": false }
],
"explanation": "typeof null === 'object' to historyczny bug w JavaScript."
}
]
}
  • Minimum 3 quizy z danymi lokalnymi (po 5-10 pytań)
  • Przepływ: lista → intro → pytania → wynik
  • Wybór odpowiedzi i podliczanie wyniku
  • Wynik końcowy (X/Y poprawnych)
  • Powrót do listy quizów
  • Routing: /, /quiz/:id, /quiz/:id/result
  • Foldersrc/
    • Folderdata/
      • quizzes.js
    • Foldercomponents/
      • QuizCard.jsx
      • QuestionView.jsx
      • AnswerOption.jsx
      • ResultView.jsx
    • Folderpages/
      • QuizListPage.jsx
      • QuizPage.jsx
Ocena: 3.0
const quizReducer = (state, action) => {
switch (action.type) {
case 'START_QUIZ':
return {
status: 'in-progress',
questions: shuffle(action.questions),
currentIndex: 0,
answers: [],
score: 0,
};
case 'ANSWER': {
const isCorrect = action.answer.correct;
return {
...state,
answers: [...state.answers, { questionId: action.questionId, answer: action.answer }],
score: isCorrect ? state.score + 1 : state.score,
currentIndex: state.currentIndex + 1,
status: state.currentIndex + 1 >= state.questions.length ? 'finished' : 'in-progress',
};
}
case 'RESET':
return { status: 'idle', questions: [], currentIndex: 0, answers: [], score: 0 };
default:
return state;
}
};
function shuffle(array) {
return [...array].sort(() => Math.random() - 0.5);
}
function useTimer(initialTime, onTimeUp) {
const [timeLeft, setTimeLeft] = useState(initialTime);
useEffect(() => {
if (timeLeft <= 0) {
onTimeUp();
return;
}
const timer = setTimeout(() => setTimeLeft((t) => t - 1), 1000);
return () => clearTimeout(timer);
}, [timeLeft, onTimeUp]);
return timeLeft;
}

Powodzenia!

Platforma quizów to projekt z naturalnym wieloekranowym flow — świetnie pokazuje że rozumiecie zarządzanie stanem przez cały cykl życia aplikacji. Maszyna stanów quizu (idle → in-progress → finished) to wzorzec używany w bardzo wielu aplikacjach!