System Testowy (Quiz)

Angular
Priorytet: Normalny Szkic

Zadanie 1000: System Testowy (Angular)

Wstęp

Twoim zadaniem jest stworzenie aplikacji "System Testowy", która symuluje egzamin (np. zawodowy INF.04). Aplikacja ma wczytać bazę pytań, wylosować z niej zestaw egzaminacyjny, przeprowadzić użytkownika przez test i wystawić ocenę.

Poniższy scenariusz przeprowadzi Cię przez ten proces krok po kroku. Pamiętaj: nie dostaniesz tutaj gotowego kodu (Ctrl+C, Ctrl+V). Otrzymasz wskazówki, które pomogą Ci samodzielnie napisać rozwiązanie.

Wymagania wstępne

  • Projekt Angular (wygenerowany przez ng new).
  • Zainstalowany Bootstrap lub inny framework CSS (opcjonalnie, dla estetyki).

Scenariusz Realizacji (Krok po Kroku)

Baza danych

dane.json

Obrazy

pliki.zip

Etap 1: Przygotowanie Danych i Typów

  1. Definicja Interfejsów (Models): Stwórz plik models/question.model.ts. Zdefiniuj interfejs Answer (treść, czy poprawna) oraz Question (id, kod, treść pytania, tablica odpowiedzi).

    Wskazówka: Użyj interface lub type w TypeScript.

  2. Przygotowanie Bazy Pytań (Mock Data): Stwórz plik public/dane.json i umieść w nim tablicę obiektów pytań (bazując na dostarczonym przykładzie).

    Wskazówka: Upewnij się, że JSON jest poprawny składniowo (walidator JSON).

  3. Serwis Danych (Data Service): Wygeneruj serwis services/question.service.ts. Zaimportuj HttpClientModule w app.module.ts.

    Wskazówka: Użyj HttpClient.get<Question[]>() do pobrania pliku JSON.

Etap 2: Logika Aplikacji (Engine)

  1. Metoda Losowania (Randomizer): W serwisie napisz funkcję getRandomQuestions(allQuestions: Question[], count: number): Question[].

    Wskazówka: Jak wylosować unikalne elementy? Może przetasowanie tablicy (shuffle) i pobranie pierwszych N elementów (slice)?

  2. State Management (Zarządzanie Stanem): Stwórz serwis services/quiz-state.service.ts do przechowywania bieżącego stanu egzaminu: aktualny indeks pytania, wybrane odpowiedzi użytkownika, wylosowana pula pytań.

    Wskazówka: Użyj BehaviorSubject jeśli chcesz reagować na zmiany, lub po prostu zmiennych w serwisie (Singleton).

  3. Struktura Odpowiedzi Użytkownika: Zastanów się, jak przechowywać wybory. Tablica? Mapa Map<QuestionID, AnswerID>?

    Wskazówka: Mapa pozwala łatwo sprawdzić "czy to pytanie ma już odpowiedź?".

Etap 3: Interfejs Użytkownika (Components)

  1. Komponent Główny (Quiz Component): Wygeneruj komponent components/quiz. To tu będzie dziać się główna akcja.

    Wskazówka: Komponent powinien w ngOnInit pobrać pytania z serwisu i zainicjować test.

  2. Layout Pytania (HTML Structure): Zbuduj widok pojedynczego pytania. Wyświetl treść pytania (question.taskContent) używając wiązania danych.

    Wskazówka: Treść zawiera HTML (obrazki)? Użyj [innerHTML], ale uważaj na sanityzację (lub zaufaj własnemu JSON-owi).

  3. Wyświetlanie Odpowiedzi (ngFor): Użyj dyrektywy *ngFor aby wygenerować listę możliwych odpowiedzi (radio buttons lub przyciski).

    Wskazówka: Pamiętaj o unikalnych atrybutach name dla radio buttonów, aby grupowały się poprawnie.

  4. Obsługa Wyboru (Event Binding): Obsłuż zdarzenie kliknięcia ((click) lub (change)). Zapisz wybór użytkownika w serwisie stanu.

    Wskazówka: Przekaż ID wybranej odpowiedzi do funkcji obsługującej.

  5. Nawigacja (Next/Prev): Dodaj przyciski "Następne" i "Poprzednie". Oprogramuj logikę zmiany indeksu aktualnego pytania.

    Wskazówka: Ukryj przycisk "Poprzednie" na pierwszym pytaniu i "Następne" na ostatnim.

  6. Przycisk "Zakończ Test": Na ostatnim pytaniu wyświetl przycisk "Zakończ", który przeniesie do podsumowania.

    Wskazówka: Możesz użyć *ngIf="isLastQuestion".

Etap 4: System Oceniania

  1. Logika Obliczania Wyniku: W serwisie napisz funkcję calculateResult(). Musi ona porównać wybory użytkownika z poprawnymi odpowiedziami w obiektach pytań.

    Wskazówka: Iteruj po wylosowanych pytaniach i sprawdzaj selectedAnswerId === correctAnswerId.

  2. Próg Zaliczenia: Oblicz procentowy wynik. Ustal flagę passed (true/false) jeśli wynik >= 50%.

Etap 5: Widok Podsumowania (Summary)

  1. Komponent Podsumowania: Wygeneruj komponent components/summary.

    Wskazówka: Wyświetl wielki napis "ZDALES" (zielony) lub "NIEZDALES" (czerwony) oraz liczbę punktów.

  2. Tabela Wyników (Review Mode): Poniżej wyniku wyświetl listę wszystkich pytań z testu.

    Wskazówka: Użyj tabeli lub listy rozwijanej (accordion).

  3. Wizualizacja Błędów: Dla każdego pytania w podsumowaniu pokaż: co zaznaczył użytkownik, a co było poprawne.

    Wskazówka: Użyj klas CSS np. .text-success dla dobrych i .text-danger dla złych odpowiedzi.

  4. Filtrowanie (Opcjonalne): Dodaj przyciski "Pokaż tylko błędne", aby ułatwić naukę.

    Wskazówka: Prosty *ngIf lub Pipe filtrujący.

Etap 6: UX i Szlify

  1. Pasek Postępu (Progress Bar): Dodaj pasek postępu (np. "Pytanie 5 z 20").

    Wskazówka: Oblicz szerokość paska jako (currentIndex / totalQuestions) * 100%.

  2. Zabezpieczenia (Guards): Co jeśli użytkownik wejdzie na /summary bez robienia testu? Przekieruj go do startu.

    Wskazówka: Użyj CanActivate lub prostej logiki w konstruktorze komponentu.

  3. Loadery i Obsługa Błędów: Co jeśli questions.json się nie załaduje? Wyświetl komunikat o błędzie zamiast białego ekranu.


Powodzenia! To kompleksowe zadanie sprawdzi Twoją znajomość Angulara.