Ver código fonte

P2-15: verificatie stadsactiviteitAanmaken (0 errors) + 2 blokkades gevonden

Bob's ronde geverifieerd via verse export + dart analyze + live profile-run:
orphan-kopieen weg (0 errors), Entree/Media erven al w600, $.success op
ButtonLogo, kop "Wat" toegevoegd, MijnHorecagelegenheden-cookieheader gefixt.

Nieuw gevonden:
- Plaats-dropdown valt op telefoon buiten het scherm (3x width 200 in een Row)
  -> formulier niet in te dienen via de handmatige cascade; shortcut-pad werkt
- ButtonFotos leest logouploadResult i.p.v. fotouploadResult (crash/valse TRUE)
- 6 look&feel-punten, o.a. onzichtbare tekstvelden en Container(height:200)
  om TextFieldAdres

Stadsrechten-migratie afgevinkt (live bevestigd: 4 gemeenten i.p.v. 1254).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob 1 semana atrás
pai
commit
d415ca56e6
1 arquivos alterados com 152 adições e 73 exclusões
  1. 152 73
      TASKS.md

+ 152 - 73
TASKS.md

@@ -2072,14 +2072,14 @@ in Drupal, geen uitputtende audit.
 Volledige onderbouwing met screenshots: [Designbrug-rapport](https://claude.ai/code/artifact/29f3412a-305f-49f3-971c-cd9bd310beb1).
 Volledige onderbouwing met screenshots: [Designbrug-rapport](https://claude.ai/code/artifact/29f3412a-305f-49f3-971c-cd9bd310beb1).
 Afvinkbare werklijst: [Designbrug werklijst](https://claude.ai/code/artifact/0c0c7347-d681-417d-83d7-7feb1de6457d).)*
 Afvinkbare werklijst: [Designbrug werklijst](https://claude.ai/code/artifact/0c0c7347-d681-417d-83d7-7feb1de6457d).)*
 
 
-**P1-35 · Eigenaar: Bob** (klein per pagina). Advertentieblok staat op
+**P1-35 · Eigenaar: Claude — bezig (sessie 2026-09-03, live pair met Bob in de builder)** (klein per pagina). Advertentieblok staat op
 de detailpagina's direct onder de titel en duwt tabs/adres/tijden onder
 de detailpagina's direct onder de titel en duwt tabs/adres/tijden onder
 de vouw. De site zet advertenties consequent ná de inhoud. Verplaats de
 de vouw. De site zet advertenties consequent ná de inhoud. Verplaats de
 `AdBanner`-node naar onder de Info-tab of onderaan de pagina, op
 `AdBanner`-node naar onder de Info-tab of onderaan de pagina, op
 `horecagelegenheid_current` en `event_current`/
 `horecagelegenheid_current` en `event_current`/
 `evenement_horecagelegenheid`.
 `evenement_horecagelegenheid`.
 
 
-**P1-36 · Eigenaar: Bob.** In `horecagelegenheidoverzicht_kaart_widget.dart`
+**P1-36 · Eigenaar: Claude — bezig (sessie 2026-09-03, live pair met Bob in de builder).** In `horecagelegenheidoverzicht_kaart_widget.dart`
 liggen drie groene categoriepillen over het logo van de zaak heen
 liggen drie groene categoriepillen over het logo van de zaak heen
 (precies over de naam in het beeldmerk), met daarnaast een leeg grijs
 (precies over de naam in het beeldmerk), met daarnaast een leeg grijs
 vlak van dezelfde grootte — leest als een kapotte afbeelding. Fix:
 vlak van dezelfde grootte — leest als een kapotte afbeelding. Fix:
@@ -2699,7 +2699,7 @@ overwegen bij een volgende theme-update:
 
 
 ---
 ---
 
 
-**P2-15 · Eigenaar: Claude (niet actief bezig — sessie 2026-09-02 afgesloten; de pagina `uitgaansevenementAanmaken` staat er en de export is open. Zie "STAND VAN ZAKEN bouwstap 5" voor wat er nog moet).
+**P2-15 · Eigenaar: Claude — bezig (sessie 2026-09-03, verificatie + live test `stadsactiviteitAanmaken`; sessie 2026-09-02 afgesloten; de pagina `uitgaansevenementAanmaken` staat er en de export is open. Zie "STAND VAN ZAKEN bouwstap 5" voor wat er nog moet).
 Bouwstap 1 afgerond en bevestigd (2026-08-27): custom action
 Bouwstap 1 afgerond en bevestigd (2026-08-27): custom action
 `bestandUpload` (`lib/custom_code/actions/bestand_upload.dart`) upload
 `bestandUpload` (`lib/custom_code/actions/bestand_upload.dart`) upload
 foto → fid, live getest tegen productie
 foto → fid, live getest tegen productie
@@ -3124,79 +3124,158 @@ Bob's eigen browser ~5 seconden per widget kost.
 **Huisstijl AF (2026-09-03, geverifieerd).** Alle border-radii op 0
 **Huisstijl AF (2026-09-03, geverifieerd).** Alle border-radii op 0
 (12 tekstvelden, 6 dropdowns, 3 knoppen, 2 afbeeldingen — 0 treffers
 (12 tekstvelden, 6 dropdowns, 3 knoppen, 2 afbeeldingen — 0 treffers
 `circular(8.0)` over), sectiekoppen op 16px.
 `circular(8.0)` over), sectiekoppen op 16px.
-**Twee restjes:** "Entree" en "Media" hebben fontSize 16 maar nog **niet**
-`FontWeight.w600` (de andere drie wel) — alleen Font Weight nog op
-600 zetten.
-
-**🚨 BLOKKEREND: 3 compile-errors, de app bouwt niet.** Er staan vier
-versies van de pagina in het project: `stadsactiviteitAanmaken` (de
-echte) plus **`Copy`, `Copy2` en `Copy3`** — orphans, nergens naartoe
-genavigeerd (`grep` op de widget-klassen geeft 0 externe treffers).
-`stadsactiviteit_aanmaken_copy2` verwijst 3× naar een niet-bestaande
-`columnMijnStadsrechtenResponse` (bij het dupliceren is de wrapper-
-`Column` met de Backend Query niet meegekomen). `dart analyze` geeft
-daardoor 3 errors en elke build faalt.
-**Op te lossen door de drie kopieën te verwijderen** — of, als
-verwijderen op de bekende "Invalid Action"-blokkade stuit (precedent
-P2-7), te hernoemen met een `kanweg_`-prefix conform de bestaande
-conventie. Doe dit vóór de eindtest, anders wacht je op een build die
-niet komt.
-
-**Openstaande takenlijst voor Bob op deze pagina:**
-1. **`$.success`-conditie op beide upload-knoppen.** Bij annuleren wordt
-   `bestandUpload` alsnog aangeroepen met een leeg bestand; `.toString()`
-   maakt van het ontbrekende veld de tekst `"null"`, en de preview toont
-   dan `Invalid argument(s): No host specified in URI file:///null`.
-   Conditional ná de upload-actie: TRUE-tak schrijft fid/url weg,
-   FALSE-tak toont een snackbar met `$.error`.
-2. **Twee sectiekoppen staan nog op "Hello World"** — de groepen "Waar"
-   en "Organisatie".
-3. **Groep 1 (`ContainerWat`) heeft geen sectiekop** — de andere vijf wel.
-4. **Onderaan staat een lege, wél gestileerde container met alleen een
-   "Hello World"-Text** (7e container). Vullen of verwijderen.
-5. **`ContainerMedia` is niet gestileerd** — Fill Color en Border Color
-   staan op Unset, terwijl de andere groepen wit met 3px `#EEEEEE` zijn.
-   Zet Fill = Secondary Background, Border = `#EEEEEE`, Border Width = 3,
-   Border Radius 0 — én Width op `infinity` (staat er wel al op).
-6. **`TextFieldTitel` en `TextFieldWebsiteURL` staan op `width: 200`**,
-   alle andere velden op infinity.
-7. **De dropdowns staan op `width: 200`.** ⚠️ `DropDownProvincie`,
-   `DropDownGemeente` en `DropDownPlaats` zitten in een **`Row`** — daar
-   is `infinity` ongeldig en weigert FlutterFlow de wijziging met
-   "Invalid Action: would have caused a crashing error" (zelf getest).
-   Wil je die vol laten lopen, wrap ze dan eerst in een `Expanded`/`Flex`
-   of haal ze uit de Row.
-8. **Nooit een activiteit ingediend.** Alles wat het pad blokkeerde is nu
-   weg; dit is de eerstvolgende echte test.
-9. Afwerking: geen validatie vooraf, lege AppBar, geen "bezig"-indicatie
-   bij indienen, foto's niet verwijderbaar.
+(De eerdere notitie dat "Entree"/"Media" nog geen `FontWeight.w600`
+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
+   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
+   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.
+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.
 
 
 **Overige restpunten (sessie 2026-08-31, live pair-fix):**
 **Overige restpunten (sessie 2026-08-31, live pair-fix):**
 
 
-8. **`field_town_access` staat volledig op plaats-niveau — 9.292 rijen
-   over 6 accounts (Drupal-kant).** Gemeten 2026-08-31 via SQL:
-   Bee 5200, Disco-Party.nl 2317, bobcity 1254, nomad 517, bobhoreca 2,
-   Team Klein Frankrijk 2 — alles niveau 3 (Plaats). De omzetting naar
-   gemeente-niveau (2026-08-27) wijzigde alleen de widget-instellingen,
-   niet de opgeslagen waarden. **`mijn_stadsrechten` is NIET stuk** —
-   het endpoint geeft correct terug wat er staat (bevestigd: API-length
-   1254 == SQL-count voor bobcity).
-   **Correctie op een eerdere notitie in deze taak:** de conclusie
-   "bobcity heeft 's-Gravendeel als stadsrecht" was gebaseerd op het
-   eerste item van een `head -20` over de volledige, alfabetisch
-   gesorteerde lijst — geen bewijs van iets. De omvang bleek pas via
-   de database.
-   **Migratiescript is aan Bob gegeven** (dry-run + `$APPLY`-vlag,
-   haalt de hele hiërarchie in 2 queries op i.p.v.
-   `taxonomy_get_parents_all()` per term; plaats-tid → gemeente-ouder,
-   dedupliceren, `user_save()`). Nog niet gedraaid. Eerst devbob.
-   **⚠️ Productbeslissing die eerst gemaakt moet worden:** na conversie
-   houdt bobcity ~300 gemeenten en Bee mogelijk heel Nederland — dan is
-   de "Mijn gemeenten"-shortcut geen snelkoppeling maar een tweede
-   plaatsenlijst. Ofwel de landelijke scope terugbrengen tot wat die
-   accounts echt beheren, ofwel de shortcut anders vormgeven (alleen
-   tonen bij ≤ ~25 gemeenten, of een zoekveld i.p.v. een dropdown).
-   Zonder die keuze heeft de migratie weinig zin.
+8. **✅ AFGEROND (Bob, 2026-09-03): stadsrechten-migratie is gedraaid.**
+   `field_town_access` stond op plaats-niveau (9.292 rijen over 6
+   accounts); de migratie naar gemeente-niveau is uitgevoerd voor alle
+   accounts en de scope-beslissing is gemaakt. Live bevestigd in de app
+   (2026-09-03): de "Mijn gemeenten"-shortcut toont voor dit testaccount
+   nu **4 gemeenten** (Amsterdam, Drechterland, Enkhuizen, Stede Broec)
+   i.p.v. 1254 plaatsen — de shortcut werkt dus zoals bedoeld en is een
+   echte snelkoppeling geworden, geen tweede plaatsenlijst.
 9. **Categorie-dropdown toont de hele hiërarchie plat.** `categorieen`
 9. **Categorie-dropdown toont de hele hiërarchie plat.** `categorieen`
    geeft `diepte`/`parent_tid` mee; de multiselect toont nu ouder- én
    geeft `diepte`/`parent_tid` mee; de multiselect toont nu ouder- én
    kindtermen door elkaar zonder inspringing. Optionele verfijning.
    kindtermen door elkaar zonder inspringing. Optionele verfijning.