Просмотр исходного кода

Live gebruikerstest (Claude, sessie 2026-08-07 avond): nieuwe P0-6
(debug-navigatieknoppen zichtbaar op productie-Login-pagina) en P1-17
(Engelse locale-fallback zonder echte vertalingen) gevonden; P2-9
(onboarding + dode Home-terugknop) en P1-15 (No-host-URI-scope)
bijgewerkt met live bevestiging op emulator na VM-herstart.
CLAUDE.md: locale/vertaling-architectuur vastgelegd als duurzaam
inzicht.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

bob 1 месяц назад
Родитель
Сommit
d0014f44cb
3 измененных файлов с 122 добавлено и 28 удалено
  1. 14 0
      CLAUDE.md
  2. 104 24
      TASKS.md
  3. 4 4
      ios/Runner.xcodeproj/project.pbxproj

+ 14 - 0
CLAUDE.md

@@ -479,6 +479,20 @@ letterlijke `[varname]`-tekst meegestuurd i.p.v. de testwaarde.
 
 
 ## Domein/architectuurcontext
 ## Domein/architectuurcontext
 
 
+- **Taal/locale volgt het toestel, niet hardcoded Nederlands** — zonder
+  opgeslagen voorkeur (`FFLocalizations`/`_kLocaleStorageKey`) valt
+  `MaterialApp.locale` terug op de systeemtaal van het toestel; matcht
+  die met `'en'` (tweede taal in `FFLocalizations.languages() =
+  ['nl','en']`), dan draait de app in het Engels. **Er is vrijwel geen
+  echte Engelse vertaling** (zie `TASKS.md` P1-17, live bevestigd
+  2026-08-07: van 169 sleutels in
+  `lib/flutter_flow/internationalization.dart` zijn er maar 2 waar
+  `nl`/`en` daadwerkelijk verschillen, en één daarvan is een fout
+  i.p.v. een vertaling). Test dus altijd met het testtoestel/de
+  emulator op Nederlands (`adb shell getprop ro.product.locale`
+  checken), anders lijkt de UI kapot terwijl het eigenlijk gewoon de
+  ontbrekende Engelse vertaling is.
+
 - **Drupal 7 Services sessie-auth**: `sessid` + `session_name` (uit
 - **Drupal 7 Services sessie-auth**: `sessid` + `session_name` (uit
   `LoginCall`'s response) vormen samen de sessie-cookie:
   `LoginCall`'s response) vormen samen de sessie-cookie:
   `Cookie: <session_name>=<sessid>`. `token` is een los CSRF-token,
   `Cookie: <session_name>=<sessid>`. `token` is een los CSRF-token,

+ 104 - 24
TASKS.md

@@ -5,19 +5,23 @@ werkinstructies/conventies. Elke openstaande taak hieronder is
 zelfstandig te begrijpen zonder de chat gelezen te hebben waarin hij
 zelfstandig te begrijpen zonder de chat gelezen te hebben waarin hij
 ontstond.
 ontstond.
 
 
-**Deze review-sessie (2026-08-07 middag):** volledige doorloop van
-open taken + code-audit, plus een eerste "ogen van een gebruiker"-blik
-op ontbrekende functionaliteit (zie nieuwe P1-15/P1-16/P2-9/P2-10
-hieronder). **Nog niet gedaan: een live doorklik-review op de
-draaiende app** — er liep tijdens deze sessie nog een andere
-sessie/build (`flutter run` sinds 14:11 op emulator + een run op een
-2e device sinds 14:29, ongecommitte export van P1-14/P1-9-werk) en de
-emulator/browser is bewust niet aangeraakt om dat werk niet te
-verstoren. **Volgende sessie: alsnog een live gebruikersdoorloop doen**
-zodra de emulator vrij is (check eerst `git status`/`adb devices` of
-er nog een actieve build/sessie is) — met name onboarding/eerste-
-gebruik (zie P2-9) kon nu alleen op basis van code ingeschat worden,
-niet bevestigd.
+**Deze review-sessie (2026-08-07, middag+avond):** volledige doorloop
+van open taken + code-audit, plus een live "ogen van een
+gebruiker"-doorloop op de emulator (ná herstart van Bob's desktop/
+Android-VM wegens een OOM — app opnieuw opgestart via de standaard
+`ff-run-fvm.sh`-workflow, daarna `pm clear` om een echte
+eerste-launch-ervaring te simuleren). Concrete live vondsten: zie
+nieuwe **P0-6** (test-navigatieknoppen zichtbaar op de productie-
+Login-pagina — grootste vondst van de sessie), **P1-17** (Engelse
+locale-fallback + vrijwel geen echte vertalingen), aangevulde **P2-9**
+(onboarding + dode terug-knop op Home, nu live bevestigd i.p.v.
+ingeschat) en **P1-15** (scope groter dan gedacht). Kanttekening: de
+emulator vertoonde ook wat omgevingsinstabiliteit (kort een "System UI
+isn't responding"-melding vlak na herstart, en `flutter run` verloor
+op een gegeven moment de verbinding met het device) — dat lijkt
+eerder aan de verse VM-herstart/host-belasting te liggen dan aan de
+app zelf, dus niet 1-op-1 als app-bug behandelen, maar wel vermeld
+voor het geval het patroon terugkomt.
 
 
 **Formaat van elke taak:** `**P0-1 · Eigenaar: ...**` als eerste regel
 **Formaat van elke taak:** `**P0-1 · Eigenaar: ...**` als eerste regel
 — een stabiel nummer (verandert niet als andere taken worden
 — een stabiel nummer (verandert niet als andere taken worden
@@ -99,6 +103,37 @@ tijd stoppen goed te doen.
 
 
 ## P0 — blokkeert livegang
 ## P0 — blokkeert livegang
 
 
+**P0-6 · Eigenaar: Onbepaald (mechanisch: widgets verwijderen/verbergen
+in de builder).** **Live bevestigd 2026-08-07 (Claude, emulator, verse
+app-data/eerste-launch-simulatie):** de **Login-pagina** toont onder de
+"Wachtwoord vergeten?"-link **5 interne test-/debug-navigatieknoppen**,
+onvoorwaardelijk zichtbaar voor elke echte gebruiker (geen
+`kDebugMode`-check, gewoon standaard `FFButtonWidget`s in
+`lib/login/login/login_widget.dart` r. 665-880):
+"HorecagelegenhedenOverzichtPag…", "selectprovinciegemeent",
+"horecagelegenheid 57897" (hardcoded test-nid), "puitgaan", en
+"kanwegtest" (linkt naar `KanwegWidget` — Bob's eigen
+scratch-testgebied, zie `lib/kanweg` elders in dit document). Dit moet
+er sowieso uit vóór livegang — een productie-loginscherm met
+zichtbare interne testknoppen (incl. een link naar de scratch-pagina)
+oogt onafgemaakt/onprofessioneel en is verwarrend voor een nieuwe
+gebruiker. **Fix:** de 5 bijbehorende `FFButtonWidget`-nodes in de
+Widget Tree van `Login` verwijderen (of, als ze voor Bob's eigen
+handige interne navigatie tijdens development moeten blijven bestaan,
+wrappen in een conditie die alleen in een niet-productie-omgeving
+zichtbaar is — verwijderen is eenvoudiger en veiliger).
+
+**Sub-bevinding, zelfde pagina/bevinding:** de e-mail- en
+wachtwoordvelden op Login hebben geen echte placeholder-tekst
+ingesteld — `hintText` is nog gebonden aan de FlutterFlow-standaardtekst
+"TextField" (keys `d507d3b9`/`t8h5f8ir` in
+`lib/flutter_flow/internationalization.dart`, `nl: 'TextField'`,
+`en: ''`). In het Nederlands zie je dus het onbedoelde woord
+"TextField" in beide velden; **in het Engels (zie P1-17) zijn de
+velden zelfs volledig leeg — de gebruiker weet dan niet wat hij moet
+invullen.** Fix: `hintText` op beide velden een echte tekst geven
+("E-mailadres" / "Wachtwoord") in zowel de `nl`- als `en`-vertaling.
+
 **P0-1 · Eigenaar: Bob (10 sec klusje) — bevestigd nog open
 **P0-1 · Eigenaar: Bob (10 sec klusje) — bevestigd nog open
 (2026-08-05).** Home-slider crasht (RangeError) bij 0 API-resultaten.
 (2026-08-05).** Home-slider crasht (RangeError) bij 0 API-resultaten.
 Bob koos: bij 0 resultaten component overslaan (niets tonen), geen
 Bob koos: bij 0 resultaten component overslaan (niets tonen), geen
@@ -304,6 +339,15 @@ verwarren — twee losse foutmeldingen in dezelfde log).
   velden, maar daar is maar 1 losse `!= null &&`-treffer gevonden —
   velden, maar daar is maar 1 losse `!= null &&`-treffer gevonden —
   niet diep genoeg nagekeken deze sessie om zeker te zijn dat het daar
   niet diep genoeg nagekeken deze sessie om zeker te zijn dat het daar
   wél goed staat).
   wél goed staat).
+- **Scope vermoedelijk groter dan gedacht:** 2026-08-07, live op de
+  emulator, verscheen `Invalid argument(s): No host specified in
+  URI` al herhaaldelijk **op/vanaf de Home-pagina zelf**, vóór enige
+  navigatie naar een horecagelegenheid-detailpagina. Dat wijst erop
+  dat hetzelfde kapotte-guard-patroon ook in Home-gerelateerde
+  componenten zit (bv. de Home-sliderkaartjes of de "OOK LEUK"-tegels),
+  niet alleen in `evenement_horecagelegenheid_widget.dart`. Nog niet
+  tot de exacte plek herleid — bij oppakken van deze taak breder zoeken
+  dan alleen het al gevonden bestand.
 
 
 **P1-16 · Eigenaar: Bob (Firebase-koppeling is account-/builder-niveau,
 **P1-16 · Eigenaar: Bob (Firebase-koppeling is account-/builder-niveau,
 geen Claude-taak).** Geen crash-reporting/analytics (bv. Firebase
 geen Claude-taak).** Geen crash-reporting/analytics (bv. Firebase
@@ -317,6 +361,31 @@ Zonder dit blijft elke toekomstige crash-bug (nieuwe RenderFlex-
 overflows, een volgende `launchURL`-achtige misser) onzichtbaar totdat
 overflows, een volgende `launchURL`-achtige misser) onzichtbaar totdat
 een gebruiker 'm toevallig meldt.
 een gebruiker 'm toevallig meldt.
 
 
+**P1-17 · Eigenaar: Onbepaald.** **Live bevestigd 2026-08-07 (Claude,
+emulator met systeemtaal en-US, verse app-data):** de app valt terug op
+**Engels** zodra het toestel niet op Nederlands staat (geen opgeslagen
+taalvoorkeur → `MaterialApp.locale` is `null` → Flutter matcht het
+systeem-`en-US` tegen de ondersteunde `['nl','en']`-lijst en kiest
+`en`). Dat zou op zich geen probleem zijn als er een echte Engelse
+vertaling stond — **die is er vrijwel niet:** van de 169 sleutels in
+`lib/flutter_flow/internationalization.dart` zijn er 50 waar `nl`/`en`
+toevallig identiek zijn (onvertaald), 44 waar **beide talen leeg zijn**
+(dus zichtbaar niets, zoals de Login-hinttekst uit P0-6), en slechts 1
+sleutel met een bewust andere Engelse tekst — en die ene is fout: key
+`7pacsyhe` (het hartje-menu-item in de drawer) toont `nl: 'Favorieten'`
+maar `en: 'Home'`, dus **een Engelstalig toestel ziet twee menu-items
+met de tekst "Home"** (huis-icoon én hartje-icoon) — verwarrend, de
+favorieten zijn zo niet te vinden. **Iedere gebruiker met een
+Engelstalig toestel** (niet ongebruikelijk, ook onder Nederlanders)
+krijgt dus een merkbaar kapotte/lege interface. **Aanbevolen fix (snel,
+vóór er echt in vertalen geïnvesteerd wordt):** forceer de locale
+hard op `'nl'` (verwijder `'en'` uit `FFLocalizations.languages()`/
+`supportedLocales`, of zet een harde default) totdat er een bewuste
+keuze is om Engels aan te bieden — een niet-vertaalde app blijft zo
+altijd nette Nederlandse tekst tonen in plaats van willekeurig kapotte
+Engelse tekst. Losstaand echt vertalen is een grotere, aparte
+contentklus (niet meegenomen in deze taak).
+
 **P1-7 · Eigenaar: Bob.** Account/profielscherm (wachtwoord wijzigen,
 **P1-7 · Eigenaar: Bob.** Account/profielscherm (wachtwoord wijzigen,
 uitloggen, account verwijderen). Bovenop de login/favorieten-P0-basis.
 uitloggen, account verwijderen). Bovenop de login/favorieten-P0-basis.
 Account verwijderen heeft mogelijk AVG-implicaties aan Drupal-kant.
 Account verwijderen heeft mogelijk AVG-implicaties aan Drupal-kant.
@@ -546,19 +615,30 @@ horeca-detailpagina · reviews/waardering voor horecagelegenheden
 (De "Wat is er vanavond"-melding is uitgelicht naar **P2-10** hieronder
 (De "Wat is er vanavond"-melding is uitgelicht naar **P2-10** hieronder
 — dat idee weegt zwaarder dan de rest van dit lijstje.)
 — dat idee weegt zwaarder dan de rest van dit lijstje.)
 
 
-**P2-9 · Eigenaar: Onbepaald — nog te verifiëren op de live app.**
-Onboarding/eerste-gebruik-uitleg. **Vanuit gebruikersperspectief
-(2026-08-07-review, code-niveau, nog niet live bevestigd):** een
-nieuwe gebruiker die de app voor het eerst opent, ziet vermoedelijk
-meteen een lijst/kaart zonder korte uitleg wat "Uitgaanskrant" is of
-hoe de provincie/gemeente-keuze werkt (zie ook P0-3's opmerking dat de
+**P2-9 · Eigenaar: Onbepaald.** Onboarding/eerste-gebruik-uitleg.
+**Live bevestigd 2026-08-07 (Claude, emulator, `pm clear` + verse
+launch = echte eerste-keer-ervaring):** een nieuwe gebruiker opent de
+app en ziet **direct** de Home-pagina met bovenaan een carousel met
+kop "OOK LEUK" ("ook leuk" veronderstelt dat je al iets gezien hebt —
+vreemd als allereerste tekst) en daaronder een kale lijst events, geen
+welkomsttekst, geen uitleg wat Uitgaanskrant is, geen prompt om een
+provincie/gemeente te kiezen. (Zie ook P0-3's opmerking dat de
 eerste-launch-default-locatie 28666/28694 geen naam toont totdat
 eerste-launch-default-locatie 28666/28694 geen naam toont totdat
-iemand handmatig kiest). Zonder duidelijke eerste indruk is de kans
+iemand handmatig kiest.) Zonder duidelijke eerste indruk is de kans
 groot dat een nieuwe gebruiker de app na 1x openen niet snapt/niet
 groot dat een nieuwe gebruiker de app na 1x openen niet snapt/niet
-terugkomt. **Volgende sessie: eerst live bevestigen** (emulator, app
-verwijderen/opnieuw installeren voor een schone eerste-launch-state)
-of dit al opgevangen wordt, vóórdat hier een concrete builder-fix
-wordt voorgesteld.
+terugkomt. Nog geen concrete builder-fix uitgewerkt — eerst met Bob
+bespreken wat voor onboarding gewenst is (korte welkomsttekst? meteen
+naar provincie/gemeente-keuze i.p.v. Home?) vóórdat dit gebouwd wordt.
+- **Bijvangst, zelfde verkenning:** Home's AppBar heeft een
+  hardcoded terug-pijl-knop (`Icons.arrow_back_outlined`, roept
+  `context.pop()` aan) naast het hamburger-menu-icoon
+  (`lib/uitgaanspaginas/home/home_widget.dart`, rond de
+  `FlexibleSpaceBar`). Op de root-pagina is er niets om naar terug te
+  gaan — live getest, de knop doet niets (geen crash, stille no-op),
+  maar oogt verwarrend/onafgemaakt op het allereerste scherm. Kleine
+  fix: knop weghalen op Home, of `automaticallyImplyLeading`/
+  conditie gebruiken zodat hij alleen verschijnt op pagina's waar
+  terug-navigeren zinvol is.
 
 
 **P2-10 · Eigenaar: Onbepaald.** "Vanavond in [gemeente/provincie]"-
 **P2-10 · Eigenaar: Onbepaald.** "Vanavond in [gemeente/provincie]"-
 herinnering (pushmelding of in-app-widget) — uitgelicht uit de
 herinnering (pushmelding of in-app-widget) — uitgelicht uit de

+ 4 - 4
ios/Runner.xcodeproj/project.pbxproj

@@ -44,8 +44,8 @@
 		97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
 		97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
 		97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
 		97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
 		97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
 		97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
-		6436409F27A31CD900820AF7 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
-		6436409927A31CDE00820AF7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		6436409027A31CD700820AF7 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		6436409F27A31CDC00820AF7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
 		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
 
 
@@ -225,8 +225,8 @@
 		6436409C27A31CD800820AF7 /* InfoPlist.strings */ = {
 		6436409C27A31CD800820AF7 /* InfoPlist.strings */ = {
 			isa = PBXVariantGroup;
 			isa = PBXVariantGroup;
 			children = (
 			children = (
-				6436409F27A31CD900820AF7 /* nl */,
-				6436409927A31CDE00820AF7 /* en */,
+				6436409027A31CD700820AF7 /* nl */,
+				6436409F27A31CDC00820AF7 /* en */,
 			);
 			);
 			name = InfoPlist.strings;
 			name = InfoPlist.strings;
 			sourceTree = "<group>";
 			sourceTree = "<group>";