Przejdź do głównej zawartości

Dostępność trenerów (widok administratora)

Wspólny, kolorowy kalendarz tygodniowy pokazujący dostępność wszystkich trenerów w jednym miejscu, z możliwością edycji.

👤 Instrukcja dla pracownika / administratora

Ścieżka: Dashboard ➔ Kalendarz ➔ Dostępność trenerów

Zamiast osobnego kalendarza dla każdego trenera, administrator i pracownik widzą jeden wspólny kalendarz tygodniowy, na którym zebrana jest dostępność wszystkich trenerów.

Jak czytać kalendarz

  • Każdy trener ma przypisany osobny, stały kolor. Kolor jest przypisywany automatycznie i nie zmienia się przy filtrowaniu.
  • Dostępność wyświetla się jako bloki przypominające rezerwacje — z imieniem trenera i zakresem godzin (np. Sławek 9:00–18:00).
  • Gdy kilku trenerów jest dostępnych tego samego dnia, ich bloki układają się obok siebie w kolumnach, więc żaden się nie przysłania.
  • Nad kalendarzem znajduje się legenda z kolorem i imieniem każdego widocznego trenera.
  • Zaplanowane zajęcia trenera pokazywane są jako blok w jego kolorze z ukośnym wzorem (zajęcia nie są edytowalne z tego widoku).

Filtrowanie

Lista rozwijana „Wybierz trenerów” pozwala zawęzić kalendarz do jednego lub kilku wybranych trenerów. Brak zaznaczenia oznacza wyświetlenie wszystkich trenerów. Kolory trenerów pozostają niezmienione po zawężeniu listy.

Selektory miasta i lokalizacji w górnym pasku ograniczają kalendarz do wybranej ulicy. Lista trenerów pokazuje tylko osoby, które mogą prowadzić zajęcia indywidualne w tej lokalizacji.

Edycja i dodawanie dostępności

  • Edycja: kliknij blok dostępności, aby otworzyć okno edycji (zmiana godzin, cykliczności lub usunięcie).
  • Dodawanie w miejscu: kliknij pustą część kolumny dnia — otworzy się okno dodawania z wstępnie ustawioną datą i godziną. Jeśli filtr zawężono do jednego trenera, zostanie on wybrany automatycznie; w przeciwnym razie należy wskazać trenera na liście.
  • Dodawanie z przycisku: przycisk „Dodaj dostępność” otwiera okno, w którym wybiera się trenera, datę i godziny.
  • Każdy nowy przedział wymaga wskazania lokalizacji. Lista zawiera wyłącznie ulice przypisane do wybranego trenera.

Przypisanie trenera do lokalizacji

W formularzu pracownika włącz opcję „Może prowadzić zajęcia indywidualne”, a następnie wybierz lokalizacje zajęć indywidualnych. Brak wyboru oznacza wszystkie lokalizacje w mieście pracownika.

Widok mobilny

Na urządzeniach mobilnych kalendarz przełącza się w agendę jednego dnia, stylizowaną spójnie z widokiem Grafik (Schedule) — jednolicie dla administratora i trenera:

  • U góry widnieje pełna data wybranego dnia oraz pigułka „Dziś”.
  • Poniżej znajduje się pasek dni tygodnia (zaznaczony dzień w kółku akcentu, bieżący dzień z obwódką). Tydzień zmienia się strzałkami lub gestem przesunięcia (swipe); dotknięcie dnia przełącza wyświetlaną agendę.
  • Pod paskiem widać pozycje wybranego dnia: dla administratora są to kolorowe wpisy trenerów (imię + zakres godzin), dla trenera — bloki Dostępny / Zajęcia / wolne przedziały.
  • Edycja: dotknij pozycji dostępności, aby otworzyć okno edycji. Zajęcia są tylko do odczytu.
  • Dodawanie: trener korzysta z pływającego przycisku (+) w prawym dolnym rogu; administrator z przycisku „Dodaj” w nagłówku (wstępnie ustawia wybrany dzień). W widoku trenera można też dotknąć wolnego przedziału.

🛠️ Dokumentacja techniczna

Komponenty

  • app/(dashboard)/dashboard/availability/page.tsx — server component; pobiera dane przez getInstructorsWithScheduleData(currentWeekStart, weekEndDate) i renderuje AdminAvailabilityView dla ról ADMIN / BACKOFFICE.
  • app/(dashboard)/dashboard/availability/components/AdminAvailabilityView.tsx — nawigacja po tygodniach, filtr trenerów (MultiSelect), budowanie mapy kolorów, legenda oraz podłączenie okien dodawania/edycji.
  • components/availability/CombinedWeeklyCalendar.tsx — wspólny kalendarz: rozwijanie dostępności cyklicznej, scalanie sąsiadujących przedziałów, układ kolumnowy nakładających się bloków oraz warianty desktop (siatka) i mobile (agenda jednego dnia z paskiem dni).
  • components/availability/MobileWeekDayStrip.tsx — współdzielony pasek wyboru dnia i nawigacji tygodnia używany w mobilnych wariantach CombinedWeeklyCalendar (admin) i WeeklyCalendarMobile (trener), zapewniający spójny UX.
  • components/availability/AddAvailabilityDialog.tsx — obsługuje opcjonalny wybór trenera (instructorOptions), gdy dodawanie odbywa się z widoku zbiorczego.
  • components/layout/global-city-select-client.tsx — udostępnia selektor ulicy na stronie dostępności i zapisuje wybór w parametrach city oraz street.
  • lib/utils/instructor-colors.ts — paleta kolorów (INSTRUCTOR_COLOR_PALETTE) oraz buildInstructorColorMap(instructorIds) przypisujący kolor deterministycznie wg indeksu.

Przypisywanie kolorów

Kolory przypisywane są na podstawie listy trenerów posortowanej alfabetycznie po nazwisku, indeksem do palety (index % długość palety). Sortowanie odbywa się przed filtrowaniem, dzięki czemu kolor danego trenera jest stały niezależnie od aktywnego filtra.

Układ nakładających się bloków

Zdarzenia w obrębie jednego dnia (dostępności + zajęcia) są grupowane w „klastry” nachodzących na siebie przedziałów. W klastrze każdemu zdarzeniu przydzielana jest pierwsza wolna kolumna (lane), a szerokość bloku to 100% / liczba kolumn w klastrze. Gwarantuje to, że nakładające się bloki nie zasłaniają się wzajemnie.

Dane

Typy InstructorAvailabilitySlot i InstructorGame pochodzą z lib/actions/instructor-schedule.ts. Rekord dostępności zawiera city i street; starsze rekordy z wartościami NULL są traktowane jako dostępność wspólna dla wszystkich lokalizacji. Dostępność cykliczna (is_recurring, recurrence_type, recurrence_end_date) jest rozwijana po stronie klienta na zakres wyświetlanego tygodnia. Zapis/edycja/usuwanie korzystają z akcji createAvailabilitySlot, updateAvailabilitySlot, deleteAvailabilitySlot.

Przypisane ulice są przechowywane w Auth0 user_metadata.individual_training_streets. Pusta tablica zachowuje zgodność wsteczną i oznacza wszystkie ulice w preferred_city. Wyszukiwanie zajęć indywidualnych filtruje jednocześnie trenerów, dostępność i korty według wybranej ulicy.