# Reservation Management System Aplikacja SPA do zarządzania rezerwacjami zbudowana w React 19 + Vite 8. Umożliwia klientom przeglądanie dostępnych terminów, dokonywanie rezerwacji z płatnością depozytu, zarządzanie historią rezerwacji oraz wystawianie opinii. Administratorzy mają dostęp do panelu zarządzania, kalendarza rezerwacji, analityki i eksportu danych. --- ## Uruchomienie ```bash # Terminal 1 – REST API (json-server na porcie 3001) npm run api # Terminal 2 – Vite dev server (port 5173) npm run dev # Testy jednostkowe (Vitest + RTL) npm test # Testy e2e (Playwright) node test_rms.mjs # Storybook (port 6006) npm run storybook ``` > **Uwaga:** przed uruchomieniem `test_rms.mjs` oba serwery muszą być aktywne. Test automatycznie przywraca dane seed (r1, r2) do stanu `pending` przed każdym przebiegiem. --- ## Dane testowe | Rola | E-mail | Hasło | |------|--------|-------| | Admin | `admin@reservations.dev` | `Admin1234!` | | Klient | `anna.kowalski@example.com` | `Client1234!` | Logowanie zawsze uruchamia **weryfikację 2FA** – kod jest wyświetlany bezpośrednio w interfejsie (symulowany e-mail). --- ## Stos technologiczny | Warstwa | Technologia | |---------|-------------| | UI | React 19, Vite 8, SCSS Modules | | Routing | React Router v7 | | Zapytania REST | TanStack React Query v5 + Axios | | Zapytania GraphQL | Apollo Client v4 + SchemaLink (in-memory) | | Formularze | Formik + Zod (`zod-formik-adapter`) | | Ikony | Lucide React | | REST mock | json-server (db.json) | | Testy jednostkowe | Vitest + React Testing Library | | Testy e2e | Playwright | | Dokumentacja | Storybook 8 | --- ## Struktura projektu ``` web_projekt/ ├── db.json # Baza danych json-server (users, services, reservations) ├── test_rms.mjs # Testy e2e Playwright (32 testy) ├── src/ │ ├── main.jsx # Punkt wejścia: Apollo Client, QueryClient, renderowanie │ ├── App.jsx # Router, lazy loading, ErrorBoundary, Suspense, ProtectedRoute │ ├── index.css # Reset + CSS custom properties (tryb ciemny/jasny) │ ├── styles/ │ │ ├── _variables.scss # Tokeny projektu: kolory, spacing, typografia, cienie, media queries │ │ └── main.scss # Globalne style bazowe │ ├── api/ │ │ ├── reservations.js # CRUD rezerwacji przez Axios (json-server :3001) │ │ ├── services.js # Pobieranie listy usług │ │ └── users.js # Pobieranie i aktualizacja użytkowników │ ├── context/ │ │ ├── AuthContext.jsx # Stan uwierzytelnienia, 2FA, role, sesja w localStorage │ │ └── ThemeContext.jsx # Przełącznik jasny/ciemny motyw (data-theme na ) │ ├── hocs/ │ │ └── withRole.jsx # HOC: renderuje komponent tylko dla dozwolonych ról │ ├── hooks/ │ │ ├── useCreateReservation.js # useMutation: POST /reservations │ │ ├── useDeleteReservation.js # useMutation: DELETE /reservations/:id │ │ ├── useReservations.js # useQuery: GET /reservations (wszystkie) │ │ ├── useServices.js # useQuery: GET /services │ │ ├── useSlotReservations.js # useQuery: GET /reservations?serviceId&date │ │ ├── useUpdateReservation.js # useMutation: PATCH /reservations/:id │ │ └── useUserReservations.js # useQuery: GET /reservations?userId │ ├── pages/ │ │ ├── LoginPage.jsx # Formularz logowania (Formik+Zod) + ekran 2FA z podglądem kodu │ │ ├── LoginPage.module.scss │ │ ├── RegisterPage.jsx # Rejestracja z walidacją Zod i weryfikacją e-mail │ │ ├── RegisterPage.module.scss │ │ ├── DashboardPage.jsx # Panel klienta: AvailabilitySearch, SlotFinder, BookingWizard, MyReservations, ProfileEditModal │ │ ├── DashboardPage.module.scss │ │ ├── ReservationsPage.jsx # Historia rezerwacji z filtrami, anulowaniem, RescheduleModal, ReviewsSection, Google Calendar, re-book │ │ ├── ReservationsPage.module.scss │ │ ├── AdminPage.jsx # Panel admina: tabela rezerwacji, UserManagement, AnalyticsDashboard, AdminCalendar, blokowanie terminów (useTransition) │ │ └── AdminPage.module.scss │ ├── components/ │ │ ├── AvailabilitySearch.jsx # Wyszukiwanie wolnych slotów z synchronizacją URL (useSearchParams) │ │ ├── AvailabilitySearch.module.scss │ │ ├── BookingWizard.jsx # 4-krokowy kreator rezerwacji (Usługa → Data → Wymagania → Podsumowanie) │ │ ├── BookingWizard.module.scss │ │ ├── BookingForm.jsx # Uproszczony formularz rezerwacji (react-hook-form) │ │ ├── BookingForm.module.scss │ │ ├── SlotFinder.jsx # Inteligentny finder slotów z punktacją (scoreSlot, findSlots) │ │ ├── SlotFinder.module.scss │ │ ├── PaymentModal.jsx # Modal płatności: Karta / Google Pay / Przelew bankowy (Portal) │ │ ├── PaymentModal.module.scss │ │ ├── RescheduleModal.jsx # Modal zmiany terminu rezerwacji (Portal) │ │ ├── RescheduleModal.module.scss │ │ ├── ProfileEditModal.jsx # Modal edycji profilu i preferencji powiadomień (Portal, Formik+Zod) │ │ ├── ProfileEditModal.module.scss │ │ ├── ReviewsSection.jsx # Sekcja opinii (GraphQL: useQuery + useMutation przez Apollo) │ │ ├── ReviewsSection.module.scss │ │ ├── ProfileView.jsx # Widok profilu (GraphQL: userProfile query) │ │ ├── ProfileView.module.scss │ │ ├── MyReservations.jsx # Sidebar z aktywnymi rezerwacjami użytkownika │ │ ├── MyReservations.module.scss │ │ ├── AdminCalendar.jsx # Widok kalendarza dla admina (miesiąc, kliknięcie dnia, panel boczny) │ │ ├── AdminCalendar.module.scss │ │ ├── AnalyticsDashboard.jsx # Statystyki rezerwacji z eksportem CSV (DataRenderer, useMemo) │ │ ├── AnalyticsDashboard.module.scss │ │ ├── UserManagement.jsx # Zarządzanie użytkownikami przez admina (tabela, dezaktywacja, reset hasła) │ │ ├── UserManagement.module.scss │ │ ├── Modal.jsx # Bazowy komponent modala (Portal, useCallback, Escape key, aria) │ │ ├── Modal.module.scss │ │ ├── StatusBadge.jsx # Odznaka statusu rezerwacji (warianty kolorów, rozmiary, aria-label) │ │ ├── StatusBadge.module.scss │ │ ├── StatusBadge.test.jsx # Testy RTL dla StatusBadge │ │ ├── ThemeToggle.jsx # Przycisk przełączania motywu (jasny/ciemny) │ │ ├── ThemeToggle.module.scss │ │ ├── DataRenderer.jsx # Render-prop: opakowuje useQuery, przekazuje dane przez children() │ │ ├── ErrorBoundary.jsx # Class component: łapie błędy runtime, wyświetla fallback UI │ │ ├── ErrorBoundary.module.scss │ │ ├── LoadingSpinner.jsx # Animowany spinner ładowania │ │ ├── LoadingSpinner.module.scss │ │ └── ProtectedRoute.jsx # Guard routingu: sprawdza rolę i przekierowuje │ ├── stories/ │ │ ├── StatusBadge.stories.jsx # Storybook: wszystkie warianty odznaki statusu │ │ ├── Modal.stories.jsx # Storybook: modal informacyjny i destrukcyjny │ │ └── ThemeToggle.stories.jsx # Storybook: przełącznik motywu │ └── tests/ │ ├── LoginPage.test.jsx # RTL: formularz logowania, błędy walidacji │ ├── BookingForm.test.jsx # RTL: formularz rezerwacji, react-hook-form │ ├── ProtectedRoute.test.jsx # RTL: ochrona tras, przekierowania │ └── StatusBadge.test.jsx # RTL: warianty statusu └── public/ └── index.html # Zawiera
i
``` --- ## Architektura danych ### REST (json-server :3001) - `GET/POST /reservations` – rezerwacje - `GET /services` – usługi - `GET/PATCH /users` – użytkownicy - Filtrowanie przez query params: `?userId=`, `?serviceId=`, `?date=` ### GraphQL (Apollo Client – in-memory, bez zewnętrznego serwera) Schema i resolvery zdefiniowane w `main.jsx`, wykonywane lokalnie przez `SchemaLink`: ```graphql type Query { userProfile(id: ID!): UserProfile serviceReviews(serviceId: String!): [Review!]! userReviews(userId: String!): [Review!]! } type Mutation { submitReview(reservationId: String!, serviceId: String!, ...): Review! } ``` --- ## Lista wymagań i ich realizacja ### Wymagania funkcjonalne (11) | # | Kryterium | Realizacja | Status | |---|-----------|-----------|--------| | F1 | **System uwierzytelniania i autoryzacji** | `AuthContext.jsx` – logowanie e-mail + 2FA (kod wyświetlany w UI); role `client`/`admin`; sesja w `localStorage`; rejestracja z weryfikacją e-mail (`RegisterPage.jsx`); `ProtectedRoute` blokuje dostęp wg roli | [OK] | | F2 | **Zarządzanie profilami użytkowników** | `ProfileEditModal.jsx` – edycja danych (Formik+Zod, PATCH `/users`), 5 preferencji powiadomień (toggle switches: potwierdzenie, anulowanie, przypomnienie 24h, zmiana terminu, promocje); `ProfileView.jsx` – dane z GraphQL; historia w `ReservationsPage.jsx` | [OK] | | F3 | **Wyszukiwanie i przeglądanie dostępności** | `AvailabilitySearch.jsx` – filtracja po dacie i usłudze, siatka slotów, URL sync (`useSearchParams`); `SlotFinder.jsx` – ranking slotów w zakresie dat z preferencjami (rano/południe/wieczór), pasek score | [OK] | | F4 | **Proces rezerwacji** | `BookingWizard.jsx` – 4 kroki: wybór usługi, data+czas (blokada zajętych slotów), wymagania specjalne, podsumowanie z ceną; `PaymentModal.jsx` – 3 metody płatności, potwierdzenie z paragonem | [OK] | | F5 | **System płatności online** | `PaymentModal.jsx` – karta kredytowa (Formik, walidacja), Google Pay (symulacja), przelew bankowy (IBAN/BIC, numer referencyjny); depozyt 50% ceny; `transactionId` zapisywany w rezerwacji | [OK] | | F6 | **Zarządzanie rezerwacjami przez użytkowników** | `ReservationsPage.jsx` – filtry (wszystkie/nadchodzące/minione/anulowane), anulowanie z potwierdzeniem, `RescheduleModal.jsx` (zmiana terminu), "Book again" (re-book), Google Calendar link | [OK] | | F7 | **Panel zarządzania rezerwacjami (admin)** | `AdminPage.jsx` – tabela rezerwacji (Confirm/Cancel/Delete), `AdminCalendar.jsx` (miesiąc, panel dnia), blokowanie i zwalnianie terminów z datepickerem i listą | [OK] | | F8 | **Zarządzanie użytkownikami (admin)** | `UserManagement.jsx` – tabela użytkowników, dezaktywacja konta (toggle), symulacja resetu hasła; dostęp chroniony przez HOC `withRole(['admin'])` | [OK] | | F9 | **Analityka i raportowanie** | `AnalyticsDashboard.jsx` – statystyki (łączna liczba, potwierdzone, anulowane, przychód z depozytów, średnia ocena); wykresy słupkowe CSS; eksport CSV z nagłówkami | [OK] | | F10 | **Integracja z zewnętrznymi systemami** | Google Calendar: link `eventedit` generowany dynamicznie z datą/godziną/tytułem dla każdej nadchodzącej rezerwacji; pełne REST API dostępne dla zewnętrznych integracji | [OK] | | F11 | **System opinii i ocen** | `ReviewsSection.jsx` – ocena gwiazdkowa (1–5) + komentarz, zapis przez GraphQL mutation `submitReview`; pobieranie przez `serviceReviews` query; widoczne po rozwinięciu minionej rezerwacji | [OK] | ### Wymagania wizualne BIU ZAO (6) | # | Kryterium | Realizacja | Status | |---|-----------|-----------|--------| | V1 | **Spójny i nowoczesny interfejs** | Jeden design system: tokeny w `_variables.scss` (paleta primary/accent/gray, spacing 4px scale, typografia, cienie), spójne BEM, Lucide icons, karty z `border-radius`, modale z overlay | [OK] | | V2 | **Pełna responsywność** | 12 breakpointów w SCSS (`$bp-xs` 480px–`$bp-2xl` 1536px); grid w DashboardPage stackuje kolumny, tabela admina scrolluje poziomo, wizard adaptuje układ pól | [OK] | | V3 | **Animacje i efekty przejścia** | CSS `transition` na przyciskach/kartach/modalach; `@keyframes` pulse na wyróżnionej karcie rezerwacji; spinner ładowania CSS; hover lift (`box-shadow` + `transform`) | [OK] | | V4 | **Wizualny feedback dla interakcji** | `StatusBadge` kolorystycznie odróżnia statusy; `:disabled`/`:hover`/`:focus-visible` na wszystkich elementach interaktywnych; błędy inline w formularzach; spinner na przyciskach pending | [OK] | | V5 | **Estetyczne wykorzystanie SCSS** | SCSS Modules z BEM, `@use '../styles/variables' as *`, zagnieżdżone reguły `&__`, `&--`, CSS custom properties dla motywu (`--clr-bg`, `--clr-text` etc.), media queries przez zmienne | [OK] | | V6 | **Wykorzystanie wbudowanych komponentów** | Natywne ``, ``, `