Commits
- 114-point boundary polygon from Census TIGER/Line shapefile
- Empty bands.json (no events listed yet)
- Added to City type, CITY_CONFIG, path mappings, and global cities
- Updated component geojson paths, vite build copy, and tests
- Scrape from https://swampscottporchfest.org/map/ using Pattern B (JS object dump)
- 36 scheduled bands (5 unsolved gigs skipped), hourly zone buckets 12-5PM
- City boundary GeoJSON from Nominatim
- Add to City union type, cityConfig.ts, components.tsx, vite.config.js
- Unit + E2E tests for swampscott
- Scraper at data/gloucester-magnolia/scraper.js (curated static data + Nominatim geocoding)
- 18 bands for Magnolia Library PorchFest, May 23, 2026 (single zone)
- City type extended to include gloucester-magnolia
- UI config, GeoJSON paths, Vite copy step, and E2E offline tests updated
- AGENTS.md updated to reflect 4-city support
- Add hamburger/close toggle button visible on desktop (src/index.tsx:115-133)
- Mobile sidebar: full-width overlay, toggle-able, closed by default
- Desktop sidebar: hidden when sidebarOpen=true, show/hide icon switches
- Add E2E test verifying toggle button controls sidebar visibility and icon state swap
- LeafletControl: fix 3 overlapping buttons (added top offsets), remove ZONE_LABEL_MAP duplication, wire locate button
- index.tsx: eliminate loading state (derive from !bands), remove no-op zoom handlers, remove redundant map div style
- components.tsx: replace Floater with MapSizeFixer, consolidate duplicate isWithdrawn, replace setTimeout scroll with useEffect, fix Legend/ BandRow colors via constants, stable BandRow keys
- types.ts: remove dead ZoneMap, single new Date() in getCurrentActiveZone, eliminate dt2p/timeToMinutes duplication, fix filterBands single-loop, retain Brussels bounding box for zoom quality
- index.css: remove 16 lines dead .sidebar CSS
- All UI components (SearchBar, AppStats, Legend, BandList, BandRow, BandMarker, LeafletControl) use Tailwind utility classes
- Zone colors mapped to closest Tailwind palette hex values (amber/blue/teal)
- index.css reduced to only essential scrollbar styling and Leaflet container sizing
- Layout (header, sidebar/map-pane, flex structure) rewritten with Tailwind
- E2E tests updated to match new selectors
- package.json: 'playwright test --timeout=30000' so npm run test:e2e
always has the safety limit
- AGENTS.md: documents npm run test:e2e as the single source of truth
for running tests (never npx playwright test directly)
- e2e/basic.spec.js: updated usage comment to match
- Removed _mapRef global variable (no longer read by App callbacks)
- Removed dead global markers dict
- Floater now just uses useMap() to assert context (side-effect)
- Clean 8-line diff finalizing the full migration
- Replace manual L.circleMarker() + useEffect lifecycle with <CircleMarker> + eventHandlers
- Removed BandMarker from BandRow (sidebar) to avoid React-Leaflet context errors
- BandMarkers now render inside MapContainer as a child prop (bandMarkers)
- Popup renders inside CircleMarker via react-leaflet's component model
- AGENTS.md: added critical --timeout=30000 rule for Playwright CLI
- Net: ~107 lines removed (global _mapRef, markers dict, verbose useEffect, LeafletControl restructure)
- Replace manual L.map() with <MapContainer> from react-leaflet
- Extract zoom/geolocation controls into LeafletControl.tsx via useMap()/useMapEvents()
- Update E2E tests from #mapid to .leaflet-container
- Add react-leaflet@5.0.0 to package.json
- Net: 63 lines removed, 22 added (Map component)
- Replace preact/preact/hooks with react/react-dom/react-dom/client
- Replace render() with createRoot()
- Replace ComponentChild with ReactNode, onInput with onChange
- Replace class= with className=
- Remove Leaflet CDN from index.html (now bundled by Vite)
- Add BandRow component to consolidate duplicate BandMarker rendering
- Fix duplicate React keys (m- vs m2- prefix)
- Add Leaflet CSS import via vite-env.d.ts TypeScript declaration
- Update tsconfig to remove jsxImportSource: preact
- Map no longer extends behind the fixed header bar (100vh → calc(
100vh - 52px) with 52px margin-top on the map canvas)
- Zoom + and Zoom - buttons are no longer obscured by the search
bar
- Restore getCurrentActiveZone() — show an active zone pill centered
at the top of the map during band hours (12pm–6pm)
- Always show a 'Festive schedule: 12pm–6pm' pill outside active zone
hours
- Scraper at data/gloucester-magnolia/scraper.js (curated static data + Nominatim geocoding)
- 18 bands for Magnolia Library PorchFest, May 23, 2026 (single zone)
- City type extended to include gloucester-magnolia
- UI config, GeoJSON paths, Vite copy step, and E2E offline tests updated
- AGENTS.md updated to reflect 4-city support
- Add hamburger/close toggle button visible on desktop (src/index.tsx:115-133)
- Mobile sidebar: full-width overlay, toggle-able, closed by default
- Desktop sidebar: hidden when sidebarOpen=true, show/hide icon switches
- Add E2E test verifying toggle button controls sidebar visibility and icon state swap
- LeafletControl: fix 3 overlapping buttons (added top offsets), remove ZONE_LABEL_MAP duplication, wire locate button
- index.tsx: eliminate loading state (derive from !bands), remove no-op zoom handlers, remove redundant map div style
- components.tsx: replace Floater with MapSizeFixer, consolidate duplicate isWithdrawn, replace setTimeout scroll with useEffect, fix Legend/ BandRow colors via constants, stable BandRow keys
- types.ts: remove dead ZoneMap, single new Date() in getCurrentActiveZone, eliminate dt2p/timeToMinutes duplication, fix filterBands single-loop, retain Brussels bounding box for zoom quality
- index.css: remove 16 lines dead .sidebar CSS
- All UI components (SearchBar, AppStats, Legend, BandList, BandRow, BandMarker, LeafletControl) use Tailwind utility classes
- Zone colors mapped to closest Tailwind palette hex values (amber/blue/teal)
- index.css reduced to only essential scrollbar styling and Leaflet container sizing
- Layout (header, sidebar/map-pane, flex structure) rewritten with Tailwind
- E2E tests updated to match new selectors
- Replace manual L.circleMarker() + useEffect lifecycle with <CircleMarker> + eventHandlers
- Removed BandMarker from BandRow (sidebar) to avoid React-Leaflet context errors
- BandMarkers now render inside MapContainer as a child prop (bandMarkers)
- Popup renders inside CircleMarker via react-leaflet's component model
- AGENTS.md: added critical --timeout=30000 rule for Playwright CLI
- Net: ~107 lines removed (global _mapRef, markers dict, verbose useEffect, LeafletControl restructure)
- Replace preact/preact/hooks with react/react-dom/react-dom/client
- Replace render() with createRoot()
- Replace ComponentChild with ReactNode, onInput with onChange
- Replace class= with className=
- Remove Leaflet CDN from index.html (now bundled by Vite)
- Add BandRow component to consolidate duplicate BandMarker rendering
- Fix duplicate React keys (m- vs m2- prefix)
- Add Leaflet CSS import via vite-env.d.ts TypeScript declaration
- Update tsconfig to remove jsxImportSource: preact
- Map no longer extends behind the fixed header bar (100vh → calc(
100vh - 52px) with 52px margin-top on the map canvas)
- Zoom + and Zoom - buttons are no longer obscured by the search
bar
- Restore getCurrentActiveZone() — show an active zone pill centered
at the top of the map during band hours (12pm–6pm)
- Always show a 'Festive schedule: 12pm–6pm' pill outside active zone
hours