Trudny / egzaminacyjny · lekcja 27

Projekt 8 (końcowy): System rezerwacji wizyt — Angular + logowanie + zadanie kontrolne

Ostatni, czwarty projekt i jednocześnie podsumowanie całego działu. Łączymy WSZYSTKO: Angular (komponenty, formularze, routing, serwisy), ASP.NET Core Web API z bazą danych, oraz logowanie użytkowników (ASP.NET Core Identity, lekcja 14) — dokładnie ten typ peł...

Zacznij tutaj

Po co się tego uczymy?

Ostatni, czwarty projekt i jednocześnie podsumowanie całego działu. Łączymy WSZYSTKO: Angular (komponenty, formularze, routing, serwisy), ASP.NET Core Web API z bazą danych, oraz logowanie użytkowników (ASP.NET Core Identity, lekcja 14) — dokładnie ten typ pełnego, wielowarstwowego zadania, jaki może pojawić się w części praktycznej egzaminu zawodowego INF.04. Na końcu lekcji znajdziesz też krótkie zadanie kontrolne sprawdzające wiedzę z całego działu.

Wprowadzenie

Teoria

Wymagania funkcjonalne systemu rezerwacji:

  • Lista dostępnych terminów — widoczna dla WSZYSTKICH odwiedzających (komponent publiczny, bez logowania);
  • Rezerwacja terminu — WYMAGA zalogowania; zalogowany użytkownik wybiera wolny termin i go rezerwuje;
  • "Moje rezerwacje" — strona (chroniona) pokazująca WYŁĄCZNIE rezerwacje zalogowanego użytkownika;
  • Anulowanie rezerwacji — użytkownik może odwołać WŁASNĄ rezerwację;
  • Logowanie i rejestracja — ASP.NET Core (lekcja 14), z tokenem/ciasteczkiem uwierzytelniającym rozpoznawanym przez Angular.

Logowanie w architekturze Angular + Web API. W parze Razor Pages (jedna aplikacja), Identity działa "w tle" automatycznie przez ciasteczka. W architekturze Angular+API mamy DWIE osobne aplikacje (inny port!) — logowanie zwykle realizuje się przez token (najczęściej JWT — JSON Web Token): backend po poprawnym zalogowaniu zwraca token, Angular zapisuje go (np. w pamięci przeglądarki) i DOŁĄCZA do KAŻDEGO kolejnego żądania w nagłówku Authorization: Bearer <token>. Backend na podstawie tego nagłówka rozpoznaje, KTO wysyła żądanie, bez potrzeby przechowywania sesji po stronie serwera. To rozwiązanie technicznie różni się od ciasteczek sesyjnych z lekcji 13, ale odpowiada na TEN SAM problem — informator CKE wprost dopuszcza obie metody: "obsłużyć sesje LUB JWT".

Model danych. Termin (Data, CzyZarezerwowany), Rezerwacja (TerminId, UzytkownikId, DataUtworzenia) — relacja jeden-do-jednego między terminem a rezerwacją, jeden-do-wielu między użytkownikiem a jego rezerwacjami (EF Core, lekcje 14-16).

Kluczowy problem: unikanie podwójnej rezerwacji. Backend MUSI ponownie sprawdzić dostępność terminu TUŻ PRZED zapisem (nie tylko przy wyświetleniu listy) — jeśli dwóch użytkowników niemal jednocześnie próbuje zarezerwować ten sam termin, backend jako "źródło prawdy" musi to wykryć i jednego z nich odrzucić z czytelnym komunikatem błędu (kod 409 Conflict).

Struktura komponentów Angular: TerminyComponent (publiczny, lista + przycisk "Zarezerwuj", przekierowujący na logowanie jeśli niezalogowany), LogowanieComponent/RejestracjaComponent, MojeRezerwacjeComponent (chroniony przez Angular Route Guard — mechanizm blokujący dostęp do trasy bez ważnego tokenu, analogiczny do [Authorize] z ASP.NET Core).

Zobacz zależności

Schemat

Gość (niezalogowany)
        │
        ▼
Pages/Terminy/Lista.cshtml (publiczna) - widzi dostępne terminy
        │
        │  klika "Zarezerwuj" → przekierowanie na logowanie (jeśli niezalogowany)
        ▼
Pages/Konto/Logowanie.cshtml → po zalogowaniu wraca (ReturnUrl)
        │
        ▼
Pages/Rezerwacje/Zarezerwuj.cshtml  [Authorize]
        │
        │  OnPostAsync: PONOWNE sprawdzenie czy termin nadal wolny
        │  (ochrona przed podwójną rezerwacją)
        ▼
Nowa Rezerwacja (TerminId, UzytkownikId) → SaveChangesAsync()
Termin.CzyZarezerwowany = true → SaveChangesAsync()
        │
        ▼
Pages/Rezerwacje/Moje.cshtml [Authorize]
   context.Rezerwacje.Include(r => r.Termin)
       .Where(r => r.UzytkownikId == User Id zalogowanego)

Administrator: Pages/Admin/ZarzadzajTerminami.cshtml [Authorize(Roles="Admin")]
   dodawanie/usuwanie dostępnych terminów

Połącz z praktyką

Przykład z życia

System rezerwacji wizyt u fryzjera, lekarza czy w gabinecie kosmetycznym — klient przegląda dostępne terminy, loguje się, rezerwuje wybrany termin i może go później odwołać. To ostatni, syntetyzujący projekt tego działu, łączący front-end (Angular), backend (ASP.NET Core Web API) i bazę danych (EF Core) w jedną, kompletną, praktyczną aplikację.