377 lines
15 KiB
Markdown
377 lines
15 KiB
Markdown
# 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":
|
||
1. Kalendarz (tydzień/miesiąc, nawigacja ←/→/Dziś, toggle rozwinięcia) — styl ujednolicony z `MealPlanner`
|
||
2. Pora posiłku — chipy filtrowane do `allowedSlots` przepisu
|
||
3. 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
|
||
4. Przycisk "Dodaj" → zapis do `planStore` (z opcjonalnym obiektem `substitutions`)
|
||
|
||
**Model danych — wymienne składniki:**
|
||
- W `RECIPES`, składnik może mieć pole `alternatives: ['id1', 'id2', ...]` — tablica ID alternatywnych składników
|
||
- Przy dodawaniu do planera, wybrane zamienniki zapisywane są jako `substitutions: { originalId: chosenAltId }` w `planStore`
|
||
- 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:**
|
||
1. **Picker przepisów**: wyszukiwarka + sekcja "Ostatnio używane" + lista filtrowana do `allowedSlots`
|
||
2. **Składniki i spiżarnia**: porównanie potrzeb vs zapasy + prognoza tygodniowa (`computeFullForecast`) + "Dodaj braki" (dzień / tydzień)
|
||
3. **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" (z `purchasePack`)
|
||
|
||
**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.
|
||
|
||
1. Otwiera aplikację → widzi zakładkę **Przepisy** z siatką 9 kart
|
||
2. Przewija listę, czyta opisy i kalorie na kartach
|
||
3. Klika kartę "Serek wiejski z orzechami i owocami"
|
||
4. Widzi detal: składniki, kroki, wartości odżywcze
|
||
5. Przy orzechach, truskawkach i borówkach widzi ikonę shuffle — klika ją przy orzechach
|
||
6. Rozwija się lista alternatyw (laskowe, nerkowca, migdały, pekan) z wartościami odżywczymi — informacyjnie
|
||
7. Zmienia liczbę porcji z 1 na 2 → składniki i kcal się przeliczają
|
||
8. Przełącza zakładkę na "Kroki" → widzi numerowane kroki
|
||
9. Przełącza na "Wartości" → widzi makroskładniki ×2
|
||
10. 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.
|
||
|
||
1. Wpisuje "łosoś" → lista filtruje się do 1 karty
|
||
2. Kasuje tekst → wracają wszystkie
|
||
3. Klika ikonę filtrów → otwiera się overlay
|
||
4. Zaznacza "Kolacja" → aktualizuje się licznik wyników
|
||
5. Dodatkowo zaznacza tag "Wysokobiałkowe"
|
||
6. Ustawia suwak na max 25 min
|
||
7. Klika "Pokaż X wyników" → wraca do przefiltrowanej listy
|
||
8. Wybiera przepis i otwiera detal
|
||
|
||
---
|
||
|
||
### Scenariusz 3: Planowanie posiłków na tydzień
|
||
|
||
**Cel:** Użytkownik układa menu na kilka dni.
|
||
|
||
1. Przechodzi na zakładkę **Planer**
|
||
2. Widzi dzisiejszy dzień (demo-dane lub wcześniej zaplanowane)
|
||
3. Klika na przepis w slocie → otwiera się detal
|
||
4. Wraca ← do planera
|
||
5. Klika następny dzień w kalendarzu
|
||
6. Widzi puste sloty, klika "Dodaj przepis" przy Śniadaniu
|
||
7. Picker: wpisuje fragment nazwy, widzi "Ostatnio używane"
|
||
8. Wybiera przepis → pojawia się w slocie z kcal w nagłówku
|
||
9. Przy obiedzie klika "Pomijam" (je na mieście) → slot przygaszony
|
||
10. Klika "Składniki na ten dzień" → widzi braki vs spiżarnia + prognoza
|
||
11. Klika "Dodaj braki na dziś do listy" → toast potwierdzenia
|
||
12. Następnego dnia: "Kopiuj dzień" → wybiera dzień docelowy → gotowe
|
||
|
||
---
|
||
|
||
### Scenariusz 4: Zarządzanie spiżarnią
|
||
|
||
**Cel:** Użytkownik sprawdza co ma w domu.
|
||
|
||
1. Przechodzi na zakładkę **Spiżarnia**
|
||
2. Widzi chipy składników pogrupowane po kategorii
|
||
3. Włącza "Tylko na stanie" → widzi co ma
|
||
4. Klika "Płatki owsiane" → bottom sheet
|
||
5. Ustawia 500g (przyciskami ± lub inputem)
|
||
6. Zamyka → chip zmienił się na zielony z "500 g"
|
||
7. Chce dodać mleko na listę → klika "Dodaj na listę" w sheecie
|
||
|
||
---
|
||
|
||
### Scenariusz 5: Zakupy w sklepie
|
||
|
||
**Cel:** Użytkownik jest w sklepie, odznacza kupione.
|
||
|
||
1. Otwiera zakładkę **Zakupy**
|
||
2. Widzi listę kuchenną pogrupowaną po kategorii
|
||
3. Bierze mleko z półki → klika checkbox → przekreślenie
|
||
4. Widzi `sourceNote` z informacją skąd pozycja pochodzi
|
||
5. Ilość się nie zgadza — klika na ilość → prompt → poprawia
|
||
6. Kupuje dalsze pozycje
|
||
|
||
---
|
||
|
||
### Scenariusz 6: Po zakupach — przeniesienie do spiżarni
|
||
|
||
**Cel:** Użytkownik wrócił ze sklepu, aktualizuje spiżarnię.
|
||
|
||
1. Otwiera **Zakupy** → widzi zaznaczone pozycje
|
||
2. Pojawia się pasek: "Kupione → spiżarnia" i "Wyczyść kupione"
|
||
3. Klika "Kupione → spiżarnia" → potwierdzenie z podglądem pozycji
|
||
4. Potwierdza → toast "Przeniesiono X pozycji"
|
||
5. Kupione znikają z listy
|
||
6. Przechodzi do **Spiżarni** → stany zaktualizowane
|
||
7. Wraca do **Planera** → braki zmniejszone
|
||
|
||
---
|
||
|
||
### Scenariusz 7: Gotowanie z przepisu
|
||
|
||
**Cel:** Użytkownik gotuje, sprawdza przepis krok po kroku.
|
||
|
||
1. Otwiera **Planer** → dzisiejszy dzień
|
||
2. Klika przepis w slocie Kolacja
|
||
3. Otwiera się detal → przełącza na "Kroki"
|
||
4. Czyta krok po kroku
|
||
5. Sprawdza ilość składnika → przełącza na "Składniki"
|
||
6. Wraca na "Kroki"
|
||
|
||
---
|
||
|
||
### Scenariusz 8: Dodanie przepisu do planera z widoku detalu
|
||
|
||
**Cel:** Użytkownik znalazł przepis i chce go zaplanować.
|
||
|
||
1. Przegląda **Przepisy** → otwiera detal "Serek wiejski z orzechami i owocami"
|
||
2. Klika "Zaplanuj" (górny przycisk)
|
||
3. Otwiera się bottom sheet z kalendarzem (domyślnie widok tygodnia, można rozwinąć do miesiąca)
|
||
4. Wybiera dzień w kalendarzu
|
||
5. Wybiera porę posiłku (np. "Śniadanie")
|
||
6. Widzi sekcję "Wymienne składniki" — 3 kompaktowe karty (orzechy, truskawki, borówki) z aktualnym wyborem
|
||
7. Klika kartę "Orzechy włoskie" → rozwija się lista opcji (włoskie, laskowe, nerkowca, migdały, pekan) z wartościami odżywczymi i radio-przyciskami
|
||
8. Wybiera "Migdały" → karta się zwija, wybrany składnik zmienia się na "Migdały" z amber tłem
|
||
9. 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ć.
|
||
|
||
1. Otwiera **Spiżarnię** → widzi co ma
|
||
2. Chciałby kliknąć "Co mogę ugotować?" → **takiej funkcji jeszcze nie ma**
|
||
3. 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) |
|