Browse Source

Bouwstap 5 (uitgaansevenement aanmaken) volledig voorbereid; homeCopy naar kanweg

Alles verzameld om de pagina "uitgaansevenement aanmaken" te kunnen
bouwen zonder eerst het Artifact te hoeven lezen: het complete
API-contract van evenementen/create, de vijf verschillen met
stadsactiviteiten/create, wat er al klaarstaat (bestandUpload,
MijnHorecagelegenheden/Categorieen/Entreeopties, het
stadsactiviteitAanmaken-sjabloon) en wat nog nieuw moet.

Belangrijkste bevinding: deze pagina is EENVOUDIGER dan
stadsactiviteitAanmaken. De 3-traps plaats-cascade vervalt volledig —
Drupal leidt stad, adres en geo af uit de gekozen horecagelegenheid, dus
de app stuurt alleen horecagelegenheid_nid. Ook geen adres-struct,
organisator of contact. Wel nieuw: tickets_url.

Let op bij het bouwen: de response is "created", niet
"created_pending_review" — een evenement komt direct gepubliceerd
binnen, dus de bevestiging moet "geplaatst" zijn en niet "wordt
beoordeeld" zoals bij stadsactiviteiten.

homeCopy hernoemd naar kanwegHomeCopy en verplaatst naar de map kanweg
(lib/kanweg/kanweg_home_copy/, klasse KanwegHomeCopyWidget). Rename en
move gingen allebei zonder de "Invalid Action"-blokkade die de
Event-pagina destijds gaf; bevestigd via verse export.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob 2 tuần trước cách đây
mục cha
commit
e3030f4c4f
1 tập tin đã thay đổi với 108 bổ sung5 xóa
  1. 108 5
      TASKS.md

+ 108 - 5
TASKS.md

@@ -2459,11 +2459,14 @@ liggen tot Bob erop terugkomt — geen eigen taak-ID.)*
   (`lib/uitgaanspaginas/home_copy/`) en
   `HomeUitgaantabelKaartComponentCopy`
   (`lib/uitgaanspaginas/home_uitgaantabel_kaart_component_copy/`).
-  **`homeCopy` kan weg** — de Home-pagina is volledig teruggedraaid en
-  met een verse export byte-identiek aan het origineel bevonden, dus dat
-  vangnet is niet meer nodig. **`HomeUitgaantabelKaartComponentCopy`
-  bewaren zolang P2-21 openstaat** (herstelpunt als de
-  pagination-omzetting misgaat); daarna ook weg.
+  **`homeCopy` is afgehandeld (2026-08-31, Bob's keuze): hernoemd naar
+  `kanwegHomeCopy` en verplaatst naar de map `kanweg`** — staat nu op
+  `lib/kanweg/kanweg_home_copy/`, klasse `KanwegHomeCopyWidget`.
+  Rename én move gingen zonder de "Invalid Action"-blokkade die de
+  Event-pagina destijds gaf; bevestigd via verse export.
+  **`HomeUitgaantabelKaartComponentCopy` bewaren zolang P2-21
+  openstaat** (herstelpunt als de pagination-omzetting misgaat);
+  daarna ook naar `kanweg`.
 - **Nieuw bevestigd dood (2026-08-31, Claude, code-only; geverifieerd
   met `grep -rn "components/<bestand>" lib/` — 0 importeurs):**
   `lib/components/uitgaantabel_kaart_widget.dart` +
@@ -3197,6 +3200,106 @@ Custom Function.**
 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).)*
 
+**Bouwstap 5 — pagina `uitgaansevenementAanmaken`. VOLLEDIG
+VOORBEREID op 2026-08-31, klaar om mee te beginnen; nog geen regel
+gebouwd.** Dit is stap 3 uit de oorspronkelijke bouwvolgorde bovenaan
+P2-15 ("Pagina Evenement aanmaken"). Alles hieronder is uitgezocht en
+geverifieerd — een nieuwe sessie kan direct bouwen zonder eerst het
+Artifact te hoeven lezen.
+
+**Kernpunt: deze pagina is EENVOUDIGER dan `stadsactiviteitAanmaken`,
+niet moeilijker.** Het zwaarste stuk van bouwstap 3 — de 3-traps
+provincie→gemeente→plaats-cascade — vervalt hier volledig. Drupal leidt
+stad, adres én geo automatisch af uit de gekozen horecagelegenheid
+(`hook_node_presave` kopieert `field_geo_horecagelegenheid`,
+`field_hor_municipality_town` en `field_address3` over). De app stuurt
+alleen het nid.
+
+**API-contract `POST evenementen/create.json`** (uit het Artifact,
+sectie "API-contract"; curl-bevestigd 2026-08-26):
+
+| Argument | Type | Verplicht | Toelichting |
+|---|---|---|---|
+| `horecagelegenheid_nid` | int | **ja** | Moet een `horecagelegenheid`-node zijn met `uid` = ingelogde user, anders **403** |
+| `titel` | string | **ja** | |
+| `datum_start` | string | **ja** | `'YYYY-MM-DD HH:MM:SS'` |
+| `datum_eind` | string | nee | leeg → gelijk aan `datum_start` |
+| `omschrijving` | string | nee | |
+| `entree_tid` | int | nee | tid uit `entreeopties/index` |
+| `entree_prijs` | string | nee | decimaal als string, bv. `"7.50"` |
+| `toelichting_entree` | string | nee | |
+| `tickets_url` | string | nee | **bestaat niet op stadsactiviteit** |
+| `website_url` | string | nee | |
+| `categorie_tids` | array<int> | nee | uit `categorieen/index`; ongeldige tid → 400 |
+| `logo_fid` | int | nee | fid uit `bestand_upload/upload` |
+| `fotos_fids` | array<int> | nee | max 5, meer → 400 |
+
+**Verschillen met `stadsactiviteiten/create` — let hier op:**
+1. **`horecagelegenheid_nid` vervangt `plaats_tid`.** Geen plaats-picker,
+   geen 3-traps cascade, geen Page State voor provincie/gemeente/plaats.
+2. **Géén `adres`-struct, géén `organisator`, géén `contact`** — die
+   drie velden bestaan hier niet. Scheelt 4 TextFields.
+3. **`tickets_url` komt er wél bij** (1 extra TextField).
+4. **De response is anders en dat is gebruikerszichtbaar:**
+   `{"status": "created", "nid": "..."}` — de node komt **direct
+   gepubliceerd** binnen. Toon dus **"geplaatst"**, NIET "wordt
+   beoordeeld" (dat laatste hoort alleen bij stadsactiviteiten, die
+   komen altijd ongepubliceerd binnen).
+5. **Eigenaarschap-gate:** een horecagelegenheid van iemand anders geeft
+   403 met "Deze horecagelegenheid is niet van jou" (curl-bevestigd op
+   nid 70132). Kan in de praktijk niet gebeuren als de picker uit
+   `mijn_horecagelegenheden` gevuld wordt, maar vang de 403 netjes af.
+
+**Wat er al klaarstaat (niets van dit hoeft opnieuw gebouwd):**
+- Custom action **`bestandUpload`** (`lib/custom_code/actions/bestand_upload.dart`)
+  — foto → fid. Wil de **volledige** upload-URL, niet alleen een base.
+- API Calls **`MijnHorecagelegenhedenCall`**, **`CategorieenCall`**,
+  **`EntreeoptiesCall`** (`lib/backend/api_requests/api_calls.dart`) —
+  alle drie bestaan en zijn exportgeverifieerd.
+- Pagina **`stadsactiviteitAanmaken`** (`lib/stadsactiviteit_aanmaken/`)
+  — het te kopiëren sjabloon voor de TextFields, de twee datumvelden
+  (`readOnly` + `showDatePicker` → `showTimePicker` → gecombineerd
+  terug in het veld), de categorie-multiselect en de foto-upload.
+- Pagina **`mijnProfiel`** (`lib/mijn_profiel/`) — heeft al een
+  "+ Voeg toe"-knop bij "Mijn horecagelegenheden" die nu nog een
+  placeholder-snackbar toont; die wordt straks de entry-point.
+
+**Wat nieuw gebouwd moet worden:**
+1. **Custom action `evenementCreate`** — kopie van
+   `stadsactiviteit_create.dart` met de argumentenlijst hierboven
+   (13 i.p.v. 20 argumenten, geen `adres`-struct). POST naar
+   `$base/en/flutterdrup/evenementen/create.json`.
+   ⚠️ Bouw 'm plat, zonder lokale closures (bekende
+   "cannot be parsed"-validatorbug), en check vóór Save even
+   **"View Boilerplate Code"** (`</>`-icoon) op een leeg naamloos
+   extra argument — dat kostte bij `stadsactiviteitCreate` tijd.
+2. **Pagina `uitgaansevenementAanmaken`** — Scaffold + AppBar
+   ("Show Default Button" aan), scrollbare Column, padding 16.
+   6 TextFields (Titel · Omschrijving · Entreeprijs · Toelichting
+   entree · Tickets-URL · Website-URL), 2 datumvelden, 1 dropdown
+   horecagelegenheid, 1 dropdown entree, 1 categorie-multiselect,
+   logo-upload + foto's-upload.
+3. **Horecagelegenheid-picker**: DropDown met Backend Query
+   `MijnHorecagelegenheden` (variabelen `session_name`/`sessid` →
+   App State `userSessionname`/`userSessionid`), optie-label `$.titel`,
+   waarde `$.nid`. **Auto-select bij precies 1 resultaat** (Bob's eis
+   uit de oorspronkelijke bouwvolgorde).
+4. **Verzendknop** — en neem hier meteen de les van P2-15 restpunt 7
+   mee: laat de knop **geen non-null assertion op een Page State-veld**
+   krijgen. Schakel 'm uit (of verberg 'm) zolang
+   `horecagelegenheid_nid`, titel of datum niet gezet zijn, anders
+   crasht indienen met "Null check operator used on a null value"
+   vóórdat de custom action zijn eigen nette foutmelding kan tonen.
+5. **Page parameter `horecagelegenheid_nid`** (optioneel) zodat
+   `mijnProfiel`'s "+ Voeg toe"-knop 'm vooringevuld kan meegeven.
+
+**Bouwvolgorde-advies:** eerst de custom action + los testen tegen
+productie met één minimaal geldig verzoek (titel + nid + datum), dán
+pas de formulier-pagina — zelfde volgorde die bij bouwstap 1/2 goed
+werkte.
+
+---
+
 **P2-16 · Eigenaar: Bob** (klein). Tabnamen gelijktrekken met de site.
 Home: app heeft Uitgaan/Activiteiten/Cultuur/Films/Jeugd, site heeft
 Uitgaan/Stadsactiviteiten/Cultuur&Info → "Activiteiten" wordt