This commit is contained in:
101
.projektstructure.txt
Executable file → Normal file
101
.projektstructure.txt
Executable file → Normal file
@@ -1,99 +1,8 @@
|
||||
Anweisung: Projektstruktur (Basis-Template) wie in „papa-kind-treff“
|
||||
Projektstruktur – Verweis
|
||||
|
||||
Aktueller Projektstand
|
||||
- Die Hauptnavigation lautet aktuell `Home`, `Event Suche`, `Community`.
|
||||
- Papa-Kind-Treff nutzt im Mitgliederbereich eine Mehr-Style-Avatar-Architektur auf Basis von DiceBear.
|
||||
- Die zentrale Avatar-Verwaltung liegt in `src/App/Avatar/AvatarManager.php`.
|
||||
- Die aktuell aktiven Styles liegen in `src/App/Avatar/Lorelei.php` und `src/App/Avatar/Croodles.php`.
|
||||
- Die Avatar-Konfiguration liegt in `config/avatar.php`.
|
||||
- Der Avatar-Proxy liegt unter `public/api/avatar.php`.
|
||||
- Die visuelle Avatar-Konfiguration liegt im Dashboard-Modal unter `partials/landing/account/dashboard.php` und rendert Komponenten-Vorschauen live nach.
|
||||
- Das Avatar-Modal ist auf Browserhoehe optimiert: kompakter Kopfbereich, fixe Komponenten-Navigation, scrollende Variantenliste und kleine Farbfelder mit `Standard`-Reset pro Komponente.
|
||||
- Der Generator speichert `avatar_style`, `avatar_seed` und `avatar_config_json` generisch im Profil.
|
||||
- Der Generator zeigt pro Style die von DiceBear unterstützten Farbfelder direkt in den passenden Komponentenabschnitten und speichert diese im gleichen Config-JSON.
|
||||
- Gespeicherte Benutzer-Avatare werden lokal unter `public/assets/avatars/users/ptk-<userId>.svg` abgelegt und bei Änderungen überschrieben.
|
||||
- Der Generator besitzt einen Button `Random Profilbild`, der Seed und Varianten des aktiven Styles zufällig neu setzt.
|
||||
- Beim Oeffnen des Modals werden nur die Bilder des aktiven Styles und Tabs geladen; weitere Tabs laden ihre Varianten erst beim Wechsel nach.
|
||||
- Kinder koennen im Mitgliederbereich zusaetzlich nachtraeglich bearbeitet und geloescht werden.
|
||||
- Wenn bei einem Kind ein Geburtsdatum hinterlegt ist, wird das Alter automatisch daraus berechnet und spaeter bei Bedarf jaehrlich aktualisiert; ohne Geburtsdatum bleibt das manuell gepflegte Alter massgeblich.
|
||||
- Profilbezogene sensible Angaben wie Vorname, Nachname, Telefonnummer, Beruf, Sprachen und Kurzvorstellung werden app-seitig verschluesselt gespeichert; vorhandene Klartextwerte werden bei der Nutzung schrittweise nachmigriert.
|
||||
- Auch die Konto-E-Mail wird jetzt app-seitig verschluesselt gespeichert; fuer Login, Verifizierung, Passwort-Reset und Dublettenpruefung dient nur ein separater HMAC-Lookup-Hash.
|
||||
- Der Hinweis auf die verschluesselte Speicherung personenbezogener Profilangaben ist auf der Datenschutz-Seite jetzt zusaetzlich deutlich hervorgehoben.
|
||||
- Das Profil besitzt jetzt zusaetzlich eine vollstaendige Adresse mit verschluesselter Strasse/Hausnummer sowie eine optionale Adress-Lokalisierung ueber die vorhandenen externen Karten-/Geocoding-Dienste.
|
||||
- Die Profiladresse unterstuetzt jetzt ausserdem eine Auswahl moeglicher Adress-Treffer, die Uebernahme aus dem Browser-Standort und einen kurzen Hinweisdialog zur lokalen Relevanz fuer Events, Termine und Treffen.
|
||||
- Der Profil-Editor im Mitgliederbereich ist jetzt kompakter aufgebaut, in ausklappbare Bereiche gegliedert und enthaelt die bearbeitbare Konto-E-Mail direkt im Formular.
|
||||
- Fuer Umkreis- und Distanzfunktionen bleiben nur `lat`/`lng` technisch im Klartext; die eigentliche Strasse/Hausnummer ist verschluesselt.
|
||||
- Alte statische Avatar-Presets und frühere Layer-Assets sind entfernt.
|
||||
- Änderungen an Funktionen mit Cookies, LocalStorage, SessionStorage, Geolocation, Tracking oder Drittanbietern müssen immer auch in Datenschutz-/Cookie-Hinweisen und im Consent-Flow berücksichtigt werden.
|
||||
Die kanonische interne Strukturdokumentation wurde verschoben nach:
|
||||
|
||||
Ziel
|
||||
- Erstelle ein neues Projekt bzw. aktualisiere das aktuelle mit exakt der gleichen Grundstruktur wie in „papa-kind-treff“.
|
||||
- Fokus auf Hauptordner und deren Zweck; keine projektspezifischen Sonderordner (z. B. Community) anlegen.
|
||||
- Inhalte können minimal sein, aber alle Pfade müssen existieren.
|
||||
- In Ordnern, die noch keine Dateien beinhalten, muss eine leere Datei mit dem Namen .gitkeep erstellt werden.
|
||||
- Bestehende Dateien nicht überschreiben; wenn nötig, Inhalte behutsam an die neue Logik anpassen.
|
||||
- `Internal/de/PROJECT_STRUCTURE.md`
|
||||
- `Internal/en/PROJECT_STRUCTURE.md`
|
||||
|
||||
Verzeichnisstruktur (Pflichtordner)
|
||||
- api/
|
||||
- config/
|
||||
- debug/
|
||||
- partials/
|
||||
- public/
|
||||
- src/
|
||||
- tools/
|
||||
- README.md
|
||||
- schema.sql
|
||||
- .gitlab-ci.yml
|
||||
|
||||
Details je Ordner
|
||||
|
||||
config/
|
||||
- Enthält alle Konfigurationen.
|
||||
- Muss Subordner für Umgebungen haben: z. B. prod/ und staging/.
|
||||
- In den Umgebungsordnern liegen Basis-Konfigurationen (z. B. db.php, settings.php, emailtemplates.php, domaindata.php).
|
||||
- Hinweis: Die Umgebungs-Subordner werden beim Deployment in den root-Config kopiert; daher ist hier keine weitere Unterscheidung nötig.
|
||||
- Falls Dateien fehlen, lege sie mit minimalem Basisinhalt an (z. B. PHP-Array/Kommentar), ohne vorhandene Inhalte zu überschreiben.
|
||||
|
||||
api/
|
||||
- Schnittstellen/Endpunkte.
|
||||
- Kann zunächst leer bleiben; dann .gitkeep anlegen.
|
||||
|
||||
debug/
|
||||
- Debug-Hilfen, Logs oder Debug-Skripte.
|
||||
- Wenn leer: .gitkeep.
|
||||
|
||||
partials/
|
||||
- Nur die Unterscheidung in:
|
||||
- landing/
|
||||
- structure/
|
||||
- landing/: Platz für seitenbezogene Teilausschnitte.
|
||||
- structure/: Layout-Grundbausteine (z. B. layout_start.php, layout_end.php, nav.php, matomo.php) als Beispieldaten.
|
||||
|
||||
public/
|
||||
- Webroot.
|
||||
- Muss assets/ enthalten mit Unterordnern: bilder/, fonts/, js/, css/ (Dateien optional).
|
||||
- Muss index.php enthalten mit Basis-Logic (z. B. Entry-Point/Router/Bootstrap).
|
||||
|
||||
src/
|
||||
- Backend/Business-Logik und Kernklassen.
|
||||
- Enthält App- oder Domain-Code (z. B. Auth, Database, Mailer, Config, Request, Assets usw.).
|
||||
- Lege eine kurze Beschreibung an, wofür src gedacht ist (Kommentar oder README im Ordner).
|
||||
|
||||
tools/
|
||||
- Entwicklungs-/Wartungs-Tools, Skripte oder Utilities.
|
||||
- Inhaltlich analog zu src gedacht, aber für interne Werkzeuge.
|
||||
|
||||
Datei-Inhalte (minimal, aber vorhanden)
|
||||
- .gitkeep: leer.
|
||||
- README.md, schema.sql, .gitlab-ci.yml: leer oder mit kurzem Platzhaltertext.
|
||||
- PHP-Dateien: leer oder mit kurzem Kommentar, z. B. "<?php // TODO".
|
||||
- .htaccess (falls genutzt): leer oder minimaler Platzhalter.
|
||||
|
||||
Zusätzliche Regeln
|
||||
- Keine projektspezifischen Sonderordner anlegen.
|
||||
- Pfade und Dateinamen exakt, Groß-/Kleinschreibung beachten.
|
||||
- Struktur ist wichtiger als Inhalt.
|
||||
|
||||
Ausgabeformat
|
||||
- Erzeuge die Ordner und Dateien exakt wie oben.
|
||||
- Liefere optional eine kurze Zusammenfassung der angelegten/angepassten Struktur.
|
||||
Bitte diese Dateien als Referenz verwenden und bei Änderungen dort pflegen.
|
||||
|
||||
22
Internal/README.md
Normal file
22
Internal/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Internal Documentation
|
||||
|
||||
Updated: 2026-08-03
|
||||
|
||||
Canonical internal project documentation lives in this directory.
|
||||
|
||||
## Directory Structure
|
||||
- `de/README.md`
|
||||
- `de/PROJECT_CONTEXT.md`
|
||||
- `de/PROJECT_STRUCTURE.md`
|
||||
- `en/README.md`
|
||||
- `en/PROJECT_CONTEXT.md`
|
||||
- `en/PROJECT_STRUCTURE.md`
|
||||
|
||||
## Maintenance Rule
|
||||
- German and English documentation must be maintained as fully parallel references.
|
||||
- Changes to project behavior, structure, wording, privacy, security, or product decisions must be reflected in both language sets.
|
||||
- The root `README.md` remains in the project root as the mandatory start document for new chats.
|
||||
|
||||
## Scope Rule
|
||||
- Public-facing website copy does not belong here.
|
||||
- `Internal/` is only for internal project, product, architecture, and maintenance documentation.
|
||||
34
Internal/de/PROJECT_CONTEXT.md
Normal file
34
Internal/de/PROJECT_CONTEXT.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Papa-Kind-Treff – Projektkontext
|
||||
|
||||
Stand: 2026-08-03
|
||||
|
||||
## Kurzbeschreibung
|
||||
Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter. Kernbereiche sind lokale Events, Termine und Treffen, ein Community-Forum, Mitgliederprofile mit optionalen Kinderinfos und ein Moderations-/Adminbereich.
|
||||
|
||||
## Wichtige Produktentscheidungen
|
||||
- Die Hauptnavigation ist bewusst knapp gehalten: `Home`, `Event Suche`, `Community`.
|
||||
- `Events` ist der Primärbegriff im Produkt.
|
||||
- `Termine` und `Treffen` werden ergänzend in SEO- und Erklärungstexten genutzt.
|
||||
- Die Community ist hierarchisch aufgebaut: Kategorien -> Boards -> Threads -> Posts.
|
||||
- Moderation ist vom normalen Community-Frontend getrennt.
|
||||
- Standortfunktionen sind relevant für lokale Events, Termine und Treffen.
|
||||
|
||||
## Konto / Mitgliederbereich
|
||||
- Profil-Menü aktuell: `Profil`, `Kinder`, `Events`, `Community`, `Einstellungen`, `Abmelden`
|
||||
- Kinder können angelegt, bearbeitet und gelöscht werden.
|
||||
- Wenn ein Geburtsdatum gesetzt ist, wird das Alter automatisch berechnet und später bei Bedarf aktualisiert.
|
||||
- Die Konto-E-Mail wird app-seitig verschlüsselt gespeichert und über einen separaten HMAC-Lookup-Hash adressiert.
|
||||
- Profiladresse kann per Suche oder Browser-Standort übernommen werden.
|
||||
|
||||
## Technischer Rahmen
|
||||
- eigener Front-Controller in `public/index.php`
|
||||
- Templates unter `partials/`
|
||||
- Geschäftslogik unter `src/App/`
|
||||
- Globales Frontend vor allem über `public/assets/js/app.js` und `public/assets/css/app.css`
|
||||
|
||||
## Pflegehinweis
|
||||
Bei Änderungen immer auch die parallelen Dateien in `Internal/en/` prüfen und inhaltlich gleichziehen.
|
||||
|
||||
## Dokumentationsprinzip
|
||||
- `Internal/de/` und `Internal/en/` werden bewusst parallel gepflegt.
|
||||
- Die Root-`README.md` dient als Start-Doku für neue Chats und muss bei grundlegenden Änderungen ebenfalls mitgeprüft werden.
|
||||
29
Internal/de/PROJECT_STRUCTURE.md
Normal file
29
Internal/de/PROJECT_STRUCTURE.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Papa-Kind-Treff – Projektstruktur
|
||||
|
||||
Stand: 2026-08-03
|
||||
|
||||
## Projektordner
|
||||
- `config/`: Konfigurationen, inklusive `prod/` und `staging/`
|
||||
- `partials/`: Templates, aufgeteilt in `landing/` und `structure/`
|
||||
- `public/`: Webroot mit Assets und Seiten-Entry-Points
|
||||
- `src/`: Backend-/Business-Logik und Kernklassen
|
||||
- `debug/`: Debug-Hilfen und Logs
|
||||
- `api/`: technische Endpunkte
|
||||
- `Internal/`: interne Projektdokumentation in Deutsch und Englisch
|
||||
|
||||
## Aktuelle Strukturhinweise
|
||||
- Avatar-Verwaltung: `src/App/Avatar/AvatarManager.php`
|
||||
- aktive Styles: `src/App/Avatar/Lorelei.php`, `src/App/Avatar/Croodles.php`
|
||||
- Profil-/Kinder-/Event-Logik im Mitgliederbereich: `partials/landing/account/dashboard.php`
|
||||
- Consent- und rechtliche Texte: `public/page/datenschutz.php`
|
||||
|
||||
## Dokumentationsregel
|
||||
Kanonische interne Dokumentation:
|
||||
- `Internal/de/README.md`
|
||||
- `Internal/de/PROJECT_CONTEXT.md`
|
||||
- `Internal/de/PROJECT_STRUCTURE.md`
|
||||
- entsprechende englische Spiegel unter `Internal/en/`
|
||||
|
||||
Zusätzlich:
|
||||
- `README.md` im Hauptordner bleibt als Start-Doku für neue Chats bestehen.
|
||||
- Änderungen an der internen Struktur müssen immer in Deutsch und Englisch parallel dokumentiert werden.
|
||||
53
Internal/de/README.md
Normal file
53
Internal/de/README.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Papa-Kind-Treff
|
||||
|
||||
Stand: 2026-08-03
|
||||
|
||||
Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter mit Fokus auf lokale Events, Termine und Treffen, Community-Austausch und einen geschützten Mitgliederbereich.
|
||||
|
||||
## Produktumfang
|
||||
- lokale Events, Termine und Treffen finden
|
||||
- Community/Forum mit Kategorien, Boards, Threads und Antworten
|
||||
- Mitgliederbereich für Profil, optionale Kinderinfos und eigene Events
|
||||
- Community-Moderation mit Rollenmodell
|
||||
|
||||
## Aktueller Stand
|
||||
- Startseite mit Hero, Event-Suche, Event-Karussell, Community-Vorschau und Mitgliederbereichs-Block
|
||||
- Community mit Board-Navigation und separater Thread-Ansicht
|
||||
- Community-Admin-Bereich für Bewerbungen, Meldungen, Rollen und Migration
|
||||
- standortbasierte Sortierung für die neuesten Events
|
||||
- Mitgliederbereich mit linker Bereichsnavigation
|
||||
- Profil-Menü mit `Profil`, `Kinder`, `Events`, `Community`, `Einstellungen`
|
||||
- Konto-E-Mails sowie sensible Profilfelder werden app-seitig verschlüsselt gespeichert
|
||||
- Kinder können angelegt, bearbeitet und gelöscht werden
|
||||
- Profiladresse mit verschlüsselter Straße/Hausnummer, Adresssuche, Browser-Übernahme und Validierung
|
||||
|
||||
## Wording-Regel
|
||||
- Primärbegriff im Produkt: `Events`
|
||||
- Ergänzende SEO-/Erklärbegriffe: `Termine`, `Treffen`
|
||||
- Navigation, Buttons und Kern-UI verwenden konsequent `Events`
|
||||
|
||||
## Technik
|
||||
- Einstieg: `public/index.php`
|
||||
- Templates: `partials/`
|
||||
- App-Logik: `src/App/`
|
||||
- Assets: `public/assets/`
|
||||
- Datenbankschema: `schema.sql`
|
||||
|
||||
## Datenschutz und Sicherheit
|
||||
- Passwort-Hashes über Argon2id
|
||||
- Konto-E-Mails verschlüsselt plus separater HMAC-Lookup-Hash
|
||||
- Profilfelder wie Vorname, Nachname, Straße/Hausnummer, Telefonnummer, Beruf, Sprachen und Kurzvorstellung verschlüsselt
|
||||
- Standortkoordinaten (`lat`, `lng`) bleiben für Distanz- und Umkreissuchen technisch im Klartext
|
||||
- nicht notwendige Analyse- und Drittanbieterfunktionen erst nach Einwilligung aktiv
|
||||
|
||||
## Dokumentationspflicht bei Änderungen
|
||||
Bei jeder Änderung im Projekt mitprüfen und bei Bedarf aktualisieren:
|
||||
- `Internal/de/README.md`
|
||||
- `Internal/de/PROJECT_CONTEXT.md`
|
||||
- `Internal/de/PROJECT_STRUCTURE.md`
|
||||
- die parallelen englischen Dateien unter `Internal/en/`
|
||||
|
||||
## Parallelpflege DE / EN
|
||||
- Die Dokumentation in `Internal/de/` und `Internal/en/` ist inhaltlich vollständig parallel zu halten.
|
||||
- Deutsch und Englisch sind beide verbindliche interne Referenzen.
|
||||
- Die Root-`README.md` im Hauptordner bleibt der feste Einstieg für neue Chats und verweist auf diese Struktur.
|
||||
31
Internal/en/PROJECT_CONTEXT.md
Normal file
31
Internal/en/PROJECT_CONTEXT.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Papa-Kind-Treff – Project Context
|
||||
|
||||
Updated: 2026-08-03
|
||||
|
||||
## Summary
|
||||
Papa-Kind-Treff is a PHP-based platform for fathers. Core areas are local events, appointments, and meetups, a community forum, member profiles with optional child information, and a moderation/admin area.
|
||||
|
||||
## Key Product Decisions
|
||||
- Main navigation remains intentionally compact: `Home`, `Event Search`, `Community`.
|
||||
- `Events` is the primary product term across the UI.
|
||||
- Secondary wording is used only in SEO and explanatory copy.
|
||||
- The community is hierarchical: categories -> boards -> threads -> posts.
|
||||
- Moderation is separated from the normal community frontend.
|
||||
- Location features are important for local discovery.
|
||||
|
||||
## Account / Member Area
|
||||
- Profile menu currently contains `Profile`, `Children`, `Events`, `Community`, `Settings`, `Logout`.
|
||||
- Children can be created, edited, and deleted.
|
||||
- If a birth date is set, age is calculated automatically and updated later when needed.
|
||||
- Account email is encrypted application-side and addressed through a separate HMAC lookup hash.
|
||||
- Profile address can be completed via address search or browser-based location import.
|
||||
|
||||
## Technical Frame
|
||||
- custom front controller in `public/index.php`
|
||||
- templates under `partials/`
|
||||
- business logic under `src/App/`
|
||||
- global frontend mainly via `public/assets/js/app.js` and `public/assets/css/app.css`
|
||||
|
||||
## Maintenance Note
|
||||
- Whenever one of these files changes, the matching files in `Internal/de/` and `Internal/en/` must be kept aligned.
|
||||
- The root `README.md` acts as the startup document for new chats and should be reviewed alongside major context changes.
|
||||
23
Internal/en/PROJECT_STRUCTURE.md
Normal file
23
Internal/en/PROJECT_STRUCTURE.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Papa-Kind-Treff – Project Structure
|
||||
|
||||
Updated: 2026-08-03
|
||||
|
||||
## Main Directories
|
||||
- `config/`: configuration, including `prod/` and `staging/`
|
||||
- `partials/`: templates split into `landing/` and `structure/`
|
||||
- `public/`: webroot, assets, and page entry points
|
||||
- `src/`: backend and business logic
|
||||
- `debug/`: debugging helpers and logs
|
||||
- `api/`: technical endpoints
|
||||
- `Internal/`: internal documentation in German and English
|
||||
|
||||
## Current Structure Notes
|
||||
- avatar management: `src/App/Avatar/AvatarManager.php`
|
||||
- active avatar styles: `src/App/Avatar/Lorelei.php`, `src/App/Avatar/Croodles.php`
|
||||
- profile/children/event logic inside member area: `partials/landing/account/dashboard.php`
|
||||
- consent and legal texts: `public/page/datenschutz.php`
|
||||
|
||||
## Documentation Rule
|
||||
- canonical internal documentation lives in `Internal/de/` and `Internal/en/`
|
||||
- `README.md` in the project root remains as the startup document for new chats
|
||||
- structural changes must always be documented in German and English in parallel
|
||||
52
Internal/en/README.md
Normal file
52
Internal/en/README.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Papa-Kind-Treff
|
||||
|
||||
Updated: 2026-08-03
|
||||
|
||||
Papa-Kind-Treff is a PHP-based platform for fathers focused on local events, appointments, and meetups, community exchange, and a protected member area.
|
||||
|
||||
## Scope
|
||||
- discover local events, appointments, and meetups
|
||||
- community/forum with categories, boards, threads, and replies
|
||||
- member area for profile, optional child information, and own events
|
||||
- community moderation with a role model
|
||||
|
||||
## Current State
|
||||
- landing page with hero, event search, event carousel, community preview, and member-area block
|
||||
- community with board navigation and separate thread view
|
||||
- community admin area for applications, reports, roles, and migrations
|
||||
- location-based ordering for the newest events
|
||||
- member area with left-side section navigation
|
||||
- profile menu with `Profile`, `Children`, `Events`, `Community`, `Settings`
|
||||
- account emails and sensitive profile fields are stored encrypted application-side
|
||||
- children can be created, edited, and deleted
|
||||
- profile address supports encrypted street/house number, address search, browser import, and validation
|
||||
|
||||
## Core Wording Rule
|
||||
- Primary product term: `Events`
|
||||
- Secondary SEO/explanatory terms: `Appointments`, `Meetups`
|
||||
|
||||
## Tech
|
||||
- entry point: `public/index.php`
|
||||
- templates: `partials/`
|
||||
- application logic: `src/App/`
|
||||
- assets: `public/assets/`
|
||||
- database schema: `schema.sql`
|
||||
|
||||
## Privacy and Security
|
||||
- password hashes via Argon2id
|
||||
- account emails are encrypted and additionally addressed through a separate HMAC lookup hash
|
||||
- profile fields such as first name, last name, street/house number, phone number, profession, languages, and short bio are encrypted
|
||||
- location coordinates (`lat`, `lng`) remain plaintext where technically required for distance and radius search
|
||||
- non-essential analytics and third-party services are only active after consent
|
||||
|
||||
## Documentation Rule
|
||||
Whenever project behavior or structure changes, review and update:
|
||||
- `Internal/de/README.md`
|
||||
- `Internal/de/PROJECT_CONTEXT.md`
|
||||
- `Internal/de/PROJECT_STRUCTURE.md`
|
||||
- matching English files under `Internal/en/`
|
||||
|
||||
## Parallel DE / EN Maintenance
|
||||
- Documentation in `Internal/de/` and `Internal/en/` must remain fully parallel in content.
|
||||
- German and English are both binding internal references.
|
||||
- The root `README.md` remains the fixed start document for new chats and must be reviewed when core project assumptions change.
|
||||
@@ -1,78 +1,8 @@
|
||||
# Papa-Kind-Treff – Chat-Kontext
|
||||
# Projektkontext – Verweis
|
||||
|
||||
Stand: 2026-07-31
|
||||
Die kanonische interne Kontextdokumentation wurde verschoben nach:
|
||||
|
||||
## Kurzbeschreibung
|
||||
Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter. Kernbereiche sind lokale Events, Termine und Treffen, ein Community-Forum, Mitgliederprofile mit optionalen Kinderinfos und ein Moderations-/Adminbereich.
|
||||
- `Internal/de/PROJECT_CONTEXT.md`
|
||||
- `Internal/en/PROJECT_CONTEXT.md`
|
||||
|
||||
## Technischer Rahmen
|
||||
- Kein großes Framework, sondern eigener Front-Controller in `public/index.php`
|
||||
- Templates unter `partials/`
|
||||
- Geschäftslogik unter `src/App/`
|
||||
- MySQL/MariaDB-Schema in `schema.sql`
|
||||
- Globales Frontend vor allem über `public/assets/js/app.js` und `public/assets/css/app.css`
|
||||
- Avatar-Manager liegt zentral unter `src/App/Avatar/AvatarManager.php`
|
||||
- Die aktiven Styles `Lorelei` und `Croodles` liegen getrennt unter `src/App/Avatar/Lorelei.php` und `src/App/Avatar/Croodles.php`
|
||||
- Die Avatar-Konfiguration liegt in `config/avatar.php`
|
||||
- In `config/avatar.php` sind pro Style auch Beispielpaletten, Komponentenlisten und Beispielprofile dokumentiert
|
||||
- Der Avatar-Endpunkt ist als direkte Datei unter `public/api/avatar.php` angebunden und laeuft bewusst ohne vollen App-Bootstrap.
|
||||
|
||||
## Wichtige Produktentscheidungen
|
||||
- Die Ansprache im Frontend soll immer den aktuellen Nutzer direkt ansprechen.
|
||||
- Die Hauptnavigation ist bewusst knapp gehalten: `Home`, `Event Suche`, `Community`.
|
||||
- `Events` sind aktuell kein eigener Hauptpunkt mehr; sie werden über Startseite und Suche erschlossen.
|
||||
- Die Community ist hierarchisch aufgebaut: Kategorien -> Boards -> Threads -> Posts.
|
||||
- Moderation ist getrennt vom normalen Community-Frontend in einem eigenen Adminbereich.
|
||||
- Standortfunktionen sind relevant für lokale Events, Termine und Treffen und werden künftig weiter ausgebaut.
|
||||
- Profilbilder werden aktuell über die Mehr-Style-Architektur serverseitig erzeugt; aktiv sind derzeit `lorelei` und `croodles`.
|
||||
- Beim Style `croodles` startet die Basisfarbe standardmaessig weiss; der Hintergrund ist standardmaessig nicht vorbelegt.
|
||||
- Stil, Seed und Varianten werden generisch im Profil gespeichert; das fertige SVG wird lokal pro Benutzer unter `ptk-<userId>.svg` abgelegt.
|
||||
- Der Avatar-Editor bietet visuelle Komponenten-Vorschauen statt reiner Text-Dropdowns, laedt nur den aktiven Style/Tab nach, zeigt die Farbfelder direkt im passenden Komponentenabschnitt an und haelt Kopfbereich sowie Komponentenleiste im Modal fixiert.
|
||||
|
||||
## Navigation / Konto
|
||||
- Eingeloggte Nutzer sehen rechts ein Profil-Menü statt einzelner `Dashboard`-/`Logout`-Buttons.
|
||||
- Das Profil-Menü enthält aktuell `Profil`, `Kinder`, `Events`, `Community`, `Einstellungen`, `Abmelden`.
|
||||
- Der Mitgliederbereich selbst ist als Layout mit linker Bereichsnavigation aufgebaut.
|
||||
- Kinder koennen im Mitgliederbereich angelegt, nachtraeglich bearbeitet und wieder geloescht werden.
|
||||
- Wenn ein Geburtsdatum gesetzt ist, wird das Alter im Mitgliederbereich automatisch berechnet und spaeter bei Bedarf anhand des Datums aktualisiert; ohne Geburtsdatum gilt der manuelle Alterswert.
|
||||
- Sensible Profildaten wie Vorname, Nachname, Telefonnummer, Beruf, Sprachen und Kurzvorstellung werden app-seitig verschluesselt gespeichert; bestehende Klartextwerte werden bei Nutzung schrittweise in den verschluesselten Zustand ueberfuehrt.
|
||||
- Die Konto-E-Mail wird ebenfalls app-seitig verschluesselt gespeichert; fuer Login, Verifizierung, Passwort-Reset und Dublettenpruefung existiert nur ein separater HMAC-Lookup-Hash.
|
||||
- Der Hinweis auf die verschluesselte Speicherung personenbezogener Profilangaben ist auf der Datenschutz-Seite jetzt zusaetzlich deutlich hervorgehoben.
|
||||
- Im Profil koennen jetzt auch Strasse/Hausnummer, PLZ, Ort und Region gepflegt werden; fuer die Adress-Lokalisierung werden die bereits vorhandenen externen Karten-/Geocoding-Dienste wiederverwendet.
|
||||
- Die Profiladresse bietet jetzt zusaetzlich eine Trefferauswahl fuer die Suche, eine Uebernahme aus dem Browser-Standort und einen kurzen Hinweisdialog zur Relevanz fuer lokale Event-, Termin- und Treff-Hinweise.
|
||||
- Der Profil-Editor ist jetzt kompakter gegliedert, nutzt ausklappbare Bereiche fuer Basisdaten, Adresse, Sprache/Beruf und Kurzvorstellung und enthaelt die bearbeitbare Konto-E-Mail direkt im Formular.
|
||||
- Im Profil kann der Nutzer aktuell Komponenten wie Augen, Augenbrauen, Mund, Brille, Haare, Bart und Ohrringe direkt per Vorschaubild auswählen.
|
||||
- Der Button `Random Profilbild` setzt Seed und Varianten des aktiven Styles zufaellig neu und aktualisiert die Vorschau sofort.
|
||||
- Beim Oeffnen des Avatar-Generators wird nur der aktive Style-/Komponenten-Tab geladen; weitere Varianten werden erst beim Wechsel nachgeladen.
|
||||
- Debug ist kein Menüpunkt und erscheint nur als Floating-Käfer für `site_admin` bei aktivem Debug-Modus.
|
||||
|
||||
## Community und Rechte
|
||||
- dekorative Ränge über Punkte
|
||||
- Moderationsrollen:
|
||||
- `forum_admin`
|
||||
- `site_admin`
|
||||
- `owner`
|
||||
- Bewerbungen für Moderation sind vorgesehen bzw. umgesetzt.
|
||||
|
||||
## Recht / Consent
|
||||
- Nicht notwendige Funktionen laufen nicht automatisch los.
|
||||
- Es gibt einen Consent-Manager mit Kategorien:
|
||||
- `analytics`
|
||||
- `external_services`
|
||||
- Matomo wird nur nach Analyse-Einwilligung geladen.
|
||||
- Externe Karten-/Standortdienste und lokale Standortspeicherung hängen an `external_services`.
|
||||
- Zusätzlich gibt es eine Standortpräferenz im Bereich `Einstellungen`:
|
||||
- `disabled`
|
||||
- `prompt`
|
||||
- `enabled`
|
||||
- Im Einstellungsbereich werden außerdem Browser-Grenzen erklärt: Die Browser-Freigabe selbst kann nicht von der Website gesetzt oder aufgehoben werden.
|
||||
- Es gibt eine eigene Seite `/datenschutz` für Datenschutz- und Cookie-Hinweise sowie einen Footer-Link auf die Consent-Einstellungen.
|
||||
- Fuer Distanz- und Umkreissuchen bleiben nur die erforderlichen Standortkoordinaten im Klartext gespeichert; die eigentliche Strasse/Hausnummer ist verschluesselt.
|
||||
|
||||
## Doku-Regel
|
||||
Bei jeder künftigen Änderung müssen mindestens diese Dateien mitgeprüft werden:
|
||||
- `README.md`
|
||||
- `.projektstructure.txt`
|
||||
- `PROJECT_CONTEXT.md`
|
||||
|
||||
Wenn Cookies, LocalStorage, SessionStorage, Tracking, Geolocation oder Drittanbieter neu hinzukommen oder geändert werden, müssen zusätzlich Consent und rechtliche Hinweise angepasst werden.
|
||||
Bitte diese Dateien als Referenz verwenden und bei Änderungen dort pflegen.
|
||||
|
||||
121
README.md
121
README.md
@@ -1,96 +1,45 @@
|
||||
# Papa-Kind-Treff
|
||||
# Papa-Kind-Treff – Start-Doku
|
||||
|
||||
Stand: 2026-07-31
|
||||
Stand: 2026-08-03
|
||||
|
||||
Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter mit Fokus auf lokale Events, Termine und Treffen, Community-Austausch und einen geschützten Mitgliederbereich.
|
||||
Diese Datei ist die zentrale Start-Doku für neue Chats und den schnellen Projekteinstieg.
|
||||
|
||||
## Produktumfang
|
||||
- lokale Events, Termine und Treffen finden
|
||||
- Community/Forum mit Kategorien, Boards, Threads und Antworten
|
||||
- Mitgliederbereich für Profil, optionale Kinderinfos und eigene Events
|
||||
- Community-Moderation mit Rollenmodell
|
||||
## Für neue Chats
|
||||
Bitte immer zuerst diese Datei lesen und danach die kanonische interne Dokumentation unter `Internal/` vollständig prüfen.
|
||||
|
||||
## Aktueller Stand
|
||||
- Startseite mit Hero, Suche, Event-Karussell, Community-Vorschau und Mitgliederbereichs-Block
|
||||
- Community mit Board-Navigation und separater Thread-Ansicht
|
||||
- Community-Admin-Bereich für Bewerbungen, Meldungen, Rollen und Migration
|
||||
- Impressum, Datenschutz-&-Cookies-Seite und Über-uns
|
||||
- standortbasierte Sortierung für die neuesten Events
|
||||
- eigener Einstellungsbereich für Standortfreigabe, Browser-Hinweise und Consent-Verwaltung
|
||||
- modernes Avatar-System mit zentraler Mehr-Style-Architektur auf Basis von DiceBear
|
||||
- aktive Avatar-Styles aktuell: `lorelei` und `croodles`; weitere Styles können über `config/avatar.php` freigeschaltet werden
|
||||
- Profilbild-Generator mit visueller Komponenten-Auswahl, generischem Style-/Seed-/Config-Speichermodell, Style-Wechsel und komponentenbezogenen Farbfeldern pro Style; im Modal bleiben Kopfbereich und Komponentenleiste fixiert, waehrend nur die Variantenliste scrollt
|
||||
- beim Style `croodles` startet die Basisfarbe standardmaessig weiss; der Hintergrund ist standardmaessig leer/ohne Vorgabe
|
||||
- jedes gespeicherte Profilbild wird als lokale Benutzer-SVG unter `public/assets/avatars/users/ptk-<userId>.svg` abgelegt
|
||||
- `config/avatar.php` enthaelt jetzt pro Style auch explizite Beispielpaletten, Farbgruppen pro Komponente und Beispielprofile als Einbindungsreferenz
|
||||
- Consent-Manager für Analyse und externe Dienste
|
||||
- Navigation aktuell mit `Home`, `Event Suche`, `Community`
|
||||
- eingeloggte Nutzer sehen rechts ein Profil-Menü mit Direktlinks zu `Profil`, `Kinder`, `Events`, `Community`, `Einstellungen`
|
||||
- der Mitgliederbereich ist als Seitenlayout mit linker Bereichsnavigation aufgebaut
|
||||
- im Bereich `Kinder` koennen vorhandene Eintraege jetzt auch nachtraeglich bearbeitet und geloescht werden
|
||||
- bei Kindern mit Geburtsdatum wird das Alter automatisch berechnet und bei Aufruf des Mitgliederbereichs bei Bedarf jaehrlich nachgezogen; ohne Geburtsdatum gilt das manuell gepflegte Alter
|
||||
- sensible Profildaten werden im Mitgliederbereich jetzt konsequent app-seitig verschluesselt gespeichert; bestehende Klartextwerte werden beim Lesen schrittweise in den verschluesselten Zustand ueberfuehrt
|
||||
- auch Konto-E-Mails werden jetzt app-seitig verschluesselt gespeichert; fuer Login, Verifizierung, Passwort-Reset und Dublettenpruefung wird nur ein separater HMAC-Lookup-Hash verwendet
|
||||
- der Hinweis auf die verschluesselte Speicherung personenbezogener Profilangaben ist jetzt auch auf der Datenschutz-Seite deutlich hervorgehoben
|
||||
- das Profil unterstuetzt jetzt eine vollstaendige Adresse mit verschluesselter Strasse/Hausnummer sowie optionaler Adress-Lokalisierung ueber die bereits vorhandenen Karten-/Geocoding-Dienste
|
||||
- bei der Profiladresse gibt es jetzt eine Trefferauswahl fuer Adresssuche, eine Uebernahme aus dem Browser-Standort sowie einen mobilen Hinweisdialog, warum die Adresse fuer lokale Events, Termine und Treffen relevant ist
|
||||
- der Profil-Editor im Mitgliederbereich ist jetzt kompakter gruppiert, nutzt ausklappbare Abschnitte und enthaelt die bearbeitbare Konto-E-Mail wieder direkt im Formular
|
||||
- Debug-Floating-Button nur für `site_admin` im Debug-Modus
|
||||
Verbindliche deutsche Referenz:
|
||||
- `Internal/de/README.md`
|
||||
- `Internal/de/PROJECT_CONTEXT.md`
|
||||
- `Internal/de/PROJECT_STRUCTURE.md`
|
||||
|
||||
## Technik
|
||||
- Einstieg: `public/index.php`
|
||||
- Templates: `partials/`
|
||||
- App-Logik: `src/App/`
|
||||
- Assets: `public/assets/`
|
||||
- Datenbankschema: `schema.sql`
|
||||
Parallele englische Referenz:
|
||||
- `Internal/en/README.md`
|
||||
- `Internal/en/PROJECT_CONTEXT.md`
|
||||
- `Internal/en/PROJECT_STRUCTURE.md`
|
||||
|
||||
## Rollen
|
||||
- `forum_admin`
|
||||
- `site_admin`
|
||||
- `owner`
|
||||
## Dokumentationsregel
|
||||
- Die Dokumentation unter `Internal/de/` und `Internal/en/` ist vollständig parallel zu pflegen.
|
||||
- Änderungen an Projektstand, Struktur, Wording, Datenschutz, Sicherheit oder Produktverhalten müssen immer in Deutsch und Englisch nachgezogen werden.
|
||||
- Die Root-`README.md` bleibt bewusst im Hauptordner, damit sie in neuen Chats direkt als Einstieg genannt werden kann.
|
||||
|
||||
Die Rechteverteilung und Community-Logik sind in `src/App/CommunityAccess.php` abgebildet.
|
||||
Die zentrale Avatar-Verwaltung liegt in `src/App/Avatar/AvatarManager.php`.
|
||||
Die aktuell aktiven Styles liegen in `src/App/Avatar/Lorelei.php` und `src/App/Avatar/Croodles.php`.
|
||||
Die Style-/Storage-Konfiguration liegt in `config/avatar.php`.
|
||||
Der direkte Avatar-Endpunkt liegt in `public/api/avatar.php`.
|
||||
Die visuelle Avatar-Auswahl sitzt im Dashboard-Modal in `partials/landing/account/dashboard.php`.
|
||||
Beim Oeffnen des Generators werden nur die Varianten des aktuell aktiven Styles und Tabs geladen; weitere Varianten werden erst beim Wechsel nachgeladen.
|
||||
Farbfelder werden pro Style direkt im Generator gepflegt und zusammen mit Stil und Seed im Profil gespeichert.
|
||||
## Kurzüberblick Projekt
|
||||
Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter mit Fokus auf:
|
||||
- lokale Events, Termine und Treffen
|
||||
- Community-Austausch
|
||||
- geschützten Mitgliederbereich mit Profil, Kinderinfos und eigenen Events
|
||||
|
||||
## Consent und rechtlich relevante Integrationen
|
||||
Der aktuelle Code nutzt oder kann nutzen:
|
||||
- notwendige Session-/Client-Cookies
|
||||
- Matomo (`analytics`)
|
||||
- Browser-Geolocation (`external_services`)
|
||||
- lokale Standortspeicherung via Cookie, `localStorage`, `sessionStorage` (`external_services`)
|
||||
- Leaflet von `unpkg.com` (`external_services`)
|
||||
- OpenStreetMap Nominatim (`external_services`)
|
||||
- DiceBear fuer serverseitig erzeugte Profilbilder; das Ergebnis wird lokal als Benutzer-SVG gespeichert
|
||||
## Wichtige aktuelle Produktregeln
|
||||
- Primärbegriff im Produkt: `Events`
|
||||
- `Termine` und `Treffen` ergänzend in SEO- und Erklärungstexten
|
||||
- Hauptnavigation aktuell: `Home`, `Event Suche`, `Community`
|
||||
- Profil-Menü aktuell: `Profil`, `Kinder`, `Events`, `Community`, `Einstellungen`, `Abmelden`
|
||||
|
||||
Zur Datensicherheit:
|
||||
- Passwort-Hashes laufen ueber Argon2id.
|
||||
- Konto-E-Mails werden verschluesselt gespeichert und nur ueber einen separaten HMAC-Lookup-Hash adressiert.
|
||||
- Profilfelder wie Vorname, Nachname, Strasse/Hausnummer, Telefonnummer, Beruf, Sprachen und Kurzvorstellung werden app-seitig verschluesselt gespeichert.
|
||||
- Standortkoordinaten (`lat`, `lng`) bleiben fuer Distanz- und Umkreissuchen technisch im Klartext gespeichert.
|
||||
## Datenschutz und Sicherheit
|
||||
- sensible Profilfelder werden app-seitig verschlüsselt gespeichert
|
||||
- Konto-E-Mails werden verschlüsselt gespeichert und zusätzlich über einen separaten HMAC-Lookup-Hash adressiert
|
||||
- Standortkoordinaten bleiben technisch im Klartext, soweit sie für Distanz- und Umkreissuchen erforderlich sind
|
||||
- Änderungen an Cookies, LocalStorage, SessionStorage, Geolocation, Tracking oder Drittanbietern erfordern immer auch die Prüfung und Aktualisierung von Consent und rechtlichen Hinweisen
|
||||
|
||||
Wichtig:
|
||||
- Nicht notwendige Analyse- und Drittanbieterfunktionen dürfen erst nach Einwilligung aktiv werden.
|
||||
- Änderungen an Cookies, Tracking oder Drittanbietern müssen immer auch in Consent und rechtlichen Hinweisen nachgezogen werden.
|
||||
|
||||
## Dokumentationspflicht bei Änderungen
|
||||
Bei jeder Änderung im Projekt immer mitprüfen und bei Bedarf aktualisieren:
|
||||
- `README.md`
|
||||
- `.projektstructure.txt`
|
||||
- `PROJECT_CONTEXT.md`
|
||||
|
||||
Zusätzlich bei neuen Cookies, Tracking-Mechanismen oder Drittanbietern:
|
||||
- Consent-Manager anpassen
|
||||
- rechtliche Hinweise/Datenschutztexte ergänzen
|
||||
- technische Opt-in-/Opt-out-Logik prüfen
|
||||
|
||||
## Dateien für neue Chats
|
||||
Für spätere Chats als Einstieg besonders wichtig:
|
||||
- `README.md`
|
||||
- `.projektstructure.txt`
|
||||
- `PROJECT_CONTEXT.md`
|
||||
## Hinweis zur internen Ablage
|
||||
- Endnutzertexte, Landingpages und UI gehören nicht nach `Internal/`
|
||||
- `Internal/` ist ausschließlich für interne Projekt- und Systemdokumentation gedacht
|
||||
|
||||
@@ -203,7 +203,7 @@ $sectionLinks = [
|
||||
<section class="account-panel" id="events">
|
||||
<div class="account-panel__head">
|
||||
<h2>Deine Events</h2>
|
||||
<p class="muted">Erstelle, bearbeite und verwalte deine eigenen Events und finde passende Termine fuer gemeinsame Treffen.</p>
|
||||
<p class="muted">Erstelle, bearbeite und verwalte deine eigenen Events und finde passende Termine für gemeinsame Treffen.</p>
|
||||
</div>
|
||||
<div class="account-panel__body">
|
||||
<div class="flex gap-12" style="margin:0 0 16px 0; flex-wrap: wrap;">
|
||||
@@ -509,7 +509,7 @@ $sectionLinks = [
|
||||
<input type="hidden" id="pRegion" name="region" value="<?= htmlspecialchars((string)($profile['region'] ?? ''), ENT_QUOTES) ?>">
|
||||
<input type="hidden" id="pLat" name="lat" value="<?= htmlspecialchars((string)($profile['lat'] ?? ''), ENT_QUOTES) ?>">
|
||||
<input type="hidden" id="pLng" name="lng" value="<?= htmlspecialchars((string)($profile['lng'] ?? ''), ENT_QUOTES) ?>">
|
||||
<p class="muted small" style="margin:0;">Persoenliche Angaben werden app-seitig verschluesselt gespeichert. Nur fuer Login und Kontofunktionen wird die E-Mail intern ueber einen separaten Lookup-Hash adressiert.</p>
|
||||
<p class="muted small" style="margin:0;">Persönliche Angaben werden app-seitig verschlüsselt gespeichert. Nur für Login und Kontofunktionen wird die E-Mail intern über einen separaten Lookup-Hash adressiert.</p>
|
||||
<details class="profile-edit-section" open>
|
||||
<summary>Basisdaten</summary>
|
||||
<div class="profile-edit-section__body">
|
||||
@@ -571,11 +571,11 @@ $sectionLinks = [
|
||||
<div id="profileAddressStatus" class="muted small" style="margin:0;"></div>
|
||||
<div id="profileAddressSelectedLabel" class="muted small" style="margin:0;<?= empty($profile['street']) && empty($profile['city']) ? ' display:none;' : '' ?>">
|
||||
<?php if (!empty($profile['street']) || !empty($profile['city'])): ?>
|
||||
Gewaehlte Adresse: <?= htmlspecialchars(trim(implode(', ', array_filter([(string)($profile['street'] ?? ''), trim((string)$profile['zip'] . ' ' . (string)$profile['city']), (string)($profile['region'] ?? '')]))), ENT_QUOTES) ?>
|
||||
Gewählte Adresse: <?= htmlspecialchars(trim(implode(', ', array_filter([(string)($profile['street'] ?? ''), trim((string)$profile['zip'] . ' ' . (string)$profile['city']), (string)($profile['region'] ?? '')]))), ENT_QUOTES) ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div id="profileAddressNeedsValidation" class="muted small" style="margin:0; display:none;">
|
||||
Die Adresse wurde manuell geaendert. Vor dem Speichern bitte erneut suchen oder die Browser-Adresse uebernehmen.
|
||||
Die Adresse wurde manuell geändert. Vor dem Speichern bitte erneut suchen oder die Browser-Adresse übernehmen.
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
@@ -596,7 +596,7 @@ $sectionLinks = [
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<label class="label" for="pLangCustom">Weitere Sprachen (Kommagetrennt)</label>
|
||||
<label class="label" for="pLangCustom">Weitere Sprachen (kommagetrennt)</label>
|
||||
<input id="pLangCustom" name="languages[]" class="input" placeholder="z. B. Italienisch, Niederländisch">
|
||||
</div>
|
||||
<div class="stack gap-6">
|
||||
@@ -630,8 +630,8 @@ $sectionLinks = [
|
||||
</div>
|
||||
<div class="stack gap-12">
|
||||
<p class="muted" style="margin:0;">Deine Adresse hilft uns, dir passende Events, Termine und Treffen in deiner Umgebung gezielter anzuzeigen.</p>
|
||||
<p class="muted" style="margin:0;">Wenn keine Adresse hinterlegt ist, koennen wir lokale Bedarfe und passende Angebote deutlich schlechter einschaetzen.</p>
|
||||
<p class="muted small" style="margin:0;">Die Adresse wird nur fuer diese Plattform-Funktionen genutzt. Strasse und Hausnummer werden verschluesselt gespeichert.</p>
|
||||
<p class="muted" style="margin:0;">Wenn keine Adresse hinterlegt ist, können wir lokale Bedarfe und passende Angebote deutlich schlechter einschätzen.</p>
|
||||
<p class="muted small" style="margin:0;">Die Adresse wird nur für diese Plattform-Funktionen genutzt. Straße und Hausnummer werden verschlüsselt gespeichert.</p>
|
||||
<div class="flex gap-12">
|
||||
<button class="btn" type="button" data-modal-close>Verstanden</button>
|
||||
</div>
|
||||
@@ -646,7 +646,7 @@ $sectionLinks = [
|
||||
<button class="btn ghost" type="button" data-modal-close>✕</button>
|
||||
</div>
|
||||
<div class="stack gap-12">
|
||||
<p class="muted small" style="margin:0;">Waehle den passenden Treffer fuer dein Profil.</p>
|
||||
<p class="muted small" style="margin:0;">Wähle den passenden Treffer für dein Profil.</p>
|
||||
<div id="profileAddressResults" class="stack gap-12"></div>
|
||||
<div class="flex gap-12">
|
||||
<button class="btn ghost" type="button" data-modal-close>Abbrechen</button>
|
||||
@@ -689,7 +689,7 @@ $sectionLinks = [
|
||||
<div class="stack gap-6">
|
||||
<label class="label" for="cAge">Alter (Jahre)</label>
|
||||
<input id="cAge" name="age_years" class="input" type="number" min="0" max="18" value="<?= htmlspecialchars((string)($editChild['age_years'] ?? ''), ENT_QUOTES) ?>">
|
||||
<p class="muted small" style="margin:0;">Mit Geburtsdatum wird das Alter automatisch berechnet und jaehrlich aktualisiert. Ohne Geburtsdatum gilt der manuelle Wert.</p>
|
||||
<p class="muted small" style="margin:0;">Mit Geburtsdatum wird das Alter automatisch berechnet und jährlich aktualisiert. Ohne Geburtsdatum gilt der manuelle Wert.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stack gap-6">
|
||||
@@ -1044,7 +1044,7 @@ $sectionLinks = [
|
||||
profileAddressSelectedLabel.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
profileAddressSelectedLabel.textContent = `Gewaehlte Adresse: ${label}`;
|
||||
profileAddressSelectedLabel.textContent = `Gewählte Adresse: ${label}`;
|
||||
profileAddressSelectedLabel.style.display = '';
|
||||
};
|
||||
|
||||
@@ -1084,13 +1084,13 @@ $sectionLinks = [
|
||||
|
||||
renderSelectedAddress(normalized.label || [normalized.street, `${normalized.zip} ${normalized.city}`.trim(), normalized.region].filter(Boolean).join(', '));
|
||||
setNeedsValidation(false);
|
||||
setProfileStatus('Adresse uebernommen.');
|
||||
setProfileStatus('Adresse übernommen.');
|
||||
};
|
||||
|
||||
const openProfileResultsModal = (results) => {
|
||||
if (!profileAddressResults || !profileAddressResultsModal) return;
|
||||
profileAddressResults.innerHTML = '';
|
||||
setProfileStatus('Bitte waehle den passenden Adress-Treffer aus.');
|
||||
setProfileStatus('Bitte wähle den passenden Adress-Treffer aus.');
|
||||
|
||||
results.forEach((result) => {
|
||||
const normalized = normalizeResult(result);
|
||||
@@ -1158,7 +1158,7 @@ $sectionLinks = [
|
||||
return;
|
||||
}
|
||||
if (!navigator.geolocation) {
|
||||
alert('Dieser Browser unterstuetzt keine Geolokalisierung.');
|
||||
alert('Dieser Browser unterstützt keine Geolokalisierung.');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1168,7 +1168,7 @@ $sectionLinks = [
|
||||
const lng = position.coords.longitude;
|
||||
reverseGeocodeProfileAddress(lat, lng, (result) => {
|
||||
applyProfileAddress(result);
|
||||
setProfileStatus('Adresse aus dem Browser-Standort uebernommen.');
|
||||
setProfileStatus('Adresse aus dem Browser-Standort übernommen.');
|
||||
});
|
||||
}, () => {
|
||||
setProfileStatus('');
|
||||
|
||||
@@ -124,7 +124,7 @@ try {
|
||||
<section class="container section" id="events">
|
||||
<div class="section__intro">
|
||||
<h2>Die neuesten Events</h2>
|
||||
<p>Neue Events, Termine und Treffen fuer Vaeter und Kinder in deiner Region.</p>
|
||||
<p>Neue Events, Termine und Treffen für Väter und Kinder in deiner Region.</p>
|
||||
</div>
|
||||
<div class="slider">
|
||||
<button class="btn ghost slider__nav" type="button" data-slider-prev aria-label="Zurück">‹</button>
|
||||
@@ -167,7 +167,7 @@ try {
|
||||
<h3 class="mt-0">Kinder (optional)</h3>
|
||||
<ul class="list">
|
||||
<li>Alter, Geburtsdatum oder kurze Hinweise hinterlegen, wenn es dir bei der Planung hilft.</li>
|
||||
<li>Treffen besser einschätzen, wenn Aktivitäten zum Alter deiner Kinder passen sollen.</li>
|
||||
<li>Events und Treffen besser einschätzen, wenn Aktivitäten zum Alter deiner Kinder passen sollen.</li>
|
||||
<li>Nur für dich sichtbar.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -46,17 +46,9 @@ if ($pdo && ($q !== '' || $loc !== '' || ($lat !== null && $lng !== null))) {
|
||||
<div class="container">
|
||||
<h1>Events suchen</h1>
|
||||
<p class="muted" style="max-width:72ch; margin:10px 0 0;">
|
||||
Finde lokale Vater-Kind-Events, Termine, Papa-Treffen, Familienaktionen und gemeinsame Freizeitangebote in deiner Naehe.
|
||||
Finde lokale Vater-Kind-Events, Termine, Papa-Treffen, Familienaktionen und gemeinsame Freizeitangebote in deiner Nähe.
|
||||
Mit der Event Suche kannst du nach Ort, PLZ, Titel oder Beschreibung passende Events und Treffen schnell filtern.
|
||||
</p>
|
||||
<p class="muted" style="max-width:72ch; margin:8px 0 0;">
|
||||
Du moechtest selbst ein Event oder Treffen anlegen?
|
||||
<?php if ($isLoggedIn): ?>
|
||||
<a href="/dashboard?section=events">Zur Event-Erstellung</a>.
|
||||
<?php else: ?>
|
||||
<a href="/login">Einloggen</a> oder <a href="/register">registrieren</a>, um eigene Events und Treffen zu erstellen.
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<form method="get" class="form-grid single" style="margin: 14px 0; gap:12px; align-items:end;" id="searchForm">
|
||||
<div class="stack gap-6">
|
||||
<label class="label" for="q">Suchbegriff (Titel, Ort, Beschreibung)</label>
|
||||
@@ -123,6 +115,14 @@ if ($pdo && ($q !== '' || $loc !== '' || ($lat !== null && $lng !== null))) {
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<p class="muted" style="max-width:72ch; margin:16px 0 0;">
|
||||
Nicht das passende gefunden?
|
||||
<?php if ($isLoggedIn): ?>
|
||||
<a href="/dashboard?section=events">Erstell doch dein eigenes Event</a>.
|
||||
<?php else: ?>
|
||||
<a href="/login">Logg dich ein</a> oder <a href="/register">registriere dich</a>, um eigene Events und Treffen anzulegen.
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -17,10 +17,10 @@ $clientCookie = $config->cookiePrefix() . 'client';
|
||||
</p>
|
||||
<div class="note" style="margin:18px 0 22px;">
|
||||
<strong>Wichtiger Hinweis zum Datenschutz:</strong>
|
||||
Personenbezogene und sensible Profilangaben werden bei Papa-Kind-Treff app-seitig verschluesselt gespeichert.
|
||||
Das betrifft insbesondere auch die Konto-E-Mail sowie Profilangaben wie Vorname, Nachname, Strasse/Hausnummer,
|
||||
Telefonnummer, Beruf, Sprachen, Kurzvorstellung und einzelne Kinderdaten. Fuer Login, Verifizierung und
|
||||
Passwort-Reset wird die E-Mail technisch nur ueber einen separaten HMAC-Lookup-Hash adressiert.
|
||||
Personenbezogene und sensible Profilangaben werden bei Papa-Kind-Treff app-seitig verschlüsselt gespeichert.
|
||||
Das betrifft insbesondere auch die Konto-E-Mail sowie Profilangaben wie Vorname, Nachname, Straße/Hausnummer,
|
||||
Telefonnummer, Beruf, Sprachen, Kurzvorstellung und einzelne Kinderdaten. Für Login, Verifizierung und
|
||||
Passwort-Reset wird die E-Mail technisch nur über einen separaten HMAC-Lookup-Hash adressiert.
|
||||
</div>
|
||||
|
||||
<section>
|
||||
@@ -59,8 +59,8 @@ $clientCookie = $config->cookiePrefix() . 'client';
|
||||
eigene Events, Event-Teilnahmen und Community-Inhalte gehören.
|
||||
</p>
|
||||
<p>
|
||||
Soweit es sich um sensible oder besonders persoenliche Profildaten handelt, werden diese innerhalb der
|
||||
Anwendung verschluesselt gespeichert und verarbeitet.
|
||||
Soweit es sich um sensible oder besonders persönliche Profildaten handelt, werden diese innerhalb der
|
||||
Anwendung verschlüsselt gespeichert und verarbeitet.
|
||||
</p>
|
||||
<p>
|
||||
Rechtsgrundlage ist Art. 6 Abs. 1 lit. b DSGVO, soweit die Verarbeitung für die Durchführung des
|
||||
@@ -90,8 +90,8 @@ $clientCookie = $config->cookiePrefix() . 'client';
|
||||
Das dient dem Schutz besonders sensibler Angaben innerhalb der Plattform.
|
||||
</p>
|
||||
<p>
|
||||
Die verschluesselte Speicherung ist damit ein grundsaetzlicher Bestandteil des Mitgliederbereichs und nicht nur
|
||||
eine optionale Zusatzmassnahme.
|
||||
Die verschlüsselte Speicherung ist damit ein grundsätzlicher Bestandteil des Mitgliederbereichs und nicht nur
|
||||
eine optionale Zusatzmaßnahme.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ final class AccountPages
|
||||
if ($resolvedAddress === null) {
|
||||
$searchResults = self::geocodeAddressCandidates($street, $zip, $city, $region, 5);
|
||||
if (!$searchResults) {
|
||||
throw new \RuntimeException('Die Profiladresse konnte nicht validiert werden. Bitte waehle eine Adresse aus der Suche oder ueber den Browser-Standort.');
|
||||
throw new \RuntimeException('Die Profiladresse konnte nicht validiert werden. Bitte wähle eine Adresse aus der Suche oder über den Browser-Standort.');
|
||||
}
|
||||
$resolvedAddress = $searchResults[0];
|
||||
}
|
||||
@@ -637,7 +637,7 @@ final class AccountPages
|
||||
return $crypto;
|
||||
}
|
||||
|
||||
throw new \RuntimeException($context . '-Daten koennen derzeit nicht sicher verarbeitet werden. Bitte spaeter erneut versuchen.');
|
||||
throw new \RuntimeException($context . '-Daten können derzeit nicht sicher verarbeitet werden. Bitte später erneut versuchen.');
|
||||
}
|
||||
|
||||
private static function encryptOptionalProfileField(Crypto $crypto, string $value): string
|
||||
|
||||
@@ -287,7 +287,7 @@ final class Lorelei
|
||||
|
||||
for ($index = 1; $index <= 9; $index++) {
|
||||
$key = sprintf('sad%02d', $index);
|
||||
$options[$key] = 'Zurueckhaltend ' . $index;
|
||||
$options[$key] = 'Zurückhaltend ' . $index;
|
||||
}
|
||||
|
||||
return $options;
|
||||
|
||||
@@ -226,7 +226,7 @@ final class UserEmailStore
|
||||
|
||||
$dataKey = trim((string)(getenv('DATA_KEY') ?: ''));
|
||||
if ($dataKey === '') {
|
||||
throw new \RuntimeException('EMAIL_LOOKUP_KEY oder DATA_KEY wird fuer sichere E-Mail-Speicherung benoetigt.');
|
||||
throw new \RuntimeException('EMAIL_LOOKUP_KEY oder DATA_KEY wird für sichere E-Mail-Speicherung benötigt.');
|
||||
}
|
||||
|
||||
if (str_starts_with($dataKey, 'base64:')) {
|
||||
|
||||
Reference in New Issue
Block a user