Commit graph

24 commits

Author SHA1 Message Date
96119e02ef Seitenkarten GL Runde 2: Events, Gassi, Routen + Facade-Erweiterung
- Facade: Polyline (geojson line-source, addTo/setLatLngs/getBounds/remove), clusterGroup,
  marker.getLatLng, map.distance(Haversine), on('click') normalisiert e.latlng aus e.lngLat, _ll objekttauglich
- events: L.markerClusterGroup→UI.map.clusterGroup
- walks: window.L-Guard, L.featureGroup→UI.map.featureGroup, fitBounds ohne .pad
- routes: L.polyline/L.circleMarker→UI.map.*, navMap/Pfeil-Marker→svgMarker, latLngBounds→coords,
  trimMap distance/click, Mini-Vorschauen auf SVG (kein WebGL-Limit, kein OSM-Raster)
2026-06-05 12:48:09 +02:00
c07b1cc01b Fix: restliche CSP-blockierte Inline-Handler — Bild-Fallbacks (globaler data-fb Error-Handler) + Hover-Effekte (CSS-Utilities + data-hover-play)
App ist jetzt vollständig frei von Inline-Event-Handlern (onerror/onmouseenter/etc.).
data-fb Modi: hide/hide-parent/dim-grandparent/sibling/show-el/emoji/initials + data-fb-src.
Hover: .by-hover-lift/-surface2/-surface3 in utilities.css. SW v1165
2026-06-04 16:22:43 +02:00
2ddd8ac350 Fix: alle funktionalen Inline-Event-Handler → addEventListener/Delegation (von CSP-Härtung 65cfa25 app-weit blockiert)
Chat (senden/öffnen/löschen/Foto), Tagebuch-Buch, KI-Berichte, Wiki-Moderation,
Events-Detail, Walks-Lightbox, Routen-Foto, Navigations-CTAs (data-page),
Presse-Copy + Züchter-Landing (externes JS). 35x UI.modal.close → data-modal-close,
28x totes event.stopPropagation entfernt. Verbleibend: kosmetische onerror/Hover. SW v1164
2026-06-04 13:59:27 +02:00
10e39ed135 Karten-Ausbau (OSM), Forum-Erweiterung, UI-Komponenten, Refactor Tagebuch/Gassi (DRY), Landing/SEO — APP_VER 1155 2026-06-03 17:24:47 +02:00
7b3041fc94 DRY: Notiz-Modal zentral in UI.noteModal (11 divergierte Kopien entfernt, ~750 Z. weniger); Fix: Founder-Race in jobs.py atomar + founder_number, SW v1133 2026-05-29 10:51:42 +02:00
73872e2c21 Sprint D: Karten-Familie auf UI.map.create+svgMarker konsolidiert, SW by-v1107
Neue zentrale Helper (in Sprint B vorbereitet) jetzt von 5 Seiten genutzt:

walks.js (1 Karten-Init):
- L.map+L.tileLayer → await UI.map.create('walks-map', {...})
- _initMap zu async, Aufrufer in _switchView und _loadData angepasst
- Mini-Karte im Walk-Formular (Modal) bleibt unverändert
  (braucht eigene dragging/scrollWheelZoom-Options)
- view-toggle nicht migriert (responsive CSS-Konflikt mit Desktop)

poison.js (1 Karten-Init):
- L.map+L.tileLayer → await UI.map.create('poison-map', {...})
- _initMap zu async, manueller UI.loadLeaflet entfernt
- DangerCircle + User-Marker unverändert

events.js (1 Karten-Init + Diamant-Marker):
- await UI.map.create('ev-map', {...})
- Rotierter Diamant: L.divIcon+L.marker → UI.map.svgMarker
  (HTML 1:1 erhalten)

lost.js (1 Karten-Init + Puls-Marker):
- Eigene async _loadLeaflet() Funktion komplett entfernt — UI.map.create
  übernimmt das jetzt zentral
- await UI.map.create('lost-map', {...})
- Puls-Animation 🐕: L.divIcon+L.marker → UI.map.svgMarker
- _initMap zu async

routes.js (6 von 7 Karten-Inits):
- _suggestMap, _recMap, _searchMap, _navMap, trimMap, _buildDetailMap
  alle auf UI.map.create umgestellt + zu async
- _buildMiniMap (Route-Card-Preview) bleibt unverändert
  (braucht 6 spezifische Interaction-Disable Options)
- View-Toggle auf neue .map-list-toggle Klasse umgestellt
  (Border-Inline-Styles raus)

NEUE CSS-KLASSE in components.css:
- .map-list-toggle (vereinheitlichter Karten/Listen-Umschalter)
- Verwendet von routes.js; walks/events können später folgen

Tests 19/19 grün. GPS-Tracking-Logik (Polylines, Recording, Trim)
komplett unangetastet. Marker-Cluster-Logik unverändert.
2026-05-27 08:17:06 +02:00
459cd425f2 Design-System Sprint A: utilities.css + 948 Inline-Styles → Utility-Klassen, SW by-v1102
PHASE 1 — Sofort-Cleanup ohne Risiko:
- Neue Datei utilities.css mit ~25 Klassen für häufige Kombinationen:
  * text-xs-muted, text-xs-secondary, text-sm-muted, text-sm-secondary
  * flex-gap-2/3, flex-col-gap-2/3/4, flex-center-gap-1/2/3
  * flex-between, flex-1-min, mb-1/3, mt-1/3
  * icon-xs/sm/md/lg, label-block, caption
- index.html bindet utilities.css ein
- mb-3/mt-3 ergänzt (waren in design-system.css unvollständig)

PHASE 2 — .by-tab Modifier für Vereinheitlichung:
- .by-tabs.grid (mit --tab-cols Variable für Admin/Health/etc.)
- .by-tabs.sticky (Desktop vertikale Tabs für Admin)
- .by-tabs.wrap (Zuchthunde, flex-wrap statt scroll)
- .by-tabs.separated (Sitting, mit eigenem Hintergrund + Border)

PHASE 3 — Inline-Style → Klassen-Migration (Python-Script):
- 948 Inline-Styles entfernt (5101 → 4153, -18%)
- 962 Migrationen über 47 Page-Dateien
- Top-Treffer: admin.js (180), health.js (67), dog-profile.js (67),
  litters.js (62), settings.js (61), zuchthunde.js (51)
- Patterns: text-muted, text-secondary, text-danger, text-xs-muted,
  text-sm-muted, grid-2 (Duplikat-Bug behoben!), flex-col-gap-3,
  p-3/4, mb-2/3/4, hidden, w-full, flex-1, ...
- Bewahrt bestehende class-Attribute (mergt korrekt)

Alle 19 Tests grün. Kein visueller Diff erwartet (gleiche Property-Werte).
2026-05-27 07:11:27 +02:00
c03884cb81 Perf: 9 Performance-Fixes — SW by-v1072
Backend:
- DB: 3 neue Indizes (forum_posts thread+user, routes user) — Forum/Routen-Queries
- Caching: cache.py (TTL-Cache ohne neue Dependency) für 5 statische Listen
  (training_exercises, pflege_tipps, wiki_stats, wiki_gruppen, help_articles)
- diary.py + breeder_photos.py: Bildverarbeitung (ffmpeg/PIL/EXIF) per
  run_in_executor → blockiert Event-Loop nicht mehr
- scheduler.py: 11 kollidierende Jobs auf 5-Min-Intervalle gestaggert, coalesce=True
- social.py: ORDER BY RANDOM() ohne LIMIT in 2 Stellen gefixt
- alerts.py: Haversine-Loop bekommt SQL-Bounding-Box-Vorfilter

Frontend:
- sw.js: Tile-Cache mit LRU-Eviction (max 500 Einträge)
- admin.js: Event-Listener-Leak — Tab-Klicks per Delegation statt N Listener
- api.js: compressImage() Helper — Client-seitiges Resize auf max 2000px
  (HEIC/Videos/<500KB unverändert), integriert in 8 Upload-Stellen
  (diary, dog-profile×2, walks, poison, lost, health×2)

Bump APP_VER 1071 → 1072 (sw.js, app.js, main.py, index.html)
2026-05-26 06:30:36 +02:00
32fde79a40 Fix: _queued-Guard in poison/walks/diary — kein Crash bei SW-gequeuten Requests
Wenn der SW einen POST in die Offline-Queue legt, gibt api.js { _queued: true }
zurück (202). Ohne Guard versuchten poison/walks/diary den Response als echtes
Server-Objekt zu nutzen → undefined lat/lon → Leaflet-Crash, undefined id → Upload-Fehler.
Nach dem Guard wird das Modal nur geschlossen; der QUEUE_PROCESSED-Toast informiert
den User sobald synchronisiert.

- poison.js: _queued guard nach API.poison.report()
- walks.js: _queued guard + try-catch statt navigator.onLine
- diary.js: _queued guard nach API.diary.create()
- SW by-v992, APP_VER 992
2026-05-15 17:56:29 +02:00
53fcb61933 Offline-Fallbacks für diary, poison, map + SW-Erweiterung
- sw.js: /api/places, /api/breeder/map-markers, /api/gassi-zeiten in _CACHEABLE_GET; /api/lost/report und /api/walks in _QUEUEABLE
- diary.js: localStorage-Cache pro Hund, Fallback bei Offline mit Toast
- poison.js: localStorage-Cache, Fallback bei Offline mit Toast (sicherheitsrelevant)
- map.js: POI-Cache (places/poison/breeders) in localStorage, Offline-Toast + Fallback auf gecachte Daten
2026-05-15 17:02:26 +02:00
79cfd63ea6 Fix: Gassi Desktop-Layout — Liste links + Karte rechts, Toggle ausgeblendet (SW by-v881) 2026-05-12 17:32:44 +02:00
44ba51cd38 Feature: Gassi-Hundefotos bei Teilnehmern + Fotos nach dem Treffen (SW by-v878) 2026-05-12 17:04:43 +02:00
b6a644ac3a Fix: Gassi-Karte fitBounds auf alle Treffen beim Öffnen (SW by-v877) 2026-05-12 10:07:28 +02:00
aa4849d947 Feature: 3 Community-Features — Foto-Challenge, Stamm-Gassis, Rassen-Chip (SW by-v700)
- Foto-Challenge der Woche: DB-Tabellen, routes/challenges.py (current/submit/vote/winners),
  Scheduler-Job jeden Montag 08:00, walks.js Challenge-Tab mit Banner, Galerie, Voting-Herz
- Gassi-Zeiten-Pool: DB-Tabelle gassi_zeiten, routes/gassi_zeiten.py (CRUD + Umkreis),
  walks.js Stamm-Gassis-Tab mit Karten, Wochentag-Selector, Mitmachen→Chat
- Rassen-Treffen-Chip: GET /api/friends/same-breed, dog-profile.js zeigt Chip
  wenn andere User gleiche Rasse haben, Klick → Forum mit Rassen-Suche vorausgefüllt
2026-05-04 21:09:35 +02:00
553e9e7854 Sprint 12+13: Tagebuch Day-One-Redesign, Notiz-Feature, Icon-Fixes, SW by-v405
Tagebuch:
- Day-One-Listenansicht: Wochentag + Tageszahl + Meta-Zeile (Zeit/Ort/Wetter)
- 4 Ansichten: Liste, Medien-Mosaik, Kalender (mit Sprungbuttons), Karte (GPS-Marker)
- Detail-Ansicht inline im Content-Bereich (kein Fullscreen-Overlay mehr)
- Hero-Bild vollständig sichtbar (object-fit:contain), Lightbox mit Safe-Area
- 2-Spalten-Layout Desktop: Text + Leaflet-Karte + POI-Liste
- EXIF-GPS-Extraktion bei Foto-Upload, historisches Wetter via Archive-API
- NoteStation-Import: Fotos in diary_media (80 Einträge migriert, 94 Medien)
- Stats-Endpoints: /diary/stats, /diary/calendar, /diary/locations

Notiz-Feature:
- Generische notes-Tabelle (parent_type + parent_id + meta_json)
- 📝-Button in 8 Bereichen, Notizblock-Seite mit KI-Analyse
- KI-Toggle in Einstellungen, notes_ki_enabled in User-Profil

Icons & Design:
- fill:currentColor Fix für welcome/onboarding/friends.js
- --c-icon Variable, --c-text-muted Dark Mode aufgehellt
- 15+ neue Phosphor-Icons aus lokaler Kopie
- CSS Network-First im SW, Cache-Control-Middleware

Infrastruktur:
- Wiki-Anreicherungs-Scheduler-Jobs entfernt (abgeschlossen)
- auth.py: notes_ki_enabled + is_social_media im User-Response
2026-04-25 20:44:46 +02:00
71a1371b44 Session 2026-04-23: Desktop Multi-Column, Forum, Fixes, Analytics
- Desktop ≥1024px: page-container 680→860px
- Walks: Liste+Karte nebeneinander, View-Toggle ausgeblendet
- Forum: Rubriken 2-zeilig via CSS Grid (ceil(n/2) Spalten, zentriert)
- Welcome: max-width 920px, Feature-Sections 2-spaltig
- Wissen: Toggle-Mechanismus entfernt, Items immer sichtbar
- Übungen Plan-Karten: vertikal statt horizontal gestapelt
- Admin Analytics: Umami v2 gibt plain numbers statt {value:X}
- CSS-Spezifität: #page-forum nötig wegen layout.css < components.css
- SW by-v312, APP_VER 300
2026-04-23 17:52:28 +02:00
eef787cc72 Fix: Benachrichtigungen öffnen direkt das Ziel-Item
- forum_reply → öffnet direkt den Forum-Thread (openThread exposed)
- walk_invite → öffnet direkt das Gassi-Treffen (openDetail exposed)
- poison_alert → öffnet direkt den Giftköder-Eintrag (openDetail exposed)
- chat_message → öffnet direkt den Chat-Thread (war schon vorhanden)
- _execNav nutzt nav.data statt nav.data?.field für konsistentes Parsing
2026-04-19 10:22:13 +02:00
e98ce0d232 Refactor: UI.loadLeaflet, leafletMarker, escape, emptyState, locationPicker zentralisiert
- Task 1: UI.loadLeaflet() in ui.js (mit Cluster-Option), lokale _loadLeaflet() in
  diary/walks/routes/places/poison/events.js entfernt
- Task 2: UI.escape() ersetzt lokale _esc()/_escape() in allen 5 Seiten-Modulen
- Task 3: UI.emptyState() ersetzt lokale _emptyState() in diary/routes/events.js
- Task 4: _fmtDate/_fmtDateShort in walks/poison bewusst behalten (anderes Format),
  Kommentare ergänzt
- Task 5: UI.locationPicker() eingebaut in places/poison/events (ersetzt manuelle
  GPS-Input-Blöcke)
- Task 6: UI.leafletMarker() factory in ui.js, Kreis-divIcon-Blöcke in walks/places/
  poison ersetzt; events.js behält Diamant-Marker (andere Form)
- SW by-v207, APP_VER 175
2026-04-18 14:34:35 +02:00
066b722c5e Feature: Walk-Einladungen und RSVP-System
Gassi-Treffen bekommen ein vollständiges Einladungs- und RSVP-System:
- Neue Tabelle walk_invitations (walk_id, user_id, status, Zeitstempel)
- Backend: /invite-candidates, /invite, /rsvp, /participants Endpoints
- Push-Notification beim Einladen
- Frontend: RSVP-Buttons (Zusagen/Vielleicht/Absagen), Teilnehmerliste
  mit Avatar-Initialen und farbkodierten RSVP-Badges, Einladen-Modal
- SW by-v205, APP_VER 173
2026-04-18 14:14:31 +02:00
e3230237a2 Feature: Gassi-Treffen — Orts-Autocomplete, Modal-UX, Teilnehmerliste, Karten-Fix
- Orts-/POI-Suche mit GPS und Vorschlägen (wie Tagebuch) + Mini-Karte im Formular
- Stornieren/Austreten als Zwei-Klick-Pattern (kein UI.modal.confirm in Modals)
- Teilnehmerliste im Detail-Modal mit User-Namen und Hunden
- Leaflet invalidateSize auf 150ms (Memory-Regel), _loadLeaflet robuster
- /api/walks/nearby Backend-Endpunkt (vor /{walk_id} Route)
- SW by-v203, APP_VER 169
2026-04-18 13:52:20 +02:00
f8d354749d Feature: Tagebuch Ort/POI, Foto/Video-Edit, Modal-UX, iOS-Fixes
Tagebuch — Ort/POI (DayOne-ähnlich):
- diary.location_name Spalte, DiaryCreate/Update mit gps_lat/lon/location_name
- GET /api/dogs/{id}/diary/nearby: Overpass + Nominatim (vor {entry_id}-Route)
- Mini-Karte im Edit-Formular: Leaflet lazy, Edit-Modus, SVG-Pin
- Meilenstein-Toggle: Button statt Checkbox, Filter in Toolbar
- Datenmigration: 97 Ort-Einträge aus text → location_name

Tagebuch — Foto/Video:
- Foto/Video im Edit: Ersetzen + Löschen, DELETE media endpoint
- Media-Picker: Kamera/Mediathek/Datei Buttons
- Video-Wiedergabe (<video controls> in Detail + Edit)

Modal-UX (alle Edit-Karten vereinheitlicht):
- Footer-Pattern: [Speichern vollbreit] / [Löschen][Abbrechen]
- diary, dog-profile, events, health, places, walks, settings, sitting
- Löschen aus Detail-Modal → Edit-Form verschoben

iOS Mobile-Fixes:
- Auto-Zoom: input/select/textarea font-size 16px !important
- Scroll-Through: html.modal-open + touch-action:none auf Overlay
- Kein position:fixed mehr auf body (kein Scroll-Sprung)

PWA & Icons:
- icon-512-any.png + icon-192-any.png (quadratisch, maskable)
- manifest.json: purpose any/maskable getrennt
- Gesundheits-Icon: syringe → first-aid

Import-Fix:
- _HTMLStripper überspringt video/audio/script → kein "Video nicht gefunden" mehr
2026-04-18 11:56:54 +02:00
b58789373c Sprint 12: UI-Vereinheitlichung + Läufigkeits-Tracker
- by-tabs/by-tab: einheitliche Tab/Pill-Navigation in allen Seiten
- by-section-label, by-toolbar: einheitliche Section-Labels und Toolbars
- Design-Tokens: fehlende --c-amber, --c-primary-soft ergänzt, Fallback-Werte entfernt
- sitting.js: sitting-layout für konsistentes flush-Layout (wie walks)
- Läufigkeits-Tracker: neuer Health-Tab für Hündinnen mit Zyklusvorhersage,
  Timeline vergangener Läufigkeiten, Erinnerungen und auto-berechnetem Nächst-Datum
- emptyState-Bug: icon-Parameter muss SVG sein, nicht Icon-Name (dog/bell/warning gefixt)
- SW-Cache: by-v103, APP_VER: 79
2026-04-16 22:31:33 +02:00
097295c628 Sprint 11: Freunde & Chat + Phosphor-Icon-Vollmigration
- Freundschaften (pending/accepted), Nutzersuche, Anfragen per Push
- Direktnachrichten mit Polling, iMessage-Stil, Deep-Links aus Push
- Alle Seiten (map, places, diary, health, dog-profile, sitting, knigge,
  forum, wiki, walks) vollständig auf Phosphor-Icons migriert
- Wikidata-Rassen-Scraper (~833 neue Rassen, lokal gespiegelte Fotos)
- TheDogAPI lokal gespiegelt (169 Rassen + Fotos)
- Quiz-Result-Cards horizontal (korrekte Bildproportionen)
- SW by-v89
2026-04-15 21:33:53 +02:00
ec17dfb029 Sprint 7: Gassi-Treffen — Meetup-Feature komplett
- Backend: walks.py mit allen Endpoints (CRUD, join/leave, Haversine-Filter)
- DB: walks, walk_participants, walk_participant_dogs Tabellen (bereits in database.py)
- Frontend: walks.js — Liste/Karte-Toggle, Heute/Demnächst-Gruppierung, Detail-Modal
  mit Teilnehmerliste, Beitreten/Verlassen, Erstellen/Bearbeiten-Formulare
- CSS: Walks-Komponenten (Card, Date-Badge, Spots-Anzeige, Map-View)
- api.js: walks-Abschnitt (list, get, create, update, cancel, join, leave)
- SW-Cache: by-v20 → by-v21
2026-04-14 06:12:52 +02:00