15 KiB
Widoki i scenariusze — Aplikacja Kuchenna
Cel dokumentu: Opis wszystkich widoków aplikacji z obecnym stanem, scenariusze użytkownika i znane problemy. Odniesienie dla dalszego rozwoju.
Kontekst projektu: To jest prototyp / mockup — celem jest wypracowanie UX, logiki widoków i przepływów użytkownika. Finalna aplikacja będzie pisana w innym języku z backendem. Wartość tego prototypu to przede wszystkim: struktura widoków, scenariusze, model danych i decyzje UX — nie kod sam w sobie.
1. Profil użytkownika
| Cecha | Opis |
|---|---|
| Liczba osób | 1 (gotuje dla siebie) |
| Planowanie | Elastyczne, 1–7 dni do przodu |
| Posiłki | 5 slotów (śniadanie, drugie śniadanie, obiad, przekąska, kolacja) |
| Powtarzalność | Duża (zwłaszcza śniadania) — kopiowanie dnia kluczowe |
| Styl gotowania | Hybrydowy: trochę meal-prep, trochę na bieżąco |
| Zakupy | Mieszane: duże zakupy + uzupełnienia w tygodniu |
| Cel dietetyczny | Utrzymanie wagi, śledzenie per posiłek |
| Pomijanie posiłków | Jawne "Pomijam" (jedzenie na mieście itp.) |
| Przepisy | Katalog wbudowany (9 przepisów, 24 składniki), bez edytora |
2. Architektura i stos technologiczny
| Warstwa | Technologia |
|---|---|
| Frontend | Plain HTML + ES modules, imperatywna manipulacja DOM |
| Style | Tailwind CSS (CDN) + inline <style> w index.html, Font Awesome 6 (CDN) |
| Dane | Statyczny katalog js/data/catalog.js (INGREDIENTS + RECIPES z opcjonalnymi alternatives per składnik), localStorage |
| Stan | Moduły-closure (filterState, state w planerze) + localStorage przez serwisy |
| Komunikacja widoków | Globalne callbacki na window (refreshPlanner, refreshPantry, refreshShopping, openRecipeDetail itp.) |
| PWA | manifest.webmanifest + sw.js (network-only fetch, spełnia warunek instalowalności) |
| Deploy | Docker + nginx:alpine, Gitea CI/CD |
| Język UI | Polski |
Struktura plików
index.html ← jedyny plik HTML, shell aplikacji
js/
app.js ← entry point, montuje widoki, setupTabs()
storageKeys.js ← klucze localStorage
views/
RecipeList.js ← lista przepisów
Filter.js ← overlay filtrów
RecipeDetail.js ← detal przepisu (slide-in overlay)
MealPlanner.js ← planer posiłków + kalendarz
Pantry.js ← spiżarnia
Shopping.js ← listy zakupów
services/
planStore.js ← load/save planów posiłków
pantryShopping.js ← logika spiżarni i list zakupów
planIngredients.js ← analityka: sumy kalorii, braki, prognoza
dateUtils.js ← narzędzia dat (poniedziałek jako start tygodnia)
planner/
mealSlots.js ← definicja 5 slotów (id, label, icon)
data/
catalog.js ← INGREDIENTS, RECIPES, helpery
ui/
toast.js ← showAppToast()
3. Przegląd widoków
3.1 Przepisy (RecipeList)
Lokalizacja: js/views/RecipeList.js
Siatka 2-kolumnowa kart przepisów generowana dynamicznie z RECIPES. Każda karta zawiera miniaturę (placeholder), tytuł, opis, czas przygotowania, kalorie, chipy slotów. Kliknięcie otwiera detal.
Elementy:
- Wyszukiwarka (real-time, po tytule i tagach)
- Przycisk filtrów (otwiera overlay)
- Siatka kart
- Empty state gdy brak wyników
Stan: Kompletny.
3.2 Filtry (Filter)
Lokalizacja: js/views/Filter.js
Full-screen overlay (z-50) z chipami pór posiłku, tagami dietetycznymi i suwakiem czasu. Filtr zamknięty przyciskiem ← odrzuca niezapisane zmiany; "Pokaż X wyników" aplikuje i zamyka.
Elementy:
- Chipy: pory posiłku (z
MEAL_SLOTS) - Chipy: tagi dietetyczne (zbierane dynamicznie z
RECIPES) - Suwak: maksymalny czas przygotowania (5–120 min)
- Przycisk "Wyczyść" + "Pokaż X wyników"
Stan: Kompletny.
3.3 Szczegóły przepisu (RecipeDetail)
Lokalizacja: js/views/RecipeDetail.js
Slide-in overlay z detalami przepisu. Trzy zakładki: Składniki, Kroki, Wartości.
Elementy:
- Hero (placeholder) + strzałka powrotu + przycisk "Zaplanuj"
- Tytuł, tagi (sloty + tagi przepisu), czas, kcal
- Selektor porcji (± , zakres 1–12) z przeliczaniem składników i wartości
- Zakładka Składniki: lista read-only (bez checkboxów, bez badge'ów spiżarni). Składniki z wymiennymi wariantami mają ikonę shuffle — kliknięcie rozwija karty z alternatywami i ich wartościami odżywczymi (informacyjnie, bez możliwości wyboru)
- Zakładka Kroki: numerowane kroki
- Zakładka Wartości: kcal/białko/tłuszcze/węglowodany × porcje
- Bottom sheet "Zaplanuj":
- Kalendarz (tydzień/miesiąc, nawigacja ←/→/Dziś, toggle rozwinięcia) — styl ujednolicony z
MealPlanner - Pora posiłku — chipy filtrowane do
allowedSlotsprzepisu - Wymienne składniki (opcjonalne, widoczne tylko gdy przepis ma
alternatives) — kompaktowe karty per składnik wyświetlające aktualny wybór z wartościami odżywczymi; kliknięcie rozwija listę opcji z radio-przyciskami; po wyborze karta się zwija; zmieniony składnik ma amber tło - Przycisk "Dodaj" → zapis do
planStore(z opcjonalnym obiektemsubstitutions)
- Kalendarz (tydzień/miesiąc, nawigacja ←/→/Dziś, toggle rozwinięcia) — styl ujednolicony z
Model danych — wymienne składniki:
- W
RECIPES, składnik może mieć polealternatives: ['id1', 'id2', ...]— tablica ID alternatywnych składników - Przy dodawaniu do planera, wybrane zamienniki zapisywane są jako
substitutions: { originalId: chosenAltId }wplanStore - Przykład: serek wiejski ma 3 wymienne składniki — orzechy (5 opcji), truskawki (banany), borówki (jagody)
Stan: Kompletny.
3.4 Planer posiłków (MealPlanner)
Lokalizacja: js/views/MealPlanner.js
Kalendarz (tydzień/miesiąc) + plan dnia z 5 slotami posiłków.
Elementy kalendarza:
- Widok tygodnia ↔ miesiąca (swipe góra/dół na
#calendar-swipe-zone) - Nawigacja: ←/→ + "Dziś"
- Kropki pod dniem = zaplanowane posiłki
Elementy planu dnia:
- Nagłówek dnia + przycisk "Kopiuj dzień"
- Karta podsumowania kalorycznego (kcal + makro, rozwijalne szczegóły)
- "Składniki na ten dzień" (badge z liczbą braków vs "OK")
- Sloty posiłków (5 slotów z
MEAL_SLOTS):- Kcal per slot w nagłówku
- Karty przepisów z porcjami (±), kcal, czasem, przyciskiem usuwania
- Kliknięcie nazwy przepisu →
RecipeDetail - "Dodaj przepis" / "Dodaj kolejny"
- "Pomijam" przy pustym slocie → slot przygaszony z "Cofnij"
Bottom sheety:
- Picker przepisów: wyszukiwarka + sekcja "Ostatnio używane" + lista filtrowana do
allowedSlots - Składniki i spiżarnia: porównanie potrzeb vs zapasy + prognoza tygodniowa (
computeFullForecast) + "Dodaj braki" (dzień / tydzień) - Kopiuj plan dnia: lista 13 dni (3 wstecz, 10 do przodu) → kopiuje cały dzień (w tym statusy "Pominięto")
Demo: seedDemoIfEmpty wypełnia dzisiejszy dzień danymi demo gdy localStorage jest pusty.
Stan: Kompletny.
3.5 Spiżarnia (Pantry)
Lokalizacja: js/views/Pantry.js
Przeglądanie i edycja stanów magazynowych składników.
Elementy:
- Wyszukiwarka
- Chipy filtrów kategorii (multi-select)
- Toggle "Tylko na stanie"
- Siatka chipów składników pogrupowana po kategorii (kolor wg stanu)
- Bottom sheet edycji (
#pv2-edit-sheet): ± z krokiem (pantryQtyStep), input numeryczny, opcjonalne wartości odżywcze (per 100g), "Dodaj na listę zakupów" (zpurchasePack)
Stan: Kompletny.
3.6 Zakupy (Shopping)
Lokalizacja: js/views/Shopping.js
Zarządzanie listami zakupów — jedna stała lista kuchenna + dowolna liczba list freeform.
Elementy:
- Selektor aktywnej listy (dropdown)
- Przycisk "Nowa lista" (freeform) + usuwanie list (nie dotyczy kuchennej)
- Lista kuchenna (
KITCHEN_LIST_ID): pogrupowana po kategorii, checkbox, edycja ilości (klik → prompt), usuwanie pozycji - Pasek akcji (widoczny gdy są zaznaczone pozycje): "Kupione → spiżarnia" (z potwierdzeniem i podglądem) + "Wyczyść kupione"
- Lista freeform: pozycje tekstowe z opcjonalną notatką, checkbox
Stan: Kompletny.
4. Przepływy między widokami
Przepisy ──[klik kartę]──→ Szczegóły przepisu
└──[Zaplanuj]──→ Bottom sheet (kalendarz + pora + opcjonalnie wymiana składników) → Planer
Planer ──[klik przepis w slocie]──→ Szczegóły przepisu
──[Składniki na ten dzień]──→ Sheet: porównanie z spiżarnią + prognoza
──[Dodaj braki do listy]──→ Zakupy (lista kuchenna)
──[Kopiuj dzień]──→ Sheet: wybór dnia docelowego
──[Dodaj przepis]──→ Sheet: picker przepisów
Spiżarnia ──[Dodaj na listę zakupów]──→ Zakupy
Zakupy ──[Kupione → spiżarnia]──→ Spiżarnia (stany zaktualizowane)
5. Scenariusze użytkownika
Scenariusz 1: Przeglądanie przepisów
Cel: Użytkownik otwiera apkę, chce zobaczyć co jest dostępne.
- Otwiera aplikację → widzi zakładkę Przepisy z siatką 9 kart
- Przewija listę, czyta opisy i kalorie na kartach
- Klika kartę "Serek wiejski z orzechami i owocami"
- Widzi detal: składniki, kroki, wartości odżywcze
- Przy orzechach, truskawkach i borówkach widzi ikonę shuffle — klika ją przy orzechach
- Rozwija się lista alternatyw (laskowe, nerkowca, migdały, pekan) z wartościami odżywczymi — informacyjnie
- Zmienia liczbę porcji z 1 na 2 → składniki i kcal się przeliczają
- Przełącza zakładkę na "Kroki" → widzi numerowane kroki
- Przełącza na "Wartości" → widzi makroskładniki ×2
- Wraca strzałką ← do listy
Uwagi:
- Brak zdjęć (szare placeholdery) — OK dla prototypu
- Po powrocie z detalu filtr/szukajka się utrzymują
Scenariusz 2: Szukanie przepisu na kolację
Cel: Użytkownik szuka czegoś konkretnego.
- Wpisuje "łosoś" → lista filtruje się do 1 karty
- Kasuje tekst → wracają wszystkie
- Klika ikonę filtrów → otwiera się overlay
- Zaznacza "Kolacja" → aktualizuje się licznik wyników
- Dodatkowo zaznacza tag "Wysokobiałkowe"
- Ustawia suwak na max 25 min
- Klika "Pokaż X wyników" → wraca do przefiltrowanej listy
- Wybiera przepis i otwiera detal
Scenariusz 3: Planowanie posiłków na tydzień
Cel: Użytkownik układa menu na kilka dni.
- Przechodzi na zakładkę Planer
- Widzi dzisiejszy dzień (demo-dane lub wcześniej zaplanowane)
- Klika na przepis w slocie → otwiera się detal
- Wraca ← do planera
- Klika następny dzień w kalendarzu
- Widzi puste sloty, klika "Dodaj przepis" przy Śniadaniu
- Picker: wpisuje fragment nazwy, widzi "Ostatnio używane"
- Wybiera przepis → pojawia się w slocie z kcal w nagłówku
- Przy obiedzie klika "Pomijam" (je na mieście) → slot przygaszony
- Klika "Składniki na ten dzień" → widzi braki vs spiżarnia + prognoza
- Klika "Dodaj braki na dziś do listy" → toast potwierdzenia
- Następnego dnia: "Kopiuj dzień" → wybiera dzień docelowy → gotowe
Scenariusz 4: Zarządzanie spiżarnią
Cel: Użytkownik sprawdza co ma w domu.
- Przechodzi na zakładkę Spiżarnia
- Widzi chipy składników pogrupowane po kategorii
- Włącza "Tylko na stanie" → widzi co ma
- Klika "Płatki owsiane" → bottom sheet
- Ustawia 500g (przyciskami ± lub inputem)
- Zamyka → chip zmienił się na zielony z "500 g"
- Chce dodać mleko na listę → klika "Dodaj na listę" w sheecie
Scenariusz 5: Zakupy w sklepie
Cel: Użytkownik jest w sklepie, odznacza kupione.
- Otwiera zakładkę Zakupy
- Widzi listę kuchenną pogrupowaną po kategorii
- Bierze mleko z półki → klika checkbox → przekreślenie
- Widzi
sourceNotez informacją skąd pozycja pochodzi - Ilość się nie zgadza — klika na ilość → prompt → poprawia
- Kupuje dalsze pozycje
Scenariusz 6: Po zakupach — przeniesienie do spiżarni
Cel: Użytkownik wrócił ze sklepu, aktualizuje spiżarnię.
- Otwiera Zakupy → widzi zaznaczone pozycje
- Pojawia się pasek: "Kupione → spiżarnia" i "Wyczyść kupione"
- Klika "Kupione → spiżarnia" → potwierdzenie z podglądem pozycji
- Potwierdza → toast "Przeniesiono X pozycji"
- Kupione znikają z listy
- Przechodzi do Spiżarni → stany zaktualizowane
- Wraca do Planera → braki zmniejszone
Scenariusz 7: Gotowanie z przepisu
Cel: Użytkownik gotuje, sprawdza przepis krok po kroku.
- Otwiera Planer → dzisiejszy dzień
- Klika przepis w slocie Kolacja
- Otwiera się detal → przełącza na "Kroki"
- Czyta krok po kroku
- Sprawdza ilość składnika → przełącza na "Składniki"
- Wraca na "Kroki"
Scenariusz 8: Dodanie przepisu do planera z widoku detalu
Cel: Użytkownik znalazł przepis i chce go zaplanować.
- Przegląda Przepisy → otwiera detal "Serek wiejski z orzechami i owocami"
- Klika "Zaplanuj" (górny przycisk)
- Otwiera się bottom sheet z kalendarzem (domyślnie widok tygodnia, można rozwinąć do miesiąca)
- Wybiera dzień w kalendarzu
- Wybiera porę posiłku (np. "Śniadanie")
- Widzi sekcję "Wymienne składniki" — 3 kompaktowe karty (orzechy, truskawki, borówki) z aktualnym wyborem
- Klika kartę "Orzechy włoskie" → rozwija się lista opcji (włoskie, laskowe, nerkowca, migdały, pekan) z wartościami odżywczymi i radio-przyciskami
- Wybiera "Migdały" → karta się zwija, wybrany składnik zmienia się na "Migdały" z amber tłem
- Klika "Dodaj" → toast potwierdzenia, sheet się zamyka, przepis dodany do planera z informacją o zamianie (substitutions)
Scenariusz 9: "Co mogę ugotować?"
Cel: Użytkownik ma coś w spiżarni, chce wiedzieć co da się z tego zrobić.
- Otwiera Spiżarnię → widzi co ma
- Chciałby kliknąć "Co mogę ugotować?" → takiej funkcji jeszcze nie ma
- Musi ręcznie sprawdzać przepisy
Propozycja: Filtr "Mam składniki" w widoku Przepisy.
6. Znane problemy i propozycje ulepszeń
Do poprawy (TODO)
| # | Problem | Dotyczy scenariusza |
|---|---|---|
| 1 | Brak wskaźnika aktywnych filtrów na ikonce (badge/kropka) | 2 |
| 2 | Po dodaniu braków do listy zakupów brak ochrony przed duplikacją (brak info "już dodano") | 3 |
| 3 | Kupione pozycje mieszają się z niekupionymi w tej samej grupie (brak separacji) | 5 |
| 4 | Brak podsumowania na liście zakupów ("Do kupienia: X, kupione: Y") | 5 |
| 5 | Brak undo przy "Kupione → spiżarnia" | 6 |
| 6 | Scroll spiżarni resetuje się po edycji (re-render) | 4 |
| 7 | "Kopiuj dzień" kopiuje też status "Pominięto" — może nie zawsze pożądane | 3 |
Propozycje nowych funkcji
| # | Funkcja | Opis |
|---|---|---|
| P1 | Tryb "krok po kroku" przy gotowaniu | Full-screen, jeden krok, swipe next + checkbox |
| P2 | Wake lock | Zapobiega wygaszeniu ekranu podczas gotowania |
| P3 | Filtr "Mam składniki" | W widoku Przepisy — pokaż co da się ugotować z aktualnej spiżarni |
| P4 | Większe elementy na liście zakupów | Ułatwienie obsługi w sklepie na telefonie |
| P5 | Edytor przepisów | Dodawanie własnych przepisów (poza wbudowanym katalogiem) |