feat: split jídel
feat: graf příjmů
This commit is contained in:
1 parent
bc85a37fc0
commit
b880b36edd
32 files changed
+2048
-262
No files matched your search
@@ -75,16 +75,18 @@ cd client && yarn build # tsc --noEmit + vite build → client/dist
|
||||
- **Pages:** `pages/` — `DayPage` (přehled dne se záložkami Příjem/Výdej),
|
||||
`TemplatesPage` (šablony tréninků a recepty), `ProfilePage` (Profil — ukazatele,
|
||||
vývoj hmotnosti, tělesné údaje, cíle a klidový výdej),
|
||||
`StatsPage` (statistiky příjmu a výdeje + import; výdej v `ActivityStatsPanel`),
|
||||
`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)
|
||||
- **Components:** `components/` (Header, CalorieLookup, MealSuggestions, NutrientsFieldset)
|
||||
a `components/modals/` (MealModal, ActivityModal, ApplyWorkoutModal, ApplyMealModal —
|
||||
výběr z historie a receptů, SettingsModal, ImportModal)
|
||||
- **Klientské enumy** patří do `enums.ts` jako TypeScript `enum` s mapou popisků,
|
||||
ne jako inline union u komponenty (`DayTab`, `StatsRange`)
|
||||
ne jako inline union u komponenty (`DayTab`, `StatsTab`, `StatsRange`)
|
||||
- **Context:** `context/auth.tsx` (JWT), `context/settings.tsx` (světlý/tmavý motiv)
|
||||
- **Routing:** konstanty adres jsou v `routes.ts`, ne v `AppRoutes.tsx` — hlavička
|
||||
je potřebuje a kruhový import by je nechal nedefinované
|
||||
je potřebuje a kruhový import by je nechal nedefinované. Přehled dne čte datum
|
||||
z parametru `?datum=YYYY-MM-DD` (`getDayUrl`), na konkrétní den se tak dá odkázat
|
||||
- **Styling:** Bootstrap 5 + React Bootstrap + SCSS; design systém a proměnné
|
||||
`--ft-*` jsou v `App.scss`, stránkové styly co-located vedle komponent
|
||||
- **API:** přes OpenAPI SDK z `types/gen/`
|
||||
@@ -250,6 +252,14 @@ stejný cvik dvakrát. Smazání všech cviků šablony ve dni `dropOrphanedPlan
|
||||
bere jako vrácené použití a plán zahodí. Aktivity ze šablony bez plánu (cvik
|
||||
přesunutý z jiného dne) se počítají jako splněné přesně dle plánu.
|
||||
|
||||
**Statistiky příjmu** (`getIntakeStats`, `GET /api/stats/intake`) jsou protějšek
|
||||
výdeje: příjem po chodech a zdrojích, živiny a porovnání s výdejem. Výdej
|
||||
a bilance se počítají **jen za dny, kdy má aspoň jedno jídlo kalorie**
|
||||
(`caloriesDayCount`) — den bez zápisu nebo s jídly z importu bez kalorií by jinak
|
||||
vypadal jako deficit celého výdeje. Ze stejného důvodu z nich vycházejí průměry.
|
||||
Klidový výdej je k hmotnosti platné v daný den (`getBasalOn` v `dayOverview.ts`).
|
||||
Peníze za jídlo jsou na samostatné záložce Útrata (`getFoodStats`, `/api/stats/summary`).
|
||||
|
||||
`GET /api/day?date=` vrací `DayOverview` se vším naráz (jídlo, pohyb, bilance),
|
||||
takže `DayPage` si vystačí s jedním voláním.
|
||||
|
||||
@@ -279,6 +289,8 @@ ostatních jídel stejného názvu, která je nemají (`fillSameNameMeals`,
|
||||
**Hromadné doplnění** (`MealGroupsPage`, odkaz ze Statistik → Příjem) 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
|
||||
údajů), a stránka je nabízí jako odkazy na přehled dne v nové záložce.
|
||||
`fillMealGroup` (`POST /api/meals/fillGroup`) doplní do skupiny **jen chybějící
|
||||
hodnoty**: gramáž ne tam, kde jde dopočítat z vlastní ceny a sazby, energii jen
|
||||
jídlům bez kalorií (jinak by dopočet přepsal ručně zadané kalorie), živiny po
|
||||
@@ -343,6 +355,13 @@ ve všech třech formátech, které Luncher exportuje (XLSX, CSV, JSON — viz
|
||||
dnech jsou (`existing`). Uživatel v něm řádky odškrtá a ostrý import dostane
|
||||
jen `selectedKeys`.
|
||||
|
||||
Jídlo, které Luncher zapsal jako jedno ("Chicken tikka massala+garlic nun"),
|
||||
jde v přehledu dne rozdělit (`MealSplitModal`, `splitMeal`, `POST /api/meals/split`)
|
||||
— import se kvůli tomu nekomplikuje. Původní záznam si nechá `importKey`, takže
|
||||
ho režim PRIDAT znovu nezaloží; odštěpená část dostane jen `importSource`, aby ji
|
||||
režim NAHRADIT odebral spolu s původním a nevzniklo jídlo dvakrát. Cena se mezi
|
||||
části nedopočítává, rozdělí se jen na vyžádání (napůl).
|
||||
|
||||
**Když se změní formát exportu v Luncheru, je potřeba upravit i tento parser**
|
||||
a testy v `server/src/tests/luncherImport.test.ts`, které si export sestavují
|
||||
přesně tak, jak ho Luncher generuje.
|
||||
|
||||
Reference in new issue
Block a user