IntersectionObserver haalt nu offset+=batch op via API ipv allItems
slicen. Bij een zoekopdracht wordt eerst de API geraadpleegd (paginated
fetchFoodPage), en bij scrollen worden volgende pagina's opgehaald.
Bij API-falen valt de code terug op de lokale client-side filtering.
Wijzigingen:
- SEARCH_PAGE_SIZE 50 → 200
- fetchFoodPage() — nieuwe async functie voor paginated API calls
- renderZoeken() — async met API try/fallback pad
- setupSearchObserver — async, API-aware via searchTotal flag
- appendSearchBatchFromApi / appendSearchBatchLocal — gesplitst
- resetSearchPagination reset nu ook searchPage en searchTotal
- isSearchLoading guard tegen race conditions
- displayCategory() met Tussendoortjes → Tussendoor mapping
- voedingsmiddelenByN Map voor click-handler lookup in API items
- data-nummer attribuut ipv data-index voor API data compatibiliteit
Alle 25 e2e tests slagen.
Worker had style.display:none in template maar gebruikte disabled in handler —
knop bleef hidden. Gefixt naar display toggle + 2-item minimum.
Save-knop en delete-knop staan nu naast elkaar zichtbaar als 2+ items geselecteerd.
- Checkboxes standaard unchecked (niet checked)
- 1 item: save-btn direct enabled, tekst 'Opslaan als maaltijd'
- 2+ items: save-btn disabled, tekst 'Selecteer N items'
- Bugfix: [] is truthy in JS → selectedIndices.length check
- Meal groups geen checkbox meer
Alleen losse voedingsmiddelen zijn selecteerbaar — al ingevoerde
maaltijden (meal groups) niet. Checkbox verwijderd uit de
eetmoment-meal-group header.
- renderZoeken toont alleen eerste 50 items, geen DOM overload meer
- IntersectionObserver laadt volgende batches via append (behoudt scrollpositie)
- Event delegation voor openAddToMealForMoment (werkt met dynamisch geladen items)
- Pagination reset bij nieuw zoekopdracht, categorie-filter, en tab-switch
- Sentinel-element onder foodList als IntersectionObserver target
- searchSentinel/sentinel CSS + searchLoading styling
Root cause: listEl.addEventListener werd elke renderDagboek call opnieuw toegevoegd → 4+ handlers per klik. Fix: delegatie in init() met _delegationSetup flag, slechts 1 registratie.
- showConfirmModal vervangt alle confirm() calls met Karby-design modal
- Opslagen maaltijden verwijderen via bevestigingsmodal
- Dagboek: hele maaltijd-groep verwijderen (niet alleen losse items)
- Dagboek: maaltijd verplaatsen naar ander eetmoment
- Delete-knop styling: rode rand + rode tekst
21 e2e tests total, all passing against production site.
Nieuwe tests toegevoegd:
- portion stepper: steppers verschijnen in addMealModal met count=1
- portion stepper: plus op tweede stepper reset eerste, activeert tweede
- portion stepper: minus verlaagt naar 0, wordt dan disabled (geen negatieven)
- portion stepper: active class toggles na plus/minus
- modal close animation: closing class tijdens dismiss
- modal open animation: fadeIn/slideUp CSS animaties op open
- tab switching: switching class tijdens crossfade
- meal save: name input leeg bij openen
- meal save: empty name toont rode rand, modal blijft open
- date navigator: prev/next verandert datum, today reset
- zoektab: food items krijgen staggered --i indices
- button press: buttons hebben transition transform
- meal-group uitklappen: saved meal expand/collapse toggles in dagboek
- NEVO dataset (2328 voedingsmiddelen) met zoekfunctie
- Dagboek met eetmomenten, koolhydratenlimiet en progress bar
- Maaltijden opslaan + nesten in dagboek + eenmalig/permanent bewerken
- Portie-systeem met steppers per NEVO-categorie
- Vorteq amber/goud branding met Karby logo
- Voedingscentrum links per product
- 8 Playwright e2e tests (100% groen)
- PWA met offline support
Kanban board: koolhydraat-app