diff --git a/CLAUDE.md b/CLAUDE.md index a62f26a..e9b7f25 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -73,11 +73,12 @@ cd client && yarn build # tsc --noEmit + vite build → client/dist ### Client (client/src/) - **Entry:** `index.tsx` → `AppRoutes.tsx`; `Login.tsx` je přihlašovací obrazovka - **Pages:** `pages/` — `DayPage` (přehled dne se záložkami Příjem/Výdej), + `MealGroupsPage` (`/jidla` — seznam jídel podle názvu a zdroje s filtrem zdroje, + hromadným doplněním údajů a přejmenováním), `TemplatesPage` (šablony tréninků a recepty), `ProfilePage` (Profil — ukazatele, vývoj hmotnosti, tělesné údaje, cíle a klidový výdej), `StatsPage` (statistiky se záložkami Příjem / Výdej / Útrata a import; panely - `IntakeStatsPanel`, `ActivityStatsPanel`, `SpendingStatsPanel`), - `MealGroupsPage` (`/statistiky/doplneni` — hromadné doplnění údajů jídel) + `IntakeStatsPanel`, `ActivityStatsPanel`, `SpendingStatsPanel`) - **Components:** `components/` (Header, CalorieLookup, MealSuggestions, NutrientsFieldset) a `components/modals/` (MealModal, ActivityModal, ApplyWorkoutModal, ApplyMealModal — výběr z historie a receptů, SettingsModal, ImportModal) @@ -267,9 +268,12 @@ takže `DayPage` si vystačí s jedním voláním. Hotová jídla (objednaná, koupená) **nemají šablony**. Při zakládání jídla se k rozepsanému názvu nabízí historie: `getMealHistory` v `meals.ts` -(`GET /api/meals/history`) projde všechna jídla uživatele a každý název vrátí -jednou (`MealSuggestion`). Názvy se porovnávají znormalizované přes -`normalizeName`, hodnoty jsou z **posledního** záznamu toho jména (cena i gramáž +(`GET /api/meals/history`) projde všechna jídla uživatele a každou dvojici +**název a zdroj** vrátí jednou (`MealSuggestion`). Stejnojmenné jídlo z jiného +zdroje (tikka masala z Everestu a z Namaste) je jiné jídlo a nikde se s ním +neslučuje — ani v návrzích, ani v seznamu jídel, ani při `fillSameNameMeals`; +na klientovi to hlídá `getMealKey` v `Utils.tsx`. Porovnává se znormalizovaně +přes `normalizeName`, hodnoty jsou z **posledního** záznamu (cena i gramáž se časem mění) a řadí se od nejčastěji jedených. Návrh nese jen to, co popisuje jídlo samo — **chod, datum, násobek ani poznámku @@ -283,10 +287,10 @@ Návrhy se nabízejí i při **úpravě** jídla, ale až po změně názvu, a d prázdná pole (`mergeSuggestion` v `MealModal`) — slouží k přejmenování naimportovaného jídla, jehož cena a zdroj jsou skutečné. Po uložení jídla s kaloriemi `DayPage` nabídne (`FillSameNameOffer`) doplnit stejné hodnoty do -ostatních jídel stejného názvu, která je nemají (`fillSameNameMeals`, +ostatních jídel stejného názvu a zdroje, která je nemají (`fillSameNameMeals`, `POST /api/meals/fillSameName`); jídla s kaloriemi se nepřepisují. -**Hromadné doplnění** (`MealGroupsPage`, odkaz ze Statistik → Příjem) seskupí +**Seznam jídel** (`MealGroupsPage`, položka Jídla v hlavičce) seskupí jídla podle znormalizovaného názvu **a zdroje** (`getMealGroups`, `GET /api/meals/groups`) a ukáže, kolika chybí kalorie, gramáž a živiny. Skupina nese i dny, kdy se jídlo jedlo (`MealGroup.days`, s příznakem neúplných @@ -297,6 +301,12 @@ jídlům bez kalorií (jinak by dopočet přepsal ručně zadané kalorie), živ jednotlivých položkách. Předvyplněné hodnoty jsou z nejnovějšího jídla skupiny; energie a živiny bez nich i z jídla stejného názvu odjinud, sazba a gramáž ne. +Druhou akcí skupiny je **přejmenování** (`renameMealGroup`, +`POST /api/meals/renameGroup`) — změní název i zdroj všem jídlům skupiny ve +všech dnech. Je oddělené od doplnění schválně: doplnění jen připisuje, co chybí, +přejmenování přepisuje. Když nový název a zdroj patří jiné skupině, jídla se do +ní sloučí (formulář na to předem upozorní). + Pole Zdroj (`SourceInput`) nabízí zdroje z historie (`getMealSources`, `GET /api/meals/sources`, nejčastější první) a podniky se sazbou z nastavení; psát jde i nový. diff --git a/client/src/AppRoutes.tsx b/client/src/AppRoutes.tsx index 28766e0..d5dc294 100644 --- a/client/src/AppRoutes.tsx +++ b/client/src/AppRoutes.tsx @@ -8,7 +8,7 @@ import StatsPage from "./pages/StatsPage"; import TemplatesPage from "./pages/TemplatesPage"; import ProfilePage from "./pages/ProfilePage"; import MealGroupsPage from "./pages/MealGroupsPage"; -import { DEN_URL, DOPLNENI_JIDEL_URL, PROFIL_URL, SABLONY_URL, STATISTIKY_URL } from "./routes"; +import { DEN_URL, JIDLA_URL, PROFIL_URL, SABLONY_URL, STATISTIKY_URL } from "./routes"; export default function AppRoutes() { const auth = useAuth(); @@ -23,10 +23,10 @@ export default function AppRoutes() {
- Jídla se stejným názvem a zdrojem doplníte najednou — kalorie, gramáž i nutriční hodnoty + Všechna jídla podle názvu a zdroje — údaje doplníte nebo název změníte ve všech dnech najednou
| Zdroj | -Jídel | -Útrata | -
|---|---|---|
| {total.key} | -{total.count} | -{formatPriceShort(total.price)} | -