Quellcode durchsuchen

P2-15: stadsactiviteitAanmaken functioneel + visueel af (op eindtest na)

Live pair-sessie Bob + Claude. Verse export, dart analyze 0 errors, live
profile-run op telefoon-emulator waarin de plaats-cascade end-to-end is
doorlopen tot de verzendknop verscheen.

Opgelost: orphan-kopieen weg; Plaats-dropdown viel buiten beeld (3x width
200 in een Row -> Column, alles infinity); ButtonFotos las
logouploadResult; cookieheader MijnHorecagelegenheden; look&feel 1 t/m 5
(18 invulwidgets van onzichtbaar wit-op-wit naar primaryBackground,
Container(height:200) om Adres weg, Media-kaart in de rooilijn, koppen
links, kop "Wat" op 16/600).

Open: eindtest (node indienen, Bob plant zelf), look&feel punt 6
(dubbele labels), 2 niet-blokkerende Issues-errors op de dropdowns.

CLAUDE.md: niet elke Issues-error blokkeert de export (actie-errors wel,
property-override-errors niet); fvm-pin ontbreekt in een verse exportmap;
layout-overflow is stil in profile-mode, diagnose via get_ui_tree;
Column i.p.v. Wrap/StaggeredView voor een afhankelijke dropdown-keten;
FlutterFlow's default fillColor maakt velden onzichtbaar op een witte kaart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob vor 1 Woche
Ursprung
Commit
4d6851fa3c
2 geänderte Dateien mit 220 neuen und 159 gelöschten Zeilen
  1. 89 1
      CLAUDE.md
  2. 131 158
      TASKS.md

+ 89 - 1
CLAUDE.md

@@ -600,12 +600,23 @@ allerlei vervolgfouten (`getJsonField isn't defined`,
 verkeerde conclusies over "kapotte" custom code. **Vaste volgorde bij
 het verifiëren van een export:**
 ```
-cd /tmp/ff-checkN && fvm flutter pub get && fvm dart analyze lib/
+cd /tmp/ff-checkN && fvm use 3.35.7 -f && fvm flutter pub get && fvm dart analyze lib/
 ```
 en tel dan alleen de regels die met `error -` beginnen (een gezond
 project geeft hier ~2000 `info`/`warning`-regels en **0 errors** —
 laat je niet afschrikken door dat totaalgetal).
 
+**De `fvm use 3.35.7 -f` erbij is geen overbodige luxe (2026-09-03).**
+Een verse exportmap heeft géén fvm-pin, dus `fvm flutter` valt daar
+terug op de globale/snap-Flutter (nu 3.44.6). Wil je in zo'n map ook
+échte *builden* (`fvm flutter run`), dan faalt dat met misleidende
+fouten in packages die je niet zelf schreef:
+`The class 'IconData' can't be extended outside of its library because
+it's a final class` (font_awesome_flutter) en
+`Couldn't find constructor 'CupertinoPageTransitionsBuilder'`
+(page_transition). Dat lijkt op kapotte dependencies maar is puur de
+verkeerde SDK-versie. Eén `fvm use 3.35.7 -f` in die map lost het op.
+
 **API Call-URL: relatief pad hoort bij een API Group, absolute URL bij
 een top-level call.** Bevestigd 2026-08-31 (`PlaatsenBijGemeente`):
 een top-level call aangemaakt mét een relatief pad
@@ -1111,6 +1122,26 @@ actie geselecteerd). Gebruik dit altijd vóór je zelf gaat zoeken.
 een geblokkeerde export is vaak niet jouw schuld — check eerst wíe de
 fout veroorzaakt voordat je in je eigen werk gaat spitten.
 
+**Nuance (2026-09-03, gemeten): NIET elke error blokkeert de export —
+alleen sommige soorten.** De kop hierboven is te absoluut. Concreet
+gemeten op dit project met 3 errors in de lijst:
+- **Blokkeert wél:** `API Action — Variable value configured incorrectly
+  for API call` (een Backend Call in een actieketen met ongebonden
+  variabelen, hier `session_name`/`sessid` op een On-Page-Load-call).
+  Zolang die erin staat faalt élke export met de generieke
+  `Status: 400 / Error generating code for the project`.
+- **Blokkeert niet:** `Property Override — Invalid API call configuration`
+  en `Property Override — return type mismatch` op een dropdown. Met
+  alléén die twee in de lijst exporteert het project gewoon.
+**Praktisch gevolg:** ga bij een 400 niet alle errors afwerken, maar
+klik ze aan en zoek de *actie*-gerelateerde eruit — dat is meestal de
+enige die je moet fixen. En andersom: "er staan nog errors" betekent
+niet automatisch dat je niet kunt exporteren; test het gewoon.
+**Verwarrende bijkomstigheid:** FlutterFlow's eigen preview/Test Mode
+is veel toleranter en draait vaak door terwijl `export-code` weigert —
+"de build doet het toch gewoon" is dus geen bewijs dat de teller
+onschuldig is.
+
 **Een Custom-Action-argument van het type `List<String>` dat als fout
 "argument X is not set properly" gemeld wordt: klap in de Inline
 Function-dialoog "Return Type (Optional)" open en druk dan pas
@@ -1887,6 +1918,63 @@ Schrijven met een **niet-platte body** (geneste structs, arrays), eigen
 foutafhandeling of logica vóór/ná het verzoek → custom action. Dát is
 de echte reden dat `stadsactiviteitCreate`/`bestandUpload` bestaan.
 
+**Een widget die door layout-overflow buiten beeld valt is in een
+profile-build volledig STIL — geen gele overflow-streep, niets in
+`logcat`, niets in `dart analyze`. Diagnose: `get_ui_tree`, niet een
+screenshot.** Bevestigd 2026-09-03 (`stadsactiviteitAanmaken`): drie
+cascade-dropdowns stonden naast elkaar in een `Row`, elk `width: 200`.
+Op een telefoon van 411dp is 3 × 200 = 600, dus de derde viel volledig
+buiten het scherm — en daarmee was het formulier niet in te dienen,
+want de verzendknop hing aan een Is-Set-guard op die derde waarde. Op
+een screenshot zie je alleen "er staat hier niets", wat net zo goed een
+verborgen widget of ontbrekende data kan zijn. `get_ui_tree` maakt het
+hard: het weggevallen widget staat **niet** in de accessibility-tree,
+terwijl een verborgen-maar-aanwezig widget er wél in staat. Reken bij
+een `Row` met vaste breedtes dus altijd even uit of N × breedte binnen
+de smalste doeldevice-breedte past (telefoon-AVD = 411dp).
+
+**Layoutkeuze voor een afhankelijke keten van dropdowns (provincie →
+gemeente → plaats): een gewone `Column`, niet `Wrap` en al helemaal
+niet `StaggeredView`.** Overwogen en verworpen 2026-09-03:
+- **StaggeredView** bestaat om een *lijst* met één item-template te
+  herhalen (Backend Query + Generate Dynamic Children). Bij losse
+  widgets met elk hun eigen query en eigen Visibility-conditie is er
+  niets om over te herhalen, en je sleept het hele
+  bounded-height-probleem mee (Shrink Wrap uit, Expanded, niet-scrollende
+  ouder — zie het Home-recept elders in dit bestand).
+- **Wrap** laat kinderen naar de volgende regel vallen als ze niet
+  passen, dus je krijgt per schermbreedte een andere indeling. En
+  `double.infinity` is in een horizontale `Wrap` net zo ongeldig als in
+  een `Row`, dus je blijft aan vaste breedtes vastzitten.
+- **Column** klopt inhoudelijk (opeenvolgende keuzes), accepteert
+  `infinity` gewoon, en sluit aan bij de rest van een formulier.
+**Praktisch:** zitten de dropdowns al in de Column van een
+groep-Container, dan is rechtsklik op de `Row` → **"Remove Widget"**
+genoeg — die haalt alleen de Row weg en schuift de kinderen een niveau
+omhoog. `infinity` weigert FlutterFlow met "Invalid Action" zolang ze
+nog Row-kinderen zijn; dus eerst uit de Row, dán de breedte.
+
+**FlutterFlow's default `fillColor` op een TextField/DropDown is
+`secondaryBackground` — precies de kleur van een witte kaart, dus
+binnen zo'n kaart zijn je invoervelden ONZICHTBAAR.** Bevestigd
+2026-09-03 op `stadsactiviteitAanmaken`: 18 widgets (12 tekstvelden +
+6 dropdowns) genereerden `filled: true, fillColor: ...secondaryBackground`
+mét `enabledBorder`/`focusedBorder` op `Color(0x00000000)` (ook een
+default). Resultaat op het toestel: alleen zwevende grijze labeltekst,
+geen zichtbaar invulvak — het leest als losse tekst in plaats van een
+formulier. **Fix die hier gekozen is:** `fillColor` →
+**`primaryBackground`** (#F2F2F2), randen transparant laten. Eén waarde
+per widget, geeft een zacht grijs vak op de witte kaart en sluit aan bij
+hoe uitgaanskrant.com zijn invoervakken vult. Alternatief is een rand op
+`alternate` (#EEEEEE), maar dat is 2 velden per widget en die kleur is
+al de kaartrand, dus het wordt vlak. **Controleer dit standaard bij elke
+nieuwe formulierpagina** — het is een default, dus het gebeurt vanzelf
+opnieuw (o.a. te verwachten op `uitgaansevenementAanmaken`).
+⚠️ **Verwarring vermijden:** een `Text`-widget (sectiekop) heeft géén
+Fill Color, alleen Text Color — die twee worden makkelijk verwisseld.
+Zit je in een paneel met secties als "Enabled Border"/"Focused Border",
+dan heb je het juiste widget te pakken.
+
 **In een profile-build rendert een crashende subtree als een neutraal
 GRIJS BLOK, niet als het rode foutscherm — en alles eronder in dezelfde
 Column verdwijnt mee.** Bevestigd 2026-08-31: één kapotte dropdown

+ 131 - 158
TASKS.md

@@ -2068,33 +2068,37 @@ in Drupal, geen uitputtende audit.
 
 ---
 
-**P1-41 · Eigenaar: Onbepaald.** Gevonden 2026-09-03 tijdens het live
-narekenen van P2-21 (Home op tablet én telefoon): de kaarten van
-`HomeUitgaantabelKaartComponent` hebben **exact dezelfde ontwerpfout die
-P1-36 net op de horeca-overzichtskaart heeft opgelost** — twee groene
-categoriepillen liggen linksonder óver de afbeelding heen (op de
-donkerste hoek, slecht leesbaar), en het zijn nog pillen (radius 12)
-i.p.v. rechte blokjes. Op smalle kaarten breekt "Kindvriendelijk" ook
-midden in het woord af.
-Fix = hetzelfde recept als P1-36: labels uit de `Stack` naar onder de
-tekst, `Column` → `Wrap` (Replace), radius 12 → 0.
-**De taak valt in twee helften uiteen, en de eerste is één klik
-(uitgezocht 2026-09-03):**
-1. **Pilvorm → recht blokje: één wijziging voor álles.** De groene tag is
-   op Home géén losse widget maar het gedeelde component
-   `lib/shared/tag_categorie_component/` (regel 101-102:
-   `Color(0xFF09B34A)` + `BorderRadius.circular(12.0)`). Dat component
-   wordt gebruikt door **9 levende kaartcomponenten**
-   (`HomeUitgaantabelKaartComponent`, `PUitgaanSliderKaartComponent`,
-   `KaartTabelUitgaanComp`, `KaartTabelUitgaanSComp`,
-   `KaartSliderUitgaanSComp`, `UitgaantabelKaart`, e.a.). Radius daar op
-   0 zetten maakt in één keer élke categorietag in de app merkconform.
-   **Dit is een ontwerpbesluit voor Bob** — het raakt veel meer schermen
-   dan P1-36 deed, dus niet ongevraagd doorvoeren.
-2. **Positie (labels van de afbeelding af):** die zit wél per
-   kaartcomponent, in de `Stack` van elk van die componenten, en moet dus
-   per stuk verplaatst worden. Het sleep-recept staat in `CLAUDE.md`
-   ("Een widget VERPLAATSEN lukt wél").
+**P1-41 · Eigenaar: Claude — bezig (sessie 2026-09-03b).** De kaarten van
+`HomeUitgaantabelKaartComponent` hadden dezelfde ontwerpfout die P1-36 op de
+horeca-overzichtskaart oploste: twee groene categoriepillen liggen linksonder
+óver de afbeelding (donkerste hoek, slecht leesbaar), als pil i.p.v. recht
+blokje, en op smalle kaarten breekt "Kindvriendelijk" midden in het woord af.
+
+**Helft 1 — pilvorm → recht blokje: AFGEROND (2026-09-03b).** De groene tag is
+het gedeelde component `lib/shared/tag_categorie_component/`; daar staat nu
+`BorderRadius.circular(0.0)` i.p.v. 12 (exportgeverifieerd). Dat maakt in één
+keer élke categorietag in de app merkconform. Bob gaf hier expliciet akkoord
+voor, juist omdat het breed doorwerkt.
+
+**Helft 2 — positie (labels van de afbeelding af): nog te doen.** Kan *niet*
+centraal: het component is alleen het groene blokje (`Padding > Container >
+Text`); wáár het landt bepaalt de ouder, via een `Align` binnen de `Stack` van
+elke kaart (op Home: `Align(-0.92, 0.76)`). Dus per kaartcomponent verplaatsen,
+met het sleep-recept uit `CLAUDE.md` ("Een widget VERPLAATSEN lukt wél").
+
+**Het zijn er 3, niet 9** (uitgezocht 2026-09-03b via
+`grep -rl "<Component>Widget("`). Acht bestanden gebruiken het tag-component,
+maar vijf daarvan worden nergens meer aangeroepen —
+`KaartTabelUitgaanComp`, `KaartTabelUitgaanSComp`,
+`KaartSliderUitgaanSComp` (zijn enige gebruiker
+`SliderUitgaanComponentSmallCurrent` is zelf ook nergens in gebruik),
+`PUitgaantabelKaartComponentOrgineelMetKaartjeerin` en
+`HomeUitgaantabelKaartComponentCopy`. Die vallen onder P2-7's opruimactie, niet
+onder deze taak. **Wél levend:**
+1. `HomeUitgaantabelKaartComponent` — Home, alle 5 tabs;
+2. `PUitgaanSliderKaartComponent` — Home-slider én PUitgaan-slider;
+3. `UitgaantabelKaart` — Favorieten tab 1.
+
 De horeca-overzichtskaart uit P1-36 gebruikt dit gedeelde component
 **niet** (die had een eigen inline groene Container), dus die is met de
 fix van 2026-09-03 al klaar en verandert hier niet door mee.
@@ -3162,143 +3166,102 @@ Bob's eigen browser ~5 seconden per widget kost.
 hadden is achterhaald — zie de verificatie hieronder: ze erven w600 al
 van `headlineSmall`.)
 
-**✅ BLOKKADE OPGEHEVEN + huisstijl-restjes gecontroleerd (2026-09-03,
-Claude, verse export + `flutter pub get` + `dart analyze` + live
-profile-run op `emulator-5556`/telefoon).** Wat Bob deze ronde deed is
-geverifieerd:
-- **`Copy`/`Copy2`/`Copy3` zijn weg** — `dart analyze lib/` geeft nu
-  **0 errors** (was 3), de app bouwt en draait weer.
-- **"Entree" + "Media" zijn wél 16px/600** — ze staan op basisstijl
-  `headlineSmall` (die is in het thema al `FontWeight.w600`) i.p.v.
-  `bodyMedium` + expliciete override zoals de andere drie. Klaar, ook
-  al ziet de code er anders uit dan bij "Wanneer"/"Waar"/"Organisatie".
-- **`$.success`-conditie staat op `ButtonLogo`** — correct: TRUE-tak
-  schrijft fid/url, FALSE-tak snackbar met `$.error`.
-- **Sectiekop "Wat" is toegevoegd** (i18n-key `hu7xw8pm`).
-- **`MijnHorecagelegenheden`-cookieheader is gefixt** — export toont
-  `'Cookie': '${sessionName}=${sessid}'` en de aanroeper in
-  `mijn_profiel_widget.dart:270` geeft beide App-State-velden mee. Er
-  staat nergens in `api_calls.dart` nog een `{{…}}`.
-
-**🚨 BLOKKEREND 1 — de Plaats-dropdown is op een telefoon onbereikbaar,
-dus het formulier is niet in te dienen via de handmatige cascade.**
-Live bevestigd (telefoon 411dp): `DropDownProvincie`,
-`DropDownGemeente` en `DropDownPlaats` staan naast elkaar in één `Row`,
-elk met `width: 200` (regels 1569/1703/1844 in
-`stadsactiviteit_aanmaken_widget.dart`). 3 × 200 = 600 > 411dp, dus
-zodra je een gemeente kiest valt de derde dropdown **volledig buiten
-het scherm** — hij staat niet eens in de accessibility-tree
-(`get_ui_tree` toont alleen de eerste twee). Zonder `createPlaatsID`
-verschijnt de verzendknop nooit (die heeft een Is-Set-guard), dus de
-pagina is via dit pad onbruikbaar. In profile-mode is er géén
-zichtbare overflow-melding en niets in `logcat` — puur stille clipping.
-**Wél werkend pad:** de shortcut `DropDownGemeentenMijngemeenten`
-bovenaan. Die zet `createGemeenteID` zonder `createProvincieID`, dus de
-Gemeente-dropdown blijft verborgen en er staan maar 2 dropdowns in de
-Row (2 × 200 = 400 < 411) → Plaats is dan wél bereikbaar. Live getest:
-Amsterdam (gemeente) → Plaats "Amsterdam"/"Amsterdam-Zuidoost" laadt
-via `PlaatsenBijGemeente`, en dán verschijnt "Activiteit indienen".
-**Fix:** haal de drie dropdowns uit de `Row` en zet ze onder elkaar op
-`infinity` (een `Column` is hier logischer dan een Row — het zijn drie
-opeenvolgende keuzes, geen naast-elkaar-groep). ⚠️ `infinity` direct op
-een Row-kind weigert FlutterFlow met "Invalid Action" (al eerder
-getest), dus eerst uit de Row halen. Zie ook `CLAUDE.md`: "Remove
-Widget" op de Row behoudt de kinderen — precies wat je hier wil.
-
-**🚨 BLOKKEREND 2 — de Foto's-knop leest de verkeerde
-actie-uitkomst.** In de `onPressed` van `ButtonFotos` staat de
-`$.success`-conditie én de fout-snackbar op `_model.logouploadResult`
-(het resultaat van de **logo**-upload) i.p.v.
-`_model.fotouploadResult` — regels 3456 en 3474; alleen de twee
-`addTo…`-regels (3460/3464) pakken de juiste variabele. Twee gevolgen:
-(1) kies je een foto **voordat** je ooit een logo hebt geüpload, dan is
-`logouploadResult` nog `null` → `if (getJsonField(null, r'$.success'))`
-→ **runtime-crash op de bool-cast** (exact de valkuil die al in
-`CLAUDE.md` staat); (2) is de logo-upload eerder wél gelukt, dan neemt
-de fotoknop **altijd** de TRUE-tak, ook als de foto-upload faalde →
-`"null"` als fid in `createFotosFids`.
-**Fix:** in de Action Flow Editor van `ButtonFotos` de conditie en de
-fout-snackbar opnieuw binden aan `fotouploadResult`. Dit is dezelfde
-copy-paste-valkuil als het `datePicked0`/`datePicked1`-geval eerder op
-deze pagina.
-
-**Look & feel — live bekeken, 6 punten die er echt uitspringen:**
-1. **De tekstvelden zijn onzichtbaar.** `enabledBorder`/`focusedBorder`
-   staan op `Color(0x00000000)` (transparant) en `fillColor` op
-   `secondaryBackground` = `#FFFFFF` — precies de kleur van de kaart
-   waar ze in staan. Je ziet alleen zwevende grijze labeltekst, geen
-   invulvak: op het scherm lijkt "Titel"/"Omschrijving"/"Adres"/
-   "Postcode"/"Plaats"/"Organisator"/"Contact"/"WebsiteURL" losse tekst
-   i.p.v. een veld. Dit is de grootste visuele misser. **Fix:** geef de
-   velden een zichtbare rand (`alternate` #EEEEEE, of `primaryText` op
-   lage opaciteit) óf zet `fillColor` op `primaryBackground` (#F2F2F2)
-   zodat het vak contrasteert met de witte kaart. De site zelf gebruikt
-   een lichtgrijze rand om invoervakken.
-2. **`Container(height: 200)` om `TextFieldAdres`** (regel 1903) — een
-   leftover vaste hoogte die een gat van ~200px in de "Waar"-kaart
-   slaat. Weghalen (of de Container zelf verwijderen).
-3. **`ContainerMedia` mist de `Align > Padding(16)`-wrapper** die de
-   andere vijf kaarten wél hebben (regel 3206 vs 196/693/1281/2276/2690).
-   Gevolg: de Media-kaart is 32px breder dan de rest en ligt zichtbaar
-   niet in lijn. Ook de twee oranje knoppen erin steken links buiten de
-   kaartrand.
-4. **Sectiekoppen zijn inconsistent uitgelijnd.** "Wat", "Wanneer",
-   "Waar" en "Organisatie" staan **gecentreerd** (geen `Align`, dus
-   Column-default), "Entree" en "Media" staan **links** (in een
-   `Align(-1.0)`). Kies er één — links past bij de site.
-5. **"Wat" heeft niet dezelfde kopstijl als de rest.** De kop staat op
-   kale `bodyMedium` (14px, normal) i.p.v. 16px/600 — visueel duidelijk
-   lichter dan "Wanneer"/"Waar". Nog omzetten.
-6. **Dubbele/zwevende veldlabels.** Boven vier velden staat een lósse
-   `Text`-widget die het label herhaalt dat het veld zelf al als
-   `labelText`/`hintText` heeft: "Categorie evenement" (regel 494),
-   "Stadseditor" (1467), "Toelichting Entree" (2874) en "Entreeprijs"
-   (3037). Bij "Toelichting Entree" en "Entreeprijs" staat het label
-   daardoor letterlijk 2× op het scherm. "Stadseditor" is bovendien een
-   zwevend, gecentreerd label zonder duidelijk bijhorend veld. Óf de
-   losse Texts weg, óf ze bij álle velden consequent gebruiken (en dan
-   de `labelText` van het veld leegmaken).
-   Kleiner, in dezelfde categorie: de kaarten hebben **geen interne
-   padding**, dus deze losse labels raken de 3px-rand van de kaart.
-
-**Kleinere restpunten op deze pagina (niet blokkerend):**
-1. **Entry-point ontbreekt nog** — `stadsactiviteitAanmaken` is alleen
-   via de route bereikbaar. De "+ Voeg toe"-knoppen op `mijnProfiel`
-   staan nog op een placeholder-snackbar en moeten Navigate-To hierheen
-   worden (bouwstap 4, restpunt 1).
-2. **Lege container met "Hello World" onderaan** (regel 3688-3704) —
-   staat er nog steeds, en is op het toestel gewoon zichtbaar onder de
-   verzendknop. Vullen of verwijderen.
-3. **Nog nooit een activiteit ingediend.** Beide blokkades hierboven
-   moeten eerst weg; daarna is dit de echte eindtest (node moet
-   ongepubliceerd binnenkomen met de juiste plaats/datum/categorieën/
-   entree/logo/foto's).
-4. **Geen validatie vooraf.** Alle 12 `…TextControllerValidator`-velden
+**✅ Bouwstap 3 (`stadsactiviteitAanmaken`) is functioneel én visueel AF
+— 2026-09-03, live pair-sessie Bob + Claude.** Verse export,
+`flutter pub get`, `dart analyze lib/` = **0 errors**, en een live
+profile-build op de telefoon-emulator (411dp) waarin de hele
+plaats-cascade end-to-end is doorlopen tot de verzendknop verscheen.
+
+**Wat deze dag is opgelost (alles exportgeverifieerd):**
+- **Orphan-kopieën `Copy`/`Copy2`/`Copy3` verwijderd** — die gaven 3
+  compile-errors; de app bouwt weer.
+- **Plaats-dropdown was op een telefoon onbereikbaar.** De drie
+  cascade-dropdowns stonden naast elkaar in een `Row`, elk
+  `width: 200`. 3 × 200 = 600 > 411dp, dus de derde viel volledig
+  buiten beeld — hij stond niet eens in de accessibility-tree. Zonder
+  `createPlaatsID` verscheen de verzendknop nooit, dus het formulier was
+  via dat pad onbruikbaar. Opgelost: `Row` → `Column`, alle 6 dropdowns
+  op `infinity` (0 treffers `width: 200` over).
+- **`ButtonFotos` las `logouploadResult` i.p.v. `fotouploadResult`** in
+  zowel de `$.success`-conditie als de fout-snackbar → crash op de
+  bool-cast bij een foto vóór een logo, en anders een altijd-TRUE-tak.
+  Beide regels omgezet.
+- **`$.success`-conditie op `ButtonLogo`**, **sectiekop "Wat"**,
+  **lege "Hello World"-container onderaan weg**, **alle border-radii 0**,
+  **sectiekoppen 16px/600**.
+- **`MijnHorecagelegenheden`-cookieheader** van `{{session_name}}={{sessid}}`
+  naar `[…]`-syntax → export toont `'Cookie': '${sessionName}=${sessid}'`
+  en de aanroeper (`mijn_profiel_widget.dart:270`) geeft beide
+  App-State-velden mee. Nergens nog `{{…}}` in `api_calls.dart`.
+- **Look & feel 1 t/m 5:** alle 18 invulwidgets (12 tekstvelden + 6
+  dropdowns) van `fillColor: secondaryBackground` naar
+  `primaryBackground` (waren onzichtbaar wit-op-wit); `Container(height:
+  200)` om `TextFieldAdres` weg; `ContainerMedia` de ontbrekende
+  `Padding(16)`-wrapper gegeven zodat hij in de rooilijn ligt; alle zes
+  sectiekoppen links uitgelijnd; kop "Wat" op 16px/w600/`primaryText`.
+
+**Nog te doen op deze pagina:**
+1. **⏭️ EINDTEST — nooit een activiteit ingediend.** Alles wat het pad
+   blokkeerde is nu weg en de verzendknop is live bereikt, maar er is
+   nog geen node aangemaakt. **Bob wil dit zelf plannen (afspraak
+   2026-09-03: "dan kunnen we morgen testen").** Te controleren na
+   indienen: node komt **ongepubliceerd** binnen, met de juiste plaats,
+   datum (start + eind), categorieën, entree-type, entreeprijs, logo en
+   foto's. Snelste route naar een geldige staat: de **"Mijn
+   gemeenten"-shortcut** (gemeente → plaats), dan verschijnt de knop.
+2. **Look & feel punt 6 — dubbele/zwevende veldlabels.** Bewust
+   geparkeerd door Bob. Boven vier velden staat een losse `Text`-widget
+   die het label herhaalt dat het veld zelf al als `labelText`/`hintText`
+   voert: **"Categorie evenement"**, **"Stadseditor"**, **"Toelichting
+   Entree"**, **"Entreeprijs"**. Bij de laatste twee staat het label
+   letterlijk 2× op het scherm; "Stadseditor" is een zwevend label
+   zonder duidelijk bijhorend veld. Keuze: óf de losse Texts weg, óf ze
+   bij álle velden consequent gebruiken en dan de `labelText` van het
+   veld leegmaken. De kaarten hebben bovendien geen interne padding,
+   waardoor die losse labels de 3px-rand raken.
+3. **Twee niet-blokkerende Issues-errors op deze pagina** (gemeten
+   2026-09-03, export loopt er gewoon mee door):
+   - `Property Override — Invalid API call configuration` op
+     `DropDownGemeentenMijngemeenten`;
+   - `Property Override — return type mismatch` op `DropDownProvincie`
+     — die genereert `options: List<String>.from(getJsonField(...
+     $[:].provincieid ...))` terwijl "Option Value Data Type" op
+     **String** staat; komt `provincieid` als getal terug, dan is dat
+     precies de mismatch.
+   De cascade werkt live, dus geen brand, maar wel opruimen.
+4. **Entry-point ontbreekt** — `stadsactiviteitAanmaken` is alleen via
+   de route bereikbaar. De "+ Voeg toe"-knoppen op `mijnProfiel` staan
+   nog op een placeholder-snackbar en moeten Navigate-To hierheen worden
+   (bouwstap 4, restpunt 1), met `plaats_tid` als page-parameter.
+5. **Geen validatie vooraf.** Alle 12 `…TextControllerValidator`-velden
    zijn in het model gedeclareerd maar nergens toegekend, dus er is geen
-   enkele verplicht-veld-check. Een leeg Titel/Datum gaat gewoon mee
-   naar de server (`datumVoorApi('')` geeft `''`, geen crash) en komt
-   terug als een Drupal-foutmelding in de snackbar. Werkt, maar rauw.
-5. **Geen "bezig"-indicatie bij indienen** — geen enkele knop op deze
+   verplicht-veld-check. Een leeg Titel/Datum gaat gewoon mee naar de
+   server (`datumVoorApi('')` geeft `''`, geen crash) en komt terug als
+   Drupal-foutmelding in de snackbar. Werkt, maar rauw.
+6. **Geen "bezig"-indicatie bij indienen** — geen enkele knop op deze
    pagina heeft `showLoadingIndicator`. Bij een trage upload/create
    lijkt de knop niets te doen.
-6. **De 6 dropdowns staan nog op `width: 200`** (regels 576, 1407,
-   1569, 1703, 1844, 2819). `DropDownCategorieen` (576) en
-   `DropDownEntree` (2819) zitten in een `Align`, niet in een `Row` —
-   die kunnen dus zonder gedoe naar `infinity`. De drie cascade-
-   dropdowns zie blokkade 1; de shortcut (1407) kan mee zodra die uit
-   de Row is.
 7. **Foto's zijn niet te verwijderen** — de Wrap toont ze als 80×80
    `Image.network` zonder verwijderknop; verkeerd gekozen foto betekent
    pagina verlaten en opnieuw beginnen.
 8. **Lege AppBar** — alleen een rode balk met terugknop, geen titel.
 9. **De verzendknop is onzichtbaar tot er een plaats gekozen is** (de
    Is-Set-guard) zonder enige uitleg. Overweeg de knop altijd te tonen
-   maar uit te schakelen met een hint "Kies eerst een plaats" — dat is
-   duidelijker dan een knop die er niet is.
+   maar uit te schakelen met een hint "Kies eerst een plaats".
 10. De laadspinner van elke dropdown-`FutureBuilder` is een
-    `SpinKitFadingCircle` van **80×80 in een `Center`** — die springt
-    bij het laden groter dan de dropdown zelf en laat de layout
-    verschuiven.
+    `SpinKitFadingCircle` van **80×80 in een `Center`** — die is groter
+    dan de dropdown zelf en laat de layout tijdens het laden verschuiven.
+11. **De categorie-dropdown en de gemeente-lijst zijn niet
+    alfabetisch** — ze volgen de volgorde van de API (provincies komen
+    binnen als Flevoland, Drenthe, Friesland, …). Cosmetisch.
+
+⚠️ **Let op bij vervolgwerk: `uitgaansevenementAanmaken` wordt in een
+andere chat gebouwd** als duplicaat van deze pagina, en zit in dezelfde
+`productie`-API-groep. Op 2026-09-03 blokkeerde een fout dáár
+(`API Action — Variable value configured incorrectly for API call`, de
+ongebonden `session_name`/`sessid` op de On-Page-Load-`MijnHorecagelegenheden`-
+call) meermaals onze export hier. Zie het nieuwe Issues-recept in
+`CLAUDE.md`.
 
 **Overige restpunten (sessie 2026-08-31, live pair-fix):**
 
@@ -3662,10 +3625,20 @@ laatste rij moet Bob zetten. Zie ook de CLAUDE.md-notitie hierover.
    alleen staleness introduceren.
 3. De "Hello World"-restplaceholder onderaan de pagina is verwijderd.
 
-**Enige echt openstaande punt op deze pagina:** `mijnProfiel`'s "+ Voeg
-toe"-knop bij Mijn horecagelegenheden wijst nog naar een placeholder-snackbar;
-die kan nu naar `/uitgaansevenementAanmaken` met `horecagelegenheidNid` als
-parameter. Daarna is bouwstap 5 compleet en is P2-15 klaar op een live test na.
+**Bouwstap 5 is compleet.** `mijnProfiel`'s "+ Voeg toe"-knop bij Mijn
+horecagelegenheden navigeert nu naar `/uitgaansevenementAanmaken`
+(`context.pushNamed`), **bewust zónder `horecagelegenheidNid` mee te geven**:
+die knop staat in de sectiekop, bóven de ListView, dus daar is geen loop-item
+en dus geen nid in scope. Dat hoeft ook niet — `horecaVoorselectie` selecteert
+de zaak vanzelf voor als de gebruiker er precies één heeft, en de meeste
+gebruikers hebben er één (Bob, 2026-09-03). Wil je later een knop *per kaart*
+("nieuw evenement bij déze zaak"), dan moet die binnen de ListView staan; daar
+is `horecaItem` → JSON Path `$.nid` wél beschikbaar.
+
+**Wat nog rest voor P2-15: een live test op een toestel** — inloggen als
+horeca-eigenaar, controleren dat de dropdown zich voorselecteert en dat de
+verzendknop verschijnt, en één evenement daadwerkelijk indienen (verwacht:
+snackbar "Je evenement is geplaatst." en de node terugvinden op de site).
 
 **Nieuwe FlutterFlow-valkuil, gevonden tijdens deze stap (geldt straks
 óók voor de formulierpagina):** een **List-typed custom-action-argument