Przejdź do głównej zawartości

Grafik na telefonie (recepcja)

Na telefonie pracownik zamiast pełnego kalendarza dostaje widok zoptymalizowany pod wąski ekran: przełącznik Oś czasu / Lista, pasek dni tygodnia i filtr kortów.

👤 Instrukcja dla pracownika (Recepcja / Administracja)

Co widać na kafelku w widoku „Lista”

Każdy wpis pokazuje:

  • nazwę zajęć, a przy rezerwacji kortu — imię i nazwisko klienta, który ją zarezerwował, wraz z ikoną pochodzenia konta (rezerwacja online, założona przez pracownika, klient lokalny, konto zsynchronizowane),
  • kort (kolorowa pigułka po prawej),
  • godziny, a przy rezerwacji dodatkowo nazwę typu rezerwacji (np. Rezerwacja, Trening indywidualny),
  • prowadzącego — przy rezerwacji tylko wtedy, gdy jest przypisany; przy pozostałych zajęciach Bez instruktora, jeśli go nie ma,
  • liczbę uczestników (zapisani/limit),
  • imiona i nazwiska uczestników (pierwsze dwa, reszta jako +N); przy rezerwacji pierwsze nazwisko jest tytułem kafelka, więc pigułki pokazują kolejne osoby. Przy nieaktywnym koncie dopisany jest (Nieaktywny).
  • kropkę rozliczenia przy każdym nazwisku — zielona, gdy ta osoba ma opłaconą pozycję, pomarańczowa, gdy nie ma,
  • status rozliczenia całych zajęć: zielona pigułka Opłacone, pomarańczowa Nieopłacone, gdy nikt nie zapłacił, oraz bursztynowa Opłacone 1/2, gdy zapłaciła tylko część uczestników.

Status rozliczenia pojawia się przy każdych zajęciach z aktywnymi uczestnikami — brak utworzonej płatności też jest liczony jako Nieopłacone, dzięki czemu ręcznie wpisana rezerwacja bez rozliczenia nie wygląda na opłaconą. Pigułki nie ma tylko tam, gdzie nikt nie jest zapisany.

Uczestnicy z anulowanym zapisem nie są brani pod uwagę — ani jako nazwa rezerwacji, ani na liście nazwisk, ani przy liczeniu rozliczenia.

Widok „Oś czasu”

Bloki na osi czasu są węższe, więc pokazują nazwę (przy rezerwacji — nazwisko klienta), godzinę rozpoczęcia oraz białą pigułkę z monetą: zielona moneta = opłacone, bursztynowa = częściowo, czerwona = nieopłacone. Przy pojedynczym korcie (filtr kortu) blok mieści dodatkowo typ rezerwacji, prowadzącego oraz ikony serii i notatki. Pełne szczegóły płatności otwierają się po kliknięciu bloku.

🛠️ Dokumentacja techniczna

  • Komponent: app/(dashboard)/dashboard/schedule/components/MobileScheduleIos.tsx (renderowany przez BookingClient tylko dla ekranów mobilnych i użytkowników z prawem edycji grafiku).
  • Dane pochodzą z getGamesByCity wywoływanego z includeAttendeeNames: true i includePayments: true (app/(dashboard)/dashboard/schedule/page.tsx oraz app/api/schedule/games/route.ts), więc kafelek nie robi dodatkowych zapytań.
  • attendeesNames[i] i payments[i] odpowiadają indeksem game.attendees[i]; wpisy z type === 'cancelled' są odfiltrowywane w activeAttendees oraz w paymentSummary.
  • payments[i] bywa null (uczestnik bez rekordu płatności) — taki wpis liczy się jako nieopłacony, tak samo jak w kalendarzu desktopowym.
  • paymentSummary zwraca { paidCount, total, settled }, co pozwala rozróżnić pełne, częściowe i brakujące rozliczenie.
  • Rozliczenie liczone jest przez PAID_PAYMENT_STATUSES z lib/analytics/payments.ts — ta sama lista statusów co w kalendarzu desktopowym (ScheduleCalendarComponents.tsx), dzięki czemu oba widoki pokazują ten sam stan.
  • Ikona pochodzenia konta to współdzielony components/created-type-icon.tsx (ten sam co w popoverze uczestników na desktopie).
  • Tłumaczenia: schedule.mobileIos.paid, schedule.mobileIos.unpaid, schedule.mobileIos.partiallyPaid i schedule.mobileIos.inactive w messages/pl.json i messages/en.json.
  • Testy: __tests__/app/schedule/mobile-schedule-ios-list-card.test.tsx.

Edycja z poziomu kafelka

  • Tapnięcie kafelka otwiera ReservationDetailsDialog albo ActivityDetailsDialog (BookingClient.handleSelectEvent), a przycisk Edytuj otwiera nad nim EditGameDialog, który na wąskim ekranie renderuje Drawer (vaul), a na desktopie Dialog (Radix).
  • Ten stos — drawer nad otwartym dialogiem — wymaga jednej kopii @radix-ui/react-dismissable-layer w node_modules. Przy dwóch kopiach na document.body zostaje pointer-events: none i aplikacja przestaje reagować na dotyk. Szczegóły i sposób weryfikacji: Drawer nad dialogiem.