XYX
All checks were successful
Deploy / deploy (push) Successful in 58s

This commit is contained in:
2026-07-31 21:58:32 +02:00
parent c335fd6f5c
commit 74c52a0705
5 changed files with 60 additions and 24 deletions

View File

@@ -21,6 +21,7 @@ Aktueller Projektstand
- Das Profil besitzt jetzt zusaetzlich eine vollstaendige Adresse mit verschluesselter Strasse/Hausnummer sowie eine optionale Adress-Lokalisierung ueber die vorhandenen externen Karten-/Geocoding-Dienste. - 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. - Die Profiladresse unterstuetzt jetzt ausserdem eine Auswahl moeglicher Adress-Treffer, die Uebernahme aus dem Browser-Standort und einen kurzen Hinweisdialog zur lokalen Relevanz.
- Der Profil-Editor im Mitgliederbereich ist jetzt kompakter aufgebaut, in ausklappbare Bereiche gegliedert und enthaelt die bearbeitbare Konto-E-Mail direkt im Formular. - Der Profil-Editor im Mitgliederbereich ist jetzt kompakter aufgebaut, in ausklappbare Bereiche gegliedert und enthaelt die bearbeitbare Konto-E-Mail direkt im Formular.
- Die Profil-Zusammenfassung oberhalb des Editors ist aktuell absichtlich als leicht rueckbaubare kompakte Zwischenvariante umgesetzt; die Umschaltstelle liegt direkt im Template.
- Fuer Umkreis- und Distanzfunktionen bleiben nur `lat`/`lng` technisch im Klartext; die eigentliche Strasse/Hausnummer ist verschluesselt. - 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. - 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. - Ä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.

View File

@@ -41,6 +41,7 @@ Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter. Kernbereiche sind l
- 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. - 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 Termin-Hinweise. - Die Profiladresse bietet jetzt zusaetzlich eine Trefferauswahl fuer die Suche, eine Uebernahme aus dem Browser-Standort und einen kurzen Hinweisdialog zur Relevanz fuer lokale Termin-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. - 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.
- Die Profil-Zusammenfassung oberhalb des Editors ist aktuell absichtlich als leicht rueckbaubare kompakte Zwischenvariante umgesetzt; die Umschaltstelle liegt direkt im Template.
- Im Profil kann der Nutzer aktuell Komponenten wie Augen, Augenbrauen, Mund, Brille, Haare, Bart und Ohrringe direkt per Vorschaubild auswählen. - 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. - 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. - Beim Oeffnen des Avatar-Generators wird nur der aktive Style-/Komponenten-Tab geladen; weitere Varianten werden erst beim Wechsel nachgeladen.

View File

@@ -35,6 +35,7 @@ Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter mit Fokus auf lokale
- das Profil unterstuetzt jetzt eine vollstaendige Adresse mit verschluesselter Strasse/Hausnummer sowie optionaler Adress-Lokalisierung ueber die bereits vorhandenen Karten-/Geocoding-Dienste - 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 Termine relevant ist - 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 Termine 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 - der Profil-Editor im Mitgliederbereich ist jetzt kompakter gruppiert, nutzt ausklappbare Abschnitte und enthaelt die bearbeitbare Konto-E-Mail wieder direkt im Formular
- die Profil-Zusammenfassung oberhalb des Editors laeuft aktuell als bewusst leicht rueckbaubare kompakte Zwischenvariante mit klarer Umschaltstelle direkt im Template
- Debug-Floating-Button nur für `site_admin` im Debug-Modus - Debug-Floating-Button nur für `site_admin` im Debug-Modus
## Technik ## Technik

View File

@@ -13,6 +13,7 @@ $allowNoKidsChecked = $editEvent ? ((int)$editEvent['allow_kids'] === 0) : false
$editingChild = isset($editChild) && $editChild !== null; $editingChild = isset($editChild) && $editChild !== null;
$childAction = $editingChild ? 'child_update' : 'child_add'; $childAction = $editingChild ? 'child_update' : 'child_add';
$childModalTitle = $editingChild ? 'Kind bearbeiten' : 'Kind hinzufügen'; $childModalTitle = $editingChild ? 'Kind bearbeiten' : 'Kind hinzufügen';
$useCompactProfileSummary = true;
$sectionLinks = [ $sectionLinks = [
'profile' => 'Profil', 'profile' => 'Profil',
'children' => 'Kinder', 'children' => 'Kinder',
@@ -78,30 +79,58 @@ $sectionLinks = [
<button class="btn" type="button" data-modal-open="modalAvatar">Profilbild gestalten</button> <button class="btn" type="button" data-modal-open="modalAvatar">Profilbild gestalten</button>
</div> </div>
</div> </div>
<div class="profile-summary-grid"> <?php if ($useCompactProfileSummary): ?>
<section class="profile-summary-card"> <div class="profile-hero-summary">
<span class="profile-summary-card__eyebrow">Basis</span> <section class="profile-hero-summary__card">
<dl class="account-kv account-kv--compact"> <span class="profile-summary-card__eyebrow">Kontakt</span>
<div><dt>Anzeigename</dt><dd><?= htmlspecialchars($profile['display_name'] ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div> <strong><?= htmlspecialchars($profile['display_name'] ?: 'Nicht hinterlegt', ENT_QUOTES) ?></strong>
<div><dt>Name</dt><dd><?= htmlspecialchars(trim($profile['first_name'] . ' ' . $profile['last_name']) ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div> <p><?= htmlspecialchars($profile['email'] ?: 'Keine E-Mail hinterlegt', ENT_QUOTES) ?></p>
<div><dt>E-Mail</dt><dd><?= htmlspecialchars($profile['email'] ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div> <p><?= htmlspecialchars($profile['contact_phone'] ?: 'Keine Telefonnummer hinterlegt', ENT_QUOTES) ?></p>
<div><dt>Telefon</dt><dd><?= htmlspecialchars($profile['contact_phone'] ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div> </section>
</dl> <section class="profile-hero-summary__card">
</section> <span class="profile-summary-card__eyebrow">Standort</span>
<section class="profile-summary-card"> <strong><?= htmlspecialchars($profile['city'] ?: 'Kein Ort hinterlegt', ENT_QUOTES) ?></strong>
<span class="profile-summary-card__eyebrow">Standort</span> <p><?= htmlspecialchars(trim(implode(', ', array_filter([(string)($profile['street'] ?? ''), trim((string)$profile['zip'] . ' ' . (string)$profile['city']), (string)($profile['region'] ?? '')]))) ?: 'Keine vollständige Adresse hinterlegt', ENT_QUOTES) ?></p>
<dl class="account-kv account-kv--compact"> </section>
<div><dt>Adresse</dt><dd><?= htmlspecialchars(trim(implode(', ', array_filter([(string)($profile['street'] ?? ''), trim((string)$profile['zip'] . ' ' . (string)$profile['city']), (string)($profile['region'] ?? '')]))) ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div> <section class="profile-hero-summary__card">
<div><dt>Sprachen</dt><dd><?= htmlspecialchars($profile['languages'] ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div> <span class="profile-summary-card__eyebrow">Profil</span>
<div><dt>Beruf</dt><dd><?= htmlspecialchars($profile['profession'] ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div> <strong><?= htmlspecialchars(trim($profile['first_name'] . ' ' . $profile['last_name']) ?: 'Kein Klarname hinterlegt', ENT_QUOTES) ?></strong>
</dl> <p><?= htmlspecialchars($profile['profession'] ?: 'Kein Beruf hinterlegt', ENT_QUOTES) ?></p>
</section> <p><?= htmlspecialchars($profile['languages'] ?: 'Keine Sprachen hinterlegt', ENT_QUOTES) ?></p>
</div> </section>
<?php if (trim((string)$profile['about']) !== ''): ?>
<div class="profile-about-card">
<strong>Über dich</strong>
<p><?= nl2br(htmlspecialchars((string)$profile['about'], ENT_QUOTES)) ?></p>
</div> </div>
<?php if (trim((string)$profile['about']) !== ''): ?>
<div class="profile-about-card">
<strong>Über dich</strong>
<p><?= nl2br(htmlspecialchars((string)$profile['about'], ENT_QUOTES)) ?></p>
</div>
<?php endif; ?>
<?php else: ?>
<div class="profile-summary-grid">
<section class="profile-summary-card">
<span class="profile-summary-card__eyebrow">Basis</span>
<dl class="account-kv account-kv--compact">
<div><dt>Anzeigename</dt><dd><?= htmlspecialchars($profile['display_name'] ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div>
<div><dt>Name</dt><dd><?= htmlspecialchars(trim($profile['first_name'] . ' ' . $profile['last_name']) ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div>
<div><dt>E-Mail</dt><dd><?= htmlspecialchars($profile['email'] ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div>
<div><dt>Telefon</dt><dd><?= htmlspecialchars($profile['contact_phone'] ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div>
</dl>
</section>
<section class="profile-summary-card">
<span class="profile-summary-card__eyebrow">Standort</span>
<dl class="account-kv account-kv--compact">
<div><dt>Adresse</dt><dd><?= htmlspecialchars(trim(implode(', ', array_filter([(string)($profile['street'] ?? ''), trim((string)$profile['zip'] . ' ' . (string)$profile['city']), (string)($profile['region'] ?? '')]))) ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div>
<div><dt>Sprachen</dt><dd><?= htmlspecialchars($profile['languages'] ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div>
<div><dt>Beruf</dt><dd><?= htmlspecialchars($profile['profession'] ?: 'Nicht hinterlegt', ENT_QUOTES) ?></dd></div>
</dl>
</section>
</div>
<?php if (trim((string)$profile['about']) !== ''): ?>
<div class="profile-about-card">
<strong>Über dich</strong>
<p><?= nl2br(htmlspecialchars((string)$profile['about'], ENT_QUOTES)) ?></p>
</div>
<?php endif; ?>
<?php endif; ?> <?php endif; ?>
<div class="flex gap-12" style="margin-top:18px;"> <div class="flex gap-12" style="margin-top:18px;">
<button class="btn" type="button" data-modal-open="modalProfile">Profil bearbeiten</button> <button class="btn" type="button" data-modal-open="modalProfile">Profil bearbeiten</button>

View File

@@ -252,6 +252,10 @@ body {
.profile-summary-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; } .profile-summary-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.profile-summary-card { padding: 18px; background: #fffdfa; border: 1px solid var(--color-border); border-radius: 18px; } .profile-summary-card { padding: 18px; background: #fffdfa; border: 1px solid var(--color-border); border-radius: 18px; }
.profile-summary-card__eyebrow { display: inline-block; margin-bottom: 12px; font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--color-highlight); } .profile-summary-card__eyebrow { display: inline-block; margin-bottom: 12px; font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--color-highlight); }
.profile-hero-summary { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.profile-hero-summary__card { display: grid; gap: 8px; align-content: start; padding: 18px; background: linear-gradient(135deg, #fffdfa, #f7f0e6); border: 1px solid var(--color-border); border-radius: 18px; }
.profile-hero-summary__card strong { font-size: 18px; line-height: 1.25; }
.profile-hero-summary__card p { margin: 0; color: var(--color-muted); line-height: 1.5; }
.profile-about-card { margin-top: 16px; padding: 18px; background: linear-gradient(135deg, #fff, #f8f4ec); border: 1px solid var(--color-border); border-radius: 18px; } .profile-about-card { margin-top: 16px; padding: 18px; background: linear-gradient(135deg, #fff, #f8f4ec); border: 1px solid var(--color-border); border-radius: 18px; }
.profile-about-card strong { display: block; margin-bottom: 8px; } .profile-about-card strong { display: block; margin-bottom: 8px; }
.profile-about-card p { margin: 0; line-height: 1.65; color: var(--color-text); } .profile-about-card p { margin: 0; line-height: 1.65; color: var(--color-text); }
@@ -302,7 +306,7 @@ body {
.avatar-component-card__label { font-size: 12px; font-weight: 700; color: var(--color-text); text-align: center; } .avatar-component-card__label { font-size: 12px; font-weight: 700; color: var(--color-text); text-align: center; }
.avatar-component-card:has(input:checked) { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(52,72,90,0.14); } .avatar-component-card:has(input:checked) { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(52,72,90,0.14); }
@media (max-width: 980px){ .avatar-component-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } } @media (max-width: 980px){ .avatar-component-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 860px){ .avatar-builder__hero { grid-template-columns: 1fr; } .avatar-builder__actions { justify-content: center; } .avatar-component-colors { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); } .avatar-component-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .profile-summary-grid { grid-template-columns: 1fr; } } @media (max-width: 860px){ .avatar-builder__hero { grid-template-columns: 1fr; } .avatar-builder__actions { justify-content: center; } .avatar-component-colors { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); } .avatar-component-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .profile-summary-grid, .profile-hero-summary { grid-template-columns: 1fr; } }
.avatar-swatch-group { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; } .avatar-swatch-group { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
.avatar-swatch { display: grid; grid-template-columns: 20px 18px minmax(0, 1fr); gap: 10px; align-items: center; padding: 10px 12px; border: 1px solid var(--color-border); border-radius: 14px; background: #fff; cursor: pointer; } .avatar-swatch { display: grid; grid-template-columns: 20px 18px minmax(0, 1fr); gap: 10px; align-items: center; padding: 10px 12px; border: 1px solid var(--color-border); border-radius: 14px; background: #fff; cursor: pointer; }
.avatar-swatch__color { width: 18px; height: 18px; border-radius: 999px; background: var(--swatch-color); border: 1px solid rgba(0,0,0,0.12); } .avatar-swatch__color { width: 18px; height: 18px; border-radius: 999px; background: var(--swatch-color); border: 1px solid rgba(0,0,0,0.12); }