Commit graph

10 commits

Author SHA1 Message Date
2ebbf76a80 experiment: shade excluded Bezirke on map (faint yellow overlay)
Tints districts the user's Bezirk filter has EXCLUDED in light yellow
(#fde68a, fillOpacity 0.35) so the active selection is obvious from
the map alone — and you can see at a glance whether a "rausgefiltert"
flat fell in a no-go district. When no district filter is set the
overlay stays off entirely (nothing is excluded).

Wiring:
- Berlin Bezirke GeoJSON checked in at web/static/berlin-districts.geojson
  (12 features, name property matches our DISTRICTS list 1:1, props
  stripped down to {name} and minified — 312KB raw, ~80KB gzipped).
- Route exposes the user's selected_districts_csv to the template.
- The flats-map-data <script> carries it on data-selected-districts so
  it flows in alongside csrf and the marker payload.
- map.js fetches the GeoJSON once (cache normally), keeps the layer in
  a module-level reference, and re-styles it via setStyle() on every
  swap (cheap). Marker layer is kicked to the front so pins always
  paint above the shaded polygons. fingerprintOf now also folds in
  the selected-districts CSV so a Bezirk-only filter change still
  triggers a re-render.

Branch only — kept off main while we see if this reads well.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 13:30:30 +02:00
787f848aba feat(ui): green map pin for applied flats, hide map reject after apply, lightbox image viewer
Map: replace Leaflet's default marker with a divIcon SVG pin coloured
per state — green when the user has already successfully applied
(status.chip === "ok"), brand-blue otherwise. Same condition also hides
the action buttons in the popup, matching the list view, which already
hid both Bewerben and Ablehnen on success — so the only remaining
action on an applied flat is opening the original ad link.

Image gallery: clicks now open a global lightbox modal instead of a new
tab. The viewer fits each image into the viewport via max-width/height
+ object-fit: contain (uniform sizing regardless of source aspect),
shows × top-right, prev/next arrows on the sides, ←/→/Esc keyboard
nav, and click-on-backdrop to close. Prev arrow is hidden on the first
image and next on the last. Tile changes from <a target="_blank"> to
<button> since the new-tab fallback is no longer wanted.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 12:37:15 +02:00
931e0bb8b7 map: clickable address + status chip + Bewerben/Ablehnen in Leaflet popups
- map_points payload now carries flat id, per-user status, can_apply, is_running
- Popup titles link to the listing; status chip mirrors the list (beworben /
  läuft… / fehlgeschlagen); Bewerben + Ablehnen submit via the same HTMX
  endpoints as the list, re-swapping #wohnungen-body
- csrf token rides on the script[data-csrf] sibling of #flats-map
- popupopen → htmx.process(popupEl) so hx-* on freshly injected DOM binds
- site-style .map-popup-* CSS hooked into Leaflet's popup wrapper

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 14:01:11 +02:00
7f7cbb5b1f cleanup: drop coord backfill, drop transit overlay, block PM autofill
- Remove the admin "Koordinaten nachladen" button, /actions/backfill-coords
  endpoint, geocode.py, googlemaps dep, GMAPS_API_KEY plumbing in the web
  service, and the map diagnostic line. Going-forward geocoding happens in
  alert on scrape; upsert_flat backfill on re-submit remains for edge cases
- Remove the OpenRailwayMap transit overlay (visually noisy); keep CartoDB
  Voyager as the sole basemap
- Profile + notifications forms get autocomplete="off" + data-lpignore +
  data-1p-ignore at form and field level to keep password managers from
  popping open on /einstellungen; immomio_password uses autocomplete=new-password

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 13:55:24 +02:00
ceb2486f35 map: fixed Berlin view, CartoDB Voyager tiles, OpenRailwayMap transit overlay
- Drop the fitBounds-to-markers logic so the map always opens at the same
  Berlin-wide view (center 52.52/13.405, zoom 11), regardless of pin count
- Swap OSM standard tiles for CartoDB Voyager — cleaner, more
  Google-Maps-like base style
- Add OpenRailwayMap overlay (opacity .75) so S-/U-Bahn/Tram lines are
  highlighted on top of the base
- CSP img-src widened to cover the new tile hosts

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 13:48:46 +02:00
0c58242ce7 map debug + coord backfill, remove email channel, countdown label
- Surface "X/Y passende Wohnungen mit Koordinaten" on the Karte view +
  admin-only "Koordinaten nachladen" button (POST /actions/backfill-coords)
  that geocodes missing flats via Google Maps directly from the web container
- Add googlemaps dep + GMAPS_API_KEY env to web service
- Light console.log in map.js ("rendering N/M markers", "building Leaflet…")
  so the browser DevTools shows what's happening
- Drop e-mail channel from notifications UI, notify dispatcher, and _alert_status;
  coerce legacy 'email' channel rows back to 'ui' on save
- Countdown said "Aktualisierung läuft…" next to "nächste Aktualisierung" →
  shortened to "aktualisiere…"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 13:42:21 +02:00
51b6b02b24 wohnungen: preserve map across HTMX polls, add rejected section, drop €/m²
- #flats-map uses hx-preserve; marker data moved to <script type="application/json">
  sibling that diffs+updates instead of rebuilding Leaflet every poll (fixes
  whitescreen + tiles rendering outside the card)
- upsert_flat backfills lat/lng on existing rows missing coords (older flats
  scraped before the lat/lng migration now appear on the map once alert re-submits)
- collapsible "Abgelehnte Wohnungen" section at the bottom with Wiederherstellen
- remove €/m² column from the list

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 13:33:55 +02:00
Moritz
4fd0b50a43 fix: lazy-init Leaflet map so tiles actually load
The map was being initialised on DOMContentLoaded even when its container
was display:none (0×0). Leaflet sets up internal bounds from container size
at init; on a zero-sized container no tiles are ever requested. Even
invalidateSize afterwards didn't recover reliably.

* map.js now only builds the Leaflet instance once the container has real
  dimensions (clientHeight >= 10). Triggered when the view toggle flips to
  Karte (rAF x2 + safety timers), and via restoreView on page load if the
  user's last choice was Karte.
* CSP img-src now includes https://unpkg.com for Leaflet marker icons.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 12:14:54 +02:00
Moritz
42377f0b67 UX: alarm-status, ablehnen-button, annika-footer, map polish
* Alarm-Status ist jetzt nur 'aktiv' wenn ein echter Push-Channel (Telegram
  mit Token+Chat oder E-Mail mit Adresse) konfiguriert ist. UI-only zählt
  nicht mehr als eingerichteter Alarm.
* Ablehnen-Button in der Wohnungsliste: flat_rejections (migration v4)
  speichert pro-User-Ablehnungen, abgelehnte Flats fallen aus Liste und
  Karte raus. Wiederholbar pro User unabhängig.
* Footer 'Programmiert für Annika ♥' erscheint nur auf Seiten, wenn annika
  angemeldet ist.
* Map: Hinweistext unter leerer Karte entfernt; alle Zoom-Mechanismen
  deaktiviert (Scrollrad, Doppelklick, Box, Touch, Tastatur, +/- Buttons).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 12:09:44 +02:00
Moritz
376551213a map view (Leaflet + OSM), iOS switches, Alarm → Benachrichtigungen
* flats: new lat/lng columns (migration v3); alert geocodes every new flat
  through googlemaps and ships coords in the payload
* web: CSP extended for unpkg (leaflet.css) + tile.openstreetmap.org
* Wohnungen tab: Liste/Karte view toggle (segmented, CSS-only via :has(),
  selection persisted in localStorage). Karte shows passende flats as Pins
  on an OSM tile map; Popup per Pin mit Adresse, Zimmer/m²/€ und Link
* Top-strip toggles are now proper iOS-style toggle switches (single
  rounded knob sliding in a pill, red when on), no descriptive subtitle
* Alarm-Karte verlinkt jetzt auf /einstellungen/benachrichtigungen
  (Filter-Karte bleibt /einstellungen/filter)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 12:02:40 +02:00