|
@@ -53,6 +53,7 @@ Google Play en één doorloop die alleen Bob kan doen.
|
|
|
| **122** | Teksten aanmaakpagina's | ✅ **A/B/C af** (Claude 2026-09-20, 19 teksten, export-geverifieerd): verkeerde woorden, typefouten, technische veldnamen en het sterretje bij de categoriekeuze. Open blijven D (hints die het label herhalen), E-restje en F (`Select...` op een NL-pagina) — eigen blok hieronder |
|
|
| **122** | Teksten aanmaakpagina's | ✅ **A/B/C af** (Claude 2026-09-20, 19 teksten, export-geverifieerd): verkeerde woorden, typefouten, technische veldnamen en het sterretje bij de categoriekeuze. Open blijven D (hints die het label herhalen), E-restje en F (`Select...` op een NL-pagina) — eigen blok hieronder |
|
|
|
| **123** | `mijn_stadsrechten` uitbreiden met de keten | **Code staat klaar en is op productie getest.** Vervang regels 316-372 van `custom.evenementen_aanmaken.inc` + `cc all`. Blokkeert 124 |
|
|
| **123** | `mijn_stadsrechten` uitbreiden met de keten | **Code staat klaar en is op productie getest.** Vervang regels 316-372 van `custom.evenementen_aanmaken.inc` + `cc all`. Blokkeert 124 |
|
|
|
| **124-126** | Stadsrechten-cascade op `stadsactiviteitAanmaken` | Voorvullen van provincie/gemeente/plaats (124), een **crash** bij een lege plaatsenlijst (125) en een stille verkeerde plaats bij het wisselen van gemeente (126). Eigen blok hieronder |
|
|
| **124-126** | Stadsrechten-cascade op `stadsactiviteitAanmaken` | Voorvullen van provincie/gemeente/plaats (124), een **crash** bij een lege plaatsenlijst (125) en een stille verkeerde plaats bij het wisselen van gemeente (126). Eigen blok hieronder |
|
|
|
|
|
+| **127** | **Kopie-knop op `MijnAanmeldingen`** (clonen) | Wens Bob 2026-09-20, **vóór de livegang**. Backend bestaat al; Drupal-patch voor 3 gaten staat klaar en is getest (127-A). App-deel in stappen B t/m F; het activiteitendeel (127-E) deelt de cascade met 124. Eigen blok hieronder |
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
#
|
|
#
|
|
@@ -395,6 +396,346 @@ sterretje bij de categoriekeuze) zijn gedaan op béide pagina's:
|
|
|
hulpregel zegt "de **zaak** waar het evenement plaatsvindt". Eén woord kiezen
|
|
hulpregel zegt "de **zaak** waar het evenement plaatsvindt". Eén woord kiezen
|
|
|
is een besluit voor Bob, geen opruimklus.
|
|
is een besluit voor Bob, geen opruimklus.
|
|
|
|
|
|
|
|
|
|
+### 123 · Stadsrechten-cascade op `stadsactiviteitAanmaken` — Drupal-deel · Eigenaar: Bob
|
|
|
|
|
+
|
|
|
|
|
+**Code staat klaar en is getest** (2026-09-20, Claude): vervang in
|
|
|
|
|
+`sites/all/modules/custom/custom.evenementen_aanmaken.inc` de **regels 316 t/m
|
|
|
|
|
+372** (docblock t/m sluitende accolade van `_custom_mijn_stadsrechten_service()`)
|
|
|
|
|
+door de aangeleverde versie. Daarna `drush @<alias> cc all`.
|
|
|
|
|
+
|
|
|
|
|
+**Waarom:** `field_town_access` mag een term op **elk** van de drie niveaus van
|
|
|
|
|
+de town-vocabulary bevatten — plaats (tot 2026-08-27), gemeente (huidige
|
|
|
|
|
+standaard) of provincie (de widget staat op Max depth 2 en laat dat toe; Bob
|
|
|
|
|
+geeft ze bewust op provincieniveau, dat scheelt veel werk). De app stopte die tid
|
|
|
|
|
+rechtstreeks in `plaatsen_bij_gemeente`, en dat geeft bij provincie én plaats een
|
|
|
|
|
+lege lijst → zie taak 125.
|
|
|
|
|
+
|
|
|
|
|
+De nieuwe versie geeft per recht de **volledig uitgeklapte keten** terug:
|
|
|
|
|
+`niveau` · `provincie_tid`/`_titel` · `gemeente_tid`/`_titel` ·
|
|
|
|
|
+`plaats_tid`/`_titel` · `keten` (`"provincie|gemeente|plaats"`, ontbrekende delen
|
|
|
|
|
+leeg) · `label` (bv. *"Noord-Brabant (hele provincie)"*). `tid`, `titel`,
|
|
|
|
|
+`parent_tid` en `parent_titel` blijven ongewijzigd staan, dus bestaande
|
|
|
|
|
+consumenten merken niets. Sortering is hiërarchisch i.p.v. alfabetisch op titel.
|
|
|
|
|
+
|
|
|
|
|
+Getest op productie onder een testnaam, alle drie de niveaus:
|
|
|
|
|
+
|
|
|
|
|
+| account | recht | `keten` |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| bobcity | 28694 Amsterdam (gemeente) | `28666\|28694\|` |
|
|
|
|
|
+| bobhoreca | 27409 Noord-Brabant (provincie) | `27409\|\|` |
|
|
|
|
|
+| Team Klein Frankrijk | 29912 Zuid-Holland (provincie) | `29912\|\|` |
|
|
|
|
|
+
|
|
|
|
|
+### 124 · Stadsrechten-cascade — app-deel · Eigenaar: nader te bepalen (na 123)
|
|
|
|
|
+
|
|
|
|
|
+De eerste dropdown in het *Waar*-blok van `stadsactiviteitAanmaken` moet de drie
|
|
|
|
|
+cascade-dropdowns voorvullen tot zover het recht reikt, in plaats van alleen
|
|
|
|
|
+`createGemeenteID` te zetten:
|
|
|
|
|
+
|
|
|
|
|
+| recht | voorvullen | gebruiker kiest nog |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| provincie | provincie | gemeente + plaats |
|
|
|
|
|
+| gemeente | provincie + gemeente | plaats |
|
|
|
|
|
+| plaats (oud) | alle drie | niets |
|
|
|
|
|
+
|
|
|
|
|
+**Stappen:** dropdown-waarde omzetten van `$[:].tid` naar **`$[:].keten`** (label
|
|
|
|
|
+op `$[:].label`), plus drie custom functions van **één** String-argument
|
|
|
|
|
+(`ketenProvincie` / `ketenGemeente` / `ketenPlaats` → `split('|')[n]`). Die ene
|
|
|
|
|
+parameter is bewust: een lookup op de hele respons vraagt een custom function met
|
|
|
|
|
+meerdere argumenten, en die binding loopt in de Action Flow Editor structureel
|
|
|
|
|
+vast (zie `CLAUDE.md`). On Selected → `Update Page State` voor
|
|
|
|
|
+`createProvincieID`/`createGemeenteID`/`createPlaatsID` + `Set Form Field` op de
|
|
|
|
|
+drie dropdowns.
|
|
|
|
|
+
|
|
|
|
|
+Een lege `Set Form Field`-waarde wordt geweigerd ("Value cannot be empty"), dus
|
|
|
|
|
+voor de lege delen van de keten is **Reset Form Fields** nodig — wat meteen de
|
|
|
|
|
+tweede helft van taak 126 afhandelt.
|
|
|
|
|
+
|
|
|
|
|
+**Voorvullen, niet verbergen** (besluit Bob 2026-09-20): met verbergen kun je
|
|
|
|
|
+achteraf niet meer wisselen zonder eerst de rechten-dropdown leeg te maken.
|
|
|
|
|
+
|
|
|
|
|
+### 125 · Crash: lege plaatsenlijst sloopt de Plaats-dropdown · Eigenaar: nader te bepalen
|
|
|
|
|
+
|
|
|
|
|
+`stadsactiviteit_aanmaken_widget.dart:1878` doet
|
|
|
|
|
+`(getJsonField(respons, r'$[:].plaatsid', true) as List?)!`. `getJsonField` geeft
|
|
|
|
|
+bij **0 matches `null`** — ook met `isForList: true`, want de `isEmpty`-check
|
|
|
|
|
+staat ervóór ([`flutter_flow_util.dart:356`]). Een lege respons `[]` geeft dus
|
|
|
|
|
+`Null check operator used on a null value`; in een release-build een grijs blok
|
|
|
|
|
+zonder melding.
|
|
|
|
|
+
|
|
|
|
|
+Treedt nu op bij elke provincie- of plaats-tid in `field_town_access`, maar staat
|
|
|
|
|
+**los van taak 123/124**: ook een gemeente zónder plaatsen in de taxonomie geeft
|
|
|
|
|
+dezelfde crash. Zelfde patroon staat op de **gemeente**- en **provincie**-dropdown
|
|
|
|
|
+van diezelfde pagina — alle drie langslopen.
|
|
|
|
|
+
|
|
|
|
|
+Fix: Generate-Dynamic-Children-achtige null-veiligheid via een **Predefined Path**
|
|
|
|
|
+op de API-call (`$[:]`, Is List) i.p.v. een JSON Path — dat genereert
|
|
|
|
|
+`(XCall.items(jsonBody)?.toList() ?? [])`. Recept staat in `CLAUDE.md`.
|
|
|
|
|
+
|
|
|
|
|
+### 126 · Stale `createPlaatsID` bij het wisselen van gemeente · Eigenaar: nader te bepalen
|
|
|
|
|
+
|
|
|
|
|
+Geen van de vier dropdowns in het *Waar*-blok reset de onderliggende. Scenario:
|
|
|
|
|
+kies gemeente A → plaats A₁ (`createPlaatsID` gezet) → wissel naar gemeente B.
|
|
|
|
|
+De Plaats-dropdown toont dan weer zijn hint (`FlutterFlowDropDown` filtert een
|
|
|
|
|
+waarde die niet in de opties zit weg, [`flutter_flow_drop_down.dart:101`]), maar
|
|
|
|
|
+`createPlaatsID` houdt **A₁** vast. De verzendknop blijft dus zichtbaar en je
|
|
|
|
|
+dient in voor de vorige plaats. Stil, geen foutmelding.
|
|
|
|
|
+
|
|
|
|
|
+Fix: `Reset Form Fields` + `Update Page State` (Reset Value) op de onderliggende
|
|
|
|
|
+velden in de On-Selected van provincie, gemeente én de rechten-dropdown. Overlapt
|
|
|
|
|
+met taak 124 — samen oppakken.
|
|
|
|
|
+
|
|
|
|
|
+### 127 · "Kopie"-knop op `MijnAanmeldingen` — evenement én activiteit klonen
|
|
|
|
|
+
|
|
|
|
|
+**Wens Bob (2026-09-20):** op elke kaart in *Mijn aanmeldingen* een knop **Kopie**.
|
|
|
|
|
+Eén tik opent het aanmaakformulier volledig ingevuld; de gebruiker vult de datum
|
|
|
|
|
+aan, past eventueel iets aan en dient in. Vóór de livegang. Beide types.
|
|
|
|
|
+
|
|
|
|
|
+**De datum komt bewust NIET mee** — je kloont juist om hetzelfde op een nieuwe
|
|
|
|
|
+datum te zetten. Dat zit al zo in de kloonbron.
|
|
|
|
|
+
|
|
|
|
|
+#### Wat er al is (gemeten 2026-09-20, niet opnieuw uitzoeken)
|
|
|
|
|
+
|
|
|
|
|
+`GET /nl/flutterdrup/aanmelding_kloonbron.json?nid=X` **bestaat en staat aan op
|
|
|
|
|
+productie** (`custom.mijn_aanmeldingen.inc:248`, resource `aanmelding_kloonbron`,
|
|
|
|
|
+operation `index`). Sessie-geauthenticeerd, met eigenaarscheck (403 op andermans
|
|
|
|
|
+node, 404 onbekend, 400 bij een ander contenttype). De sleutelnamen zijn met
|
|
|
|
|
+opzet gelijk aan wat `evenementen/create` en `stadsactiviteiten/create`
|
|
|
|
|
+verwachten — tids en fids, geen weergavewaarden.
|
|
|
|
|
+
|
|
|
|
|
+Aan de **app-kant is nog niets**: geen API Call, geen knop, 0 treffers op
|
|
|
|
|
+`kloonbron` in een verse export.
|
|
|
|
|
+
|
|
|
|
|
+#### 127-A · Drupal: drie gaten in de kloonbron dichten · Eigenaar: Bob
|
|
|
|
|
+
|
|
|
|
|
+**Code staat klaar en is op productie getest** (2026-09-20, Claude, read-only via
|
|
|
|
|
+`drush php-script` — het bestand is niet gewijzigd). Drie gaten, alle drie hard
|
|
|
|
|
+gemeten:
|
|
|
|
|
+
|
|
|
|
|
+| # | Gat | Bewijs |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| 1 | **`entree_tid` ontbreekt bij een activiteit** | De veldkaart heeft `'entree' => NULL` voor `activity`, maar `_custom_stadsactiviteit_create()` schrijft wél naar **`field_act_entree`** (Bob 2026-08-26, zelfde vocabulary als `field_goo_entree`). Testnode 222818 heeft `field_act_entree = 36197`; de kloonbron gaf dat niet terug → **dataverlies bij klonen** |
|
|
|
|
|
+| 2 | **Geen `logo_url`/`fotos_urls`** | De aanmaakpagina toont de preview uit page state `createLogoUrl`/`createFotosUrls`. Zonder URL's gaat het beeld wél mee (de fid) maar zie je een leeg previewvak — verwarrend |
|
|
|
|
|
+| 3 | **Geen plaatsketen bij een activiteit** | Alleen `plaats_tid`. De pagina heeft drie cascade-dropdowns (provincie → gemeente → plaats) en kan uit één tid niet afleiden welke provincie/gemeente erbij horen |
|
|
|
|
|
+
|
|
|
|
|
+**De patch** staat als `kloonbron-patch.inc` in het sessie-scratchpad van
|
|
|
|
|
+2026-09-20; opnieuw te genereren met de beschrijving hieronder. Twee ingrepen in
|
|
|
|
|
+`sites/all/modules/custom/custom.mijn_aanmeldingen.inc`:
|
|
|
|
|
+
|
|
|
|
|
+1. **Regel 125**: `'entree' => NULL,` → `'entree' => 'field_act_entree',`
|
|
|
|
|
+2. **Regels 240 t/m 313** (docblock t/m sluitende accolade van
|
|
|
|
|
+ `_custom_aanmelding_kloonbron()`) vervangen door de nieuwe versie. Die voegt
|
|
|
|
|
+ twee helpers toe (`_custom_aanm_bestand_urls()` en `_custom_aanm_keten()`) en
|
|
|
|
|
+ geeft extra terug: `logo_url`, `fotos_urls`, `entree_tid` (nu voor **beide**
|
|
|
|
|
+ types, uit het gedeelde blok), en voor een activiteit `provincie_tid`,
|
|
|
|
|
+ `gemeente_tid` en **`keten`**.
|
|
|
|
|
+
|
|
|
|
|
+Daarna `drush @uitgaanskrant.com cc all`.
|
|
|
|
|
+
|
|
|
|
|
+⚠️ **`keten` heeft bewust exact hetzelfde formaat als taak 123**
|
|
|
|
|
+(`"provincie|gemeente|plaats"`, ontbrekende delen leeg). De drie custom functions
|
|
|
|
|
+uit taak 124 (`ketenProvincie` / `ketenGemeente` / `ketenPlaats`) zijn daardoor
|
|
|
|
|
+1-op-1 herbruikbaar — bouw ze niet twee keer.
|
|
|
|
|
+
|
|
|
|
|
+**Getest op productie, beide types plus alle randgevallen:**
|
|
|
|
|
+
|
|
|
|
|
+| invoer | `keten` |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| plaats 28739 (Hoogkarspel) | `28666\|28737\|28739` |
|
|
|
|
|
+| gemeente 28694 (Amsterdam) | `28666\|28694\|` |
|
|
|
|
|
+| provincie 28666 (Noord-Holland) | `28666\|\|` |
|
|
|
|
|
+| `NULL` / `0` / onbestaande tid | `\|\|` (geen crash) |
|
|
|
|
|
+
|
|
|
|
|
+**Gemeten: alle 23 gevulde `field_act_state_municipality_tow`-waarden staan op
|
|
|
|
|
+niveau 3 (plaats).** Er is dus geen activiteit waarbij `plaats_tid` en het derde
|
|
|
|
|
+deel van de keten uiteenlopen — dat randgeval hoeft niet afgevangen te worden.
|
|
|
|
|
+
|
|
|
|
|
+ℹ️ **Niet "repareren": `file_create_url()` geeft onder drush `http://`.** Dat is
|
|
|
|
|
+een drush-artefact (geen request-context, `$base_url` staat op
|
|
|
|
|
+`http://uitgaanskrant.com`). Via een echte HTTP-request levert Drupal gewoon
|
|
|
|
|
+`https://` — geverifieerd op `flutterflowmobiel_establishment_info`. Controleer
|
|
|
|
|
+het bij de eerste test vanuit de app, maar ga er niet aan sleutelen.
|
|
|
|
|
+
|
|
|
|
|
+#### 127-B · App: transport via App State · Eigenaar: nader te bepalen
|
|
|
|
|
+
|
|
|
|
|
+**Waarom niet gewoon On Page Load?** Een `TextField` leest zijn Initial Value
|
|
|
|
|
+**tijdens de eerste build**; een Backend Call op *On Page Load* draait in een
|
|
|
|
|
+`addPostFrameCallback`, dus daarná. Het veld blijft dan leeg terwijl de data
|
|
|
|
|
+binnen is. Zelfde valkuil als bij Initial Option Value (staat in `CLAUDE.md`).
|
|
|
|
|
+Daarom: **de call gebeurt op de knop, vóór de navigatie.**
|
|
|
|
|
+
|
|
|
|
|
+**Besluit Bob 2026-09-20: App State, niet page parameters.** Eén JSON-veld scheelt
|
|
|
|
|
+de helft van het bindwerk (1 binding bij het vullen i.p.v. 16) en houdt de route
|
|
|
|
|
+schoon.
|
|
|
|
|
+
|
|
|
|
|
+**Nieuw aan te maken:**
|
|
|
|
|
+
|
|
|
|
|
+| wat | waar | details |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| App State `kloonBron` | App Values → State | Type **JSON**, *Is List* uit, **niet** persisted |
|
|
|
|
|
+| API Call `AanmeldingKloonbron` | API Calls | GET `https://uitgaanskrant.com/nl/flutterdrup/aanmelding_kloonbron.json`, header `Cookie: [sessionName]=[sessid]` (rechte haken!), query `nid`. Kopieer `MijnAanmeldingenCall` als voorbeeld |
|
|
|
|
|
+| Custom function `kloonTekst` | Custom Code | `String kloonTekst(dynamic bron, String sleutel)` — **non-nullable** return, `''` bij ontbreken |
|
|
|
|
|
+| Custom function `kloonLijst` | Custom Code | `List<String> kloonLijst(dynamic bron, String sleutel)` — non-nullable, `[]` bij ontbreken |
|
|
|
|
|
+
|
|
|
|
|
+```dart
|
|
|
|
|
+// kloonTekst — plat schrijven, geen closures (FlutterFlow's validator
|
|
|
|
|
+// struikelt over een genest (params) { ... }-patroon).
|
|
|
|
|
+String kloonTekst(dynamic bron, String sleutel) {
|
|
|
|
|
+ if (bron == null || bron is! Map) return '';
|
|
|
|
|
+ final waarde = bron[sleutel];
|
|
|
|
|
+ if (waarde == null) return '';
|
|
|
|
|
+ return waarde.toString();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+List<String> kloonLijst(dynamic bron, String sleutel) {
|
|
|
|
|
+ final uit = <String>[];
|
|
|
|
|
+ if (bron == null || bron is! Map) return uit;
|
|
|
|
|
+ final waarde = bron[sleutel];
|
|
|
|
|
+ if (waarde is List) {
|
|
|
|
|
+ for (final item in waarde) {
|
|
|
|
|
+ if (item != null) uit.add(item.toString());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return uit;
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+⚠️ **Return type non-nullable houden.** Bij een `String?` eist FlutterFlow een
|
|
|
|
|
+"Default Variable Value", en `valueOrDefault` substitueert die óók bij een lege
|
|
|
|
|
+string — dan kun je nooit een leeg veld klonen. Geen `getJsonField()` gebruiken:
|
|
|
|
|
+die bestaat niet binnen een Custom Function (wel in een Custom Action).
|
|
|
|
|
+
|
|
|
|
|
+#### 127-C · De knop op de kaart · Eigenaar: nader te bepalen
|
|
|
|
|
+
|
|
|
|
|
+Huidige opbouw van de kaart (`mijn_aanmeldingen_widget.dart`, itemBuilder):
|
|
|
|
|
+`Padding > Container > Padding > InkWell > Column [logo, titel, datum_start,
|
|
|
|
|
+status_label]`. De hele kaart is één `InkWell`.
|
|
|
|
|
+
|
|
|
|
|
+De knop moet **buiten die InkWell** staan, anders vuurt ook de navigatie naar
|
|
|
|
|
+`EventCurrent`. Recept (staat in `CLAUDE.md`): rechtsklik de `InkWell` →
|
|
|
|
|
+**Wrap Widget → Column** → "+" op die nieuwe Column → de knop. Een `TabBar Page`
|
|
|
|
|
+of `InkWell` accepteert maar één kind, een `Column` meerdere.
|
|
|
|
|
+
|
|
|
|
|
+**Actieketen op de knop:**
|
|
|
|
|
+
|
|
|
|
|
+1. **Backend Call** → `AanmeldingKloonbron`, `nid` = `$.nid` van het loop-item
|
|
|
|
|
+ (`aanmeldingItemItem`), sessie uit App State.
|
|
|
|
|
+2. **Update App State** → `kloonBron` = *Action Outputs → JSON Body →
|
|
|
|
|
+ No Further Changes*. Doe dit in de **Action Flow Editor** (knop *Edit*, dan het
|
|
|
|
|
+ `|<` om de trigger-kolom in te klappen) — in het compacte Actions-paneel
|
|
|
|
|
+ reageert het Value-veld niet.
|
|
|
|
|
+3. **Add Conditional** op de **page parameter `type`** (`Equal to` `go_out_event`):
|
|
|
|
|
+ - TRUE → `Navigate To` **`uitgaansevenementAanmaken`**, page parameter
|
|
|
|
|
+ `horecagelegenheidNid` = `$.horecagelegenheid_nid` uit de action output.
|
|
|
|
|
+ - FALSE → `Navigate To` **`stadsactiviteitAanmaken`**.
|
|
|
|
|
+
|
|
|
|
|
+ ⚠️ Conditioneer op de **page parameter**, niet op `$.type` van het item: een
|
|
|
|
|
+ JSON-Path-binding krijgt type *Json* en levert `if (getJsonField(...))` op —
|
|
|
|
|
+ een `dynamic` als `bool`, die compileert en pas bij runtime crasht. De page
|
|
|
|
|
+ parameter is een gewone String, dus een veilige Single Condition.
|
|
|
|
|
+
|
|
|
|
|
+**Gratis meegenomen:** `horecagelegenheidNid` bestaat al als page parameter en
|
|
|
|
|
+heeft in `horecaVoorselectie()` (`custom_functions.dart:245`) al **voorrang** op
|
|
|
|
|
+de automatische voorselectie. Voor evenementen hoeft de horecagelegenheid dus
|
|
|
|
|
+niet via App State.
|
|
|
|
|
+
|
|
|
|
|
+#### 127-D · Evenementenformulier voorvullen · Eigenaar: nader te bepalen
|
|
|
|
|
+
|
|
|
|
|
+14 bindingen. Initial Value = `kloonTekst(FFAppState().kloonBron, '<sleutel>')`.
|
|
|
|
|
+
|
|
|
|
|
+| kloonbron-sleutel | doel | soort |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| `titel` | `textFieldTitel` | Initial Value |
|
|
|
|
|
+| `omschrijving` | `textFieldOmschrijving` | Initial Value |
|
|
|
|
|
+| `entree_prijs` | `textFieldEntreeprijs` | Initial Value |
|
|
|
|
|
+| `toelichting_entree` | `textFieldToelichtingEntree` | Initial Value |
|
|
|
|
|
+| `website_url` | `textFieldWebsiteURL` | Initial Value |
|
|
|
|
|
+| `tickets_url` | `textFieldTicketsURL` | Initial Value |
|
|
|
|
|
+| `entree_tid` | `dropDownEntree` | Initial Option Value **+** page state `createEntreeTid` in On Page Load |
|
|
|
|
|
+| `categorie_tids` | `dropDownCategorieen` | Initial Option Value (`kloonLijst`) **+** page state `createCategorieTids` |
|
|
|
|
|
+| `logo_fid` / `logo_url` | — | page states `createLogoFid` / `createLogoUrl` |
|
|
|
|
|
+| `fotos_fids` / `fotos_urls` | — | page states `createFotosFids` / `createFotosUrls` |
|
|
|
|
|
+| `horecagelegenheid_nid` | page parameter | ✅ gratis, zie 127-C |
|
|
|
|
|
+| datums | — | bewust leeg |
|
|
|
|
|
+
|
|
|
|
|
+**Waarom een dropdown twee bindingen nodig heeft:** de page state wordt gezet in
|
|
|
|
|
+`onChanged`, en die vuurt niet bij een voorselectie. Zonder de tweede binding
|
|
|
|
|
+selecteert de dropdown wél de juiste waarde maar verstuurt de create-actie leeg.
|
|
|
|
|
+
|
|
|
|
|
+De page states worden pas bij het indienen gelezen, dus die mogen gewoon in
|
|
|
|
|
+On Page Load — daar speelt het timingprobleem niet.
|
|
|
|
|
+
|
|
|
|
|
+#### 127-E · Activiteitenformulier voorvullen · ⚠️ na 124 · Eigenaar: n.t.b.
|
|
|
|
|
+
|
|
|
|
|
+24 bindingen. Tien TextFields (`titel`, `omschrijving`, `organisator`, `contact`,
|
|
|
|
|
+`adres_straat` → *Adres*, `adres_plaats` → *Plaats*, `adres_postcode`,
|
|
|
|
|
+`entree_prijs`, `toelichting_entree`, `website_url`), plus `entree_tid` en
|
|
|
|
|
+`categorie_tids` (elk 2), de vier beeld-page-states, en **de cascade** (3 × 2).
|
|
|
|
|
+
|
|
|
|
|
+**De cascade is precies taak 124.** Beide moeten de drie dropdowns voorvullen uit
|
|
|
|
|
+een `keten`-string, met dezelfde drie custom functions. Bouw 124 eerst, of bouw ze
|
|
|
|
|
+samen — anders doe je het werk twee keer.
|
|
|
|
|
+
|
|
|
|
|
+**Hoe de timing hier uitpakt** (gemeten in de export):
|
|
|
|
|
+
|
|
|
|
|
+- De **gemeente**-dropdown zit achter `if (createProvincieID != null && != '')`
|
|
|
|
|
+ (`stadsactiviteit_aanmaken_widget.dart:1852`) en de **plaats**-dropdown achter
|
|
|
|
|
+ `if (createGemeenteID ...)` (regel 1991). Die twee **bestaan nog niet** tijdens
|
|
|
|
|
+ de eerste build, dus hun `FormFieldController` wordt pas ná On Page Load
|
|
|
|
|
+ aangemaakt — daar is het eerste-build-probleem er dus **niet**.
|
|
|
|
|
+- Alleen de **provincie**-dropdown staat er meteen. Die ene heeft zijn Initial
|
|
|
|
|
+ Option Value uit App State nodig: `ketenProvincie(kloonTekst(kloonBron,'keten'))`.
|
|
|
|
|
+- On Page Load moet **alle drie** de page states zetten
|
|
|
|
|
+ (`createProvincieID`/`createGemeenteID`/`createPlaatsID`), want een
|
|
|
|
|
+ voorgeselecteerde dropdown vuurt geen `onChanged`.
|
|
|
|
|
+
|
|
|
|
|
+ℹ️ `gemeenteTid` bestaat al als page parameter van deze pagina en heeft voorrang
|
|
|
|
|
+in `gemeenteVoorselectie()` — bruikbaar, maar hij zet alleen `createGemeenteID` en
|
|
|
|
|
+**niet** `createProvincieID`, dus de gemeente-dropdown blijft dan onzichtbaar. Voor
|
|
|
|
|
+een kloon is de App-State-route via `keten` dus de volledige oplossing.
|
|
|
|
|
+
|
|
|
|
|
+#### 127-F · `kloonBron` wissen · Eigenaar: nader te bepalen
|
|
|
|
|
+
|
|
|
|
|
+Zonder dit blijft een kloon hangen: wie daarna een **vers** evenement aanmaakt,
|
|
|
|
|
+krijgt het vorige formulier opnieuw ingevuld.
|
|
|
|
|
+
|
|
|
|
|
+Zet vóór elke bestaande "nieuw aanmaken"-navigatie een `Update App State` met
|
|
|
|
|
+`kloonBron` op **Clear Value** (zelfde patroon als de uitlogknop). Vier plekken in
|
|
|
|
|
+een verse export van 2026-09-20:
|
|
|
|
|
+
|
|
|
|
|
+| bestand | regel | doel |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| `mijn_profiel_widget.dart` | 823 | `UitgaansevenementAanmaken` |
|
|
|
|
|
+| `mijn_profiel_widget.dart` | 1317 | `StadsactiviteitAanmaken` |
|
|
|
|
|
+| `mijn_profiel_widget.dart` | 1506 | `StadsactiviteitAanmaken` |
|
|
|
|
|
+| `favorieten_widget.dart` | 1042 | `StadsactiviteitAanmaken` |
|
|
|
|
|
+
|
|
|
|
|
+Dit zijn **alle** ingangen: de aanmaakpagina's zijn verder nergens vanuit de app
|
|
|
|
|
+bereikbaar (wel via een directe route).
|
|
|
|
|
+
|
|
|
|
|
+#### Volgorde en omvang
|
|
|
|
|
+
|
|
|
|
|
+1. **127-A** (Drupal) — code staat klaar, ±15 min, blokkeert alles.
|
|
|
|
|
+2. **127-B** (App State + call + 2 functies) — ±30 min.
|
|
|
|
|
+3. **127-C + 127-D + 127-F** (evenementen, end-to-end werkend) — één sessie.
|
|
|
|
|
+4. **124/125/126** (cascade) en daarna **127-E** (activiteiten) — eigen sessie.
|
|
|
|
|
+
|
|
|
|
|
+Stap 1-3 leveren al een werkende kloonknop voor evenementen; de knop op een
|
|
|
|
|
+activiteitenkaart verbergen tot 127-E klaar is, is één Visibility-conditie op de
|
|
|
|
|
+page parameter `type`.
|
|
|
|
|
+
|
|
|
|
|
+#### Testen
|
|
|
|
|
+
|
|
|
|
|
+- Kloon een evenement **met** en **zonder** logo/foto's, en één met meerdere
|
|
|
|
|
+ categorieën (testnode 222818 heeft er drie).
|
|
|
|
|
+- Klonen van een **ongepubliceerde** aanmelding moet gewoon werken — de kloonbron
|
|
|
|
|
+ kijkt niet naar `status`. Juist dát is het scenario: een afgekeurde of nog
|
|
|
|
|
+ wachtende aanmelding opnieuw indienen.
|
|
|
|
|
+- Controleer dat de datumvelden **leeg** zijn en dat indienen zonder datum
|
|
|
|
|
+ geweigerd wordt.
|
|
|
|
|
+- Na een kloon: terug naar Mijn profiel → *Nieuw evenement* → formulier moet
|
|
|
|
|
+ **leeg** zijn (127-F).
|
|
|
|
|
+- Controleer in de eerste echte respons dat `logo_url` op `https://` staat.
|
|
|
|
|
+
|
|
|
### 121 · 15 verweesde mappen in `lib/` · Eigenaar: Bob (Claude verwijdert niets)
|
|
### 121 · 15 verweesde mappen in `lib/` · Eigenaar: Bob (Claude verwijdert niets)
|
|
|
|
|
|
|
|
Gevonden 2026-09-20 bij het committen van de achterstallige working tree. Deze
|
|
Gevonden 2026-09-20 bij het committen van de achterstallige working tree. Deze
|