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>
This commit is contained in:
EiSiMo 2026-04-21 13:42:21 +02:00
parent 51b6b02b24
commit 0c58242ce7
11 changed files with 149 additions and 58 deletions

View file

@ -11,7 +11,6 @@
<select class="input" name="channel">
<option value="ui" {% if notifications.channel == 'ui' %}selected{% endif %}>Nur im Dashboard (kein Push)</option>
<option value="telegram" {% if notifications.channel == 'telegram' %}selected{% endif %}>Telegram</option>
<option value="email" {% if notifications.channel == 'email' %}selected{% endif %}>E-Mail</option>
</select>
</div>
@ -26,12 +25,6 @@
<input class="input" name="telegram_chat_id" value="{{ notifications.telegram_chat_id }}" placeholder="987654321">
</div>
<div>
<label class="block text-xs uppercase text-slate-500 mb-1">E-Mail Adresse</label>
<input class="input" type="email" name="email_address" value="{{ notifications.email_address }}"
placeholder="du@example.com">
</div>
<div class="border-t border-soft pt-4 space-y-2">
<label class="flex items-center gap-2">
<input type="checkbox" name="notify_on_match" {% if notifications.notify_on_match %}checked{% endif %}>

View file

@ -97,7 +97,26 @@
</section>
<!-- Karte (Leaflet-Container bleibt über HTMX-Swaps hinweg erhalten) -->
<section class="view-map">
<section class="view-map space-y-2">
<div class="card p-3 text-xs text-slate-600 flex items-center justify-between gap-3 flex-wrap">
<div>
{{ map_matched_with_coords }} / {{ map_matched_total }} passende Wohnungen mit Koordinaten
{% if map_matched_without_coords %}
· <span class="chip chip-warn">{{ map_matched_without_coords }} ohne Koordinaten</span>
{% endif %}
</div>
{% if is_admin and map_matched_without_coords %}
<form method="post" action="/actions/backfill-coords"
hx-post="/actions/backfill-coords" hx-target="#wohnungen-body" hx-swap="outerHTML">
<input type="hidden" name="csrf" value="{{ csrf }}">
<button class="btn btn-ghost text-xs" type="submit"
{% if not gmaps_available %}disabled title="GMAPS_API_KEY fehlt"{% endif %}
hx-confirm="Fehlende Koordinaten jetzt über Google Maps nachladen?">
Koordinaten nachladen
</button>
</form>
{% endif %}
</div>
<div class="card p-3">
<div id="flats-map" hx-preserve="true"></div>
</div>