diff --git a/.projektstructure.txt b/.projektstructure.txt index e80a2fe..fd271dc 100755 --- a/.projektstructure.txt +++ b/.projektstructure.txt @@ -1,10 +1,9 @@ Anweisung: Projektstruktur (Basis-Template) wie in „papa-kind-treff“ Aktueller Projektstand -- Papa-Kind-Treff nutzt im Mitgliederbereich einen modernen Avatar-Generator auf Layer-Basis. -- Die Avatare bestehen aus getrennten SVG-Ebenen für Kopf, Haare, Bart, Brille, Mütze, Outfit und Farben. +- Papa-Kind-Treff nutzt im Mitgliederbereich 100 moderne Portrait-Presets im gewünschten Referenzstil. - Relevante Logik liegt in `src/App/Avatar.php`. -- Die Layer-Assets liegen unter `public/assets/avatars/layers/modern/`. +- Die Preset-Assets liegen unter `public/assets/avatars/presets/`. - Ä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. Ziel diff --git a/PROJECT_CONTEXT.md b/PROJECT_CONTEXT.md index dafd1d1..58dcf3d 100644 --- a/PROJECT_CONTEXT.md +++ b/PROJECT_CONTEXT.md @@ -19,13 +19,13 @@ Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter. Kernbereiche sind l - 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 Treffen und werden künftig weiter ausgebaut. -- Profilbilder werden aktuell über einen modernen Layer-Generator mit getrennten SVG-Ebenen statt über freie Bild-Uploads erzeugt. +- Profilbilder werden aktuell über 100 moderne Preset-Portraits im gewünschten Referenzstil statt über freie Bild-Uploads erzeugt. ## Navigation / Konto - Eingeloggte Nutzer sehen rechts ein Profil-Menü statt einzelner `Dashboard`-/`Logout`-Buttons. - Das Profil-Menü enthält aktuell `Profil`, `Kinder`, `Termine`, `Community`, `Einstellungen`, `Abmelden`. - Der Mitgliederbereich selbst ist als Layout mit linker Bereichsnavigation aufgebaut. -- Im Profil kann der Nutzer aktuell seinen Avatar über Layer für Kopfform, Haare, Bart, Brille, Mütze, Outfit und Farbwelten zusammenstellen. +- Im Profil kann der Nutzer aktuell aus 100 modernen Preset-Varianten wählen, gruppiert nach Hauttönen. - Debug ist kein Menüpunkt und erscheint nur als Floating-Käfer für `site_admin` bei aktivem Debug-Modus. ## Community und Rechte diff --git a/README.md b/README.md index 1e2a134..ca1afa5 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Papa-Kind-Treff ist eine PHP-basierte Plattform für Väter mit Fokus auf lokale - Impressum, Datenschutz-&-Cookies-Seite und Über-uns - standortbasierte Sortierung für die neuesten Treffen - eigener Einstellungsbereich für Standortfreigabe, Browser-Hinweise und Consent-Verwaltung -- moderner Avatar-Generator auf Layer-Basis mit kombinierbaren SVG-Elementen für Kopf, Haare, Bart, Brille, Mütze, Outfit und Farben +- modernes Avatar-System auf Basis von 100 festen Portrait-Presets im Referenzstil, gruppiert nach Hauttönen - Consent-Manager für Analyse und externe Dienste - Navigation aktuell mit `Home`, `Suche`, `Community` - eingeloggte Nutzer sehen rechts ein Profil-Menü mit Direktlinks zu `Profil`, `Kinder`, `Termine`, `Community`, `Einstellungen` diff --git a/partials/landing/account/dashboard.php b/partials/landing/account/dashboard.php index b1684af..0b85b4f 100755 --- a/partials/landing/account/dashboard.php +++ b/partials/landing/account/dashboard.php @@ -67,7 +67,7 @@ $sectionLinks = [

Dein Profilbild

-

Stell dir mit wenigen Klicks ein wiedererkennbares Community-Bild zusammen. Du kannst Haut, Haare, Augen, Bart, Brille und Kopfform direkt anpassen.

+

Wähle ein modernes Portrait im Stil der Community. Die Varianten bleiben konsistent, frisch und deutlich näher an der gewünschten Optik.

@@ -302,121 +302,39 @@ $sectionLinks = [
-

Stell dein Portrait direkt aus Haaren, Bart, Brille, Mütze, Outfit und Farben zusammen. Die Vorschau wird sofort aktualisiert.

+

Wähle zuerst einen Hautton-Bereich und dann eine passende Variante. Die Vorschau aktualisiert sich sofort.

-
- - +
+ $groupMeta): ?> + +
- - -
-
- - -
-
- - -
-
- - -
-
- - -
- -
- Hautfarbe -
- $meta): ?> - - -
-
- -
- Haarfarbe -
- $meta): ?> - - -
-
- -
- Augenfarbe -
- $meta): ?> - - -
-
- -
- Mützenfarbe -
- $meta): ?> - - -
-
- -
- Outfit-Farbe -
- $meta): ?> - - -
+ Variante wählen + $groupPresets): ?> +
+
+ $meta): ?> + + +
+
+
diff --git a/public/assets/avatars/presets/modern_001.png b/public/assets/avatars/presets/modern_001.png new file mode 100644 index 0000000..dbdf204 Binary files /dev/null and b/public/assets/avatars/presets/modern_001.png differ diff --git a/public/assets/avatars/presets/modern_002.png b/public/assets/avatars/presets/modern_002.png new file mode 100644 index 0000000..733939b Binary files /dev/null and b/public/assets/avatars/presets/modern_002.png differ diff --git a/public/assets/avatars/presets/modern_003.png b/public/assets/avatars/presets/modern_003.png new file mode 100644 index 0000000..4768846 Binary files /dev/null and b/public/assets/avatars/presets/modern_003.png differ diff --git a/public/assets/avatars/presets/modern_004.png b/public/assets/avatars/presets/modern_004.png new file mode 100644 index 0000000..8505bbf Binary files /dev/null and b/public/assets/avatars/presets/modern_004.png differ diff --git a/public/assets/avatars/presets/modern_005.png b/public/assets/avatars/presets/modern_005.png new file mode 100644 index 0000000..2955ab9 Binary files /dev/null and b/public/assets/avatars/presets/modern_005.png differ diff --git a/public/assets/avatars/presets/modern_006.png b/public/assets/avatars/presets/modern_006.png new file mode 100644 index 0000000..a716eac Binary files /dev/null and b/public/assets/avatars/presets/modern_006.png differ diff --git a/public/assets/avatars/presets/modern_007.png b/public/assets/avatars/presets/modern_007.png new file mode 100644 index 0000000..a26c3c8 Binary files /dev/null and b/public/assets/avatars/presets/modern_007.png differ diff --git a/public/assets/avatars/presets/modern_008.png b/public/assets/avatars/presets/modern_008.png new file mode 100644 index 0000000..8395051 Binary files /dev/null and b/public/assets/avatars/presets/modern_008.png differ diff --git a/public/assets/avatars/presets/modern_009.png b/public/assets/avatars/presets/modern_009.png new file mode 100644 index 0000000..3a75dcc Binary files /dev/null and b/public/assets/avatars/presets/modern_009.png differ diff --git a/public/assets/avatars/presets/modern_010.png b/public/assets/avatars/presets/modern_010.png new file mode 100644 index 0000000..29a3e32 Binary files /dev/null and b/public/assets/avatars/presets/modern_010.png differ diff --git a/public/assets/avatars/presets/modern_011.png b/public/assets/avatars/presets/modern_011.png new file mode 100644 index 0000000..2fabf02 Binary files /dev/null and b/public/assets/avatars/presets/modern_011.png differ diff --git a/public/assets/avatars/presets/modern_012.png b/public/assets/avatars/presets/modern_012.png new file mode 100644 index 0000000..ee78593 Binary files /dev/null and b/public/assets/avatars/presets/modern_012.png differ diff --git a/public/assets/avatars/presets/modern_013.png b/public/assets/avatars/presets/modern_013.png new file mode 100644 index 0000000..452e340 Binary files /dev/null and b/public/assets/avatars/presets/modern_013.png differ diff --git a/public/assets/avatars/presets/modern_014.png b/public/assets/avatars/presets/modern_014.png new file mode 100644 index 0000000..9a86b35 Binary files /dev/null and b/public/assets/avatars/presets/modern_014.png differ diff --git a/public/assets/avatars/presets/modern_015.png b/public/assets/avatars/presets/modern_015.png new file mode 100644 index 0000000..54b911c Binary files /dev/null and b/public/assets/avatars/presets/modern_015.png differ diff --git a/public/assets/avatars/presets/modern_016.png b/public/assets/avatars/presets/modern_016.png new file mode 100644 index 0000000..c68c69b Binary files /dev/null and b/public/assets/avatars/presets/modern_016.png differ diff --git a/public/assets/avatars/presets/modern_017.png b/public/assets/avatars/presets/modern_017.png new file mode 100644 index 0000000..185bc03 Binary files /dev/null and b/public/assets/avatars/presets/modern_017.png differ diff --git a/public/assets/avatars/presets/modern_018.png b/public/assets/avatars/presets/modern_018.png new file mode 100644 index 0000000..8fd7ce6 Binary files /dev/null and b/public/assets/avatars/presets/modern_018.png differ diff --git a/public/assets/avatars/presets/modern_019.png b/public/assets/avatars/presets/modern_019.png new file mode 100644 index 0000000..7f309ae Binary files /dev/null and b/public/assets/avatars/presets/modern_019.png differ diff --git a/public/assets/avatars/presets/modern_020.png b/public/assets/avatars/presets/modern_020.png new file mode 100644 index 0000000..b6d8331 Binary files /dev/null and b/public/assets/avatars/presets/modern_020.png differ diff --git a/public/assets/avatars/presets/modern_021.png b/public/assets/avatars/presets/modern_021.png new file mode 100644 index 0000000..473b078 Binary files /dev/null and b/public/assets/avatars/presets/modern_021.png differ diff --git a/public/assets/avatars/presets/modern_022.png b/public/assets/avatars/presets/modern_022.png new file mode 100644 index 0000000..b5e9360 Binary files /dev/null and b/public/assets/avatars/presets/modern_022.png differ diff --git a/public/assets/avatars/presets/modern_023.png b/public/assets/avatars/presets/modern_023.png new file mode 100644 index 0000000..45f742f Binary files /dev/null and b/public/assets/avatars/presets/modern_023.png differ diff --git a/public/assets/avatars/presets/modern_024.png b/public/assets/avatars/presets/modern_024.png new file mode 100644 index 0000000..10f9dc9 Binary files /dev/null and b/public/assets/avatars/presets/modern_024.png differ diff --git a/public/assets/avatars/presets/modern_025.png b/public/assets/avatars/presets/modern_025.png new file mode 100644 index 0000000..6e3394f Binary files /dev/null and b/public/assets/avatars/presets/modern_025.png differ diff --git a/public/assets/avatars/presets/modern_026.png b/public/assets/avatars/presets/modern_026.png new file mode 100644 index 0000000..277224f Binary files /dev/null and b/public/assets/avatars/presets/modern_026.png differ diff --git a/public/assets/avatars/presets/modern_027.png b/public/assets/avatars/presets/modern_027.png new file mode 100644 index 0000000..f6bca10 Binary files /dev/null and b/public/assets/avatars/presets/modern_027.png differ diff --git a/public/assets/avatars/presets/modern_028.png b/public/assets/avatars/presets/modern_028.png new file mode 100644 index 0000000..e684edd Binary files /dev/null and b/public/assets/avatars/presets/modern_028.png differ diff --git a/public/assets/avatars/presets/modern_029.png b/public/assets/avatars/presets/modern_029.png new file mode 100644 index 0000000..1de9e0a Binary files /dev/null and b/public/assets/avatars/presets/modern_029.png differ diff --git a/public/assets/avatars/presets/modern_030.png b/public/assets/avatars/presets/modern_030.png new file mode 100644 index 0000000..920c022 Binary files /dev/null and b/public/assets/avatars/presets/modern_030.png differ diff --git a/public/assets/avatars/presets/modern_031.png b/public/assets/avatars/presets/modern_031.png new file mode 100644 index 0000000..76818d5 Binary files /dev/null and b/public/assets/avatars/presets/modern_031.png differ diff --git a/public/assets/avatars/presets/modern_032.png b/public/assets/avatars/presets/modern_032.png new file mode 100644 index 0000000..c9935bf Binary files /dev/null and b/public/assets/avatars/presets/modern_032.png differ diff --git a/public/assets/avatars/presets/modern_033.png b/public/assets/avatars/presets/modern_033.png new file mode 100644 index 0000000..3f525a4 Binary files /dev/null and b/public/assets/avatars/presets/modern_033.png differ diff --git a/public/assets/avatars/presets/modern_034.png b/public/assets/avatars/presets/modern_034.png new file mode 100644 index 0000000..abc2cf6 Binary files /dev/null and b/public/assets/avatars/presets/modern_034.png differ diff --git a/public/assets/avatars/presets/modern_035.png b/public/assets/avatars/presets/modern_035.png new file mode 100644 index 0000000..519d719 Binary files /dev/null and b/public/assets/avatars/presets/modern_035.png differ diff --git a/public/assets/avatars/presets/modern_036.png b/public/assets/avatars/presets/modern_036.png new file mode 100644 index 0000000..b841220 Binary files /dev/null and b/public/assets/avatars/presets/modern_036.png differ diff --git a/public/assets/avatars/presets/modern_037.png b/public/assets/avatars/presets/modern_037.png new file mode 100644 index 0000000..503d6f9 Binary files /dev/null and b/public/assets/avatars/presets/modern_037.png differ diff --git a/public/assets/avatars/presets/modern_038.png b/public/assets/avatars/presets/modern_038.png new file mode 100644 index 0000000..dd9c212 Binary files /dev/null and b/public/assets/avatars/presets/modern_038.png differ diff --git a/public/assets/avatars/presets/modern_039.png b/public/assets/avatars/presets/modern_039.png new file mode 100644 index 0000000..79e07ea Binary files /dev/null and b/public/assets/avatars/presets/modern_039.png differ diff --git a/public/assets/avatars/presets/modern_040.png b/public/assets/avatars/presets/modern_040.png new file mode 100644 index 0000000..4178d83 Binary files /dev/null and b/public/assets/avatars/presets/modern_040.png differ diff --git a/public/assets/avatars/presets/modern_041.png b/public/assets/avatars/presets/modern_041.png new file mode 100644 index 0000000..7897a54 Binary files /dev/null and b/public/assets/avatars/presets/modern_041.png differ diff --git a/public/assets/avatars/presets/modern_042.png b/public/assets/avatars/presets/modern_042.png new file mode 100644 index 0000000..046e054 Binary files /dev/null and b/public/assets/avatars/presets/modern_042.png differ diff --git a/public/assets/avatars/presets/modern_043.png b/public/assets/avatars/presets/modern_043.png new file mode 100644 index 0000000..efda0ca Binary files /dev/null and b/public/assets/avatars/presets/modern_043.png differ diff --git a/public/assets/avatars/presets/modern_044.png b/public/assets/avatars/presets/modern_044.png new file mode 100644 index 0000000..0fd464f Binary files /dev/null and b/public/assets/avatars/presets/modern_044.png differ diff --git a/public/assets/avatars/presets/modern_045.png b/public/assets/avatars/presets/modern_045.png new file mode 100644 index 0000000..5a6e70b Binary files /dev/null and b/public/assets/avatars/presets/modern_045.png differ diff --git a/public/assets/avatars/presets/modern_046.png b/public/assets/avatars/presets/modern_046.png new file mode 100644 index 0000000..8ab2272 Binary files /dev/null and b/public/assets/avatars/presets/modern_046.png differ diff --git a/public/assets/avatars/presets/modern_047.png b/public/assets/avatars/presets/modern_047.png new file mode 100644 index 0000000..6ec9a20 Binary files /dev/null and b/public/assets/avatars/presets/modern_047.png differ diff --git a/public/assets/avatars/presets/modern_048.png b/public/assets/avatars/presets/modern_048.png new file mode 100644 index 0000000..e173b4f Binary files /dev/null and b/public/assets/avatars/presets/modern_048.png differ diff --git a/public/assets/avatars/presets/modern_049.png b/public/assets/avatars/presets/modern_049.png new file mode 100644 index 0000000..4ddaf50 Binary files /dev/null and b/public/assets/avatars/presets/modern_049.png differ diff --git a/public/assets/avatars/presets/modern_050.png b/public/assets/avatars/presets/modern_050.png new file mode 100644 index 0000000..d72e5ae Binary files /dev/null and b/public/assets/avatars/presets/modern_050.png differ diff --git a/public/assets/avatars/presets/modern_051.png b/public/assets/avatars/presets/modern_051.png new file mode 100644 index 0000000..fe9576a Binary files /dev/null and b/public/assets/avatars/presets/modern_051.png differ diff --git a/public/assets/avatars/presets/modern_052.png b/public/assets/avatars/presets/modern_052.png new file mode 100644 index 0000000..5efa6b1 Binary files /dev/null and b/public/assets/avatars/presets/modern_052.png differ diff --git a/public/assets/avatars/presets/modern_053.png b/public/assets/avatars/presets/modern_053.png new file mode 100644 index 0000000..74f66b2 Binary files /dev/null and b/public/assets/avatars/presets/modern_053.png differ diff --git a/public/assets/avatars/presets/modern_054.png b/public/assets/avatars/presets/modern_054.png new file mode 100644 index 0000000..135bc27 Binary files /dev/null and b/public/assets/avatars/presets/modern_054.png differ diff --git a/public/assets/avatars/presets/modern_055.png b/public/assets/avatars/presets/modern_055.png new file mode 100644 index 0000000..2c854c4 Binary files /dev/null and b/public/assets/avatars/presets/modern_055.png differ diff --git a/public/assets/avatars/presets/modern_056.png b/public/assets/avatars/presets/modern_056.png new file mode 100644 index 0000000..acb896f Binary files /dev/null and b/public/assets/avatars/presets/modern_056.png differ diff --git a/public/assets/avatars/presets/modern_057.png b/public/assets/avatars/presets/modern_057.png new file mode 100644 index 0000000..7177e1c Binary files /dev/null and b/public/assets/avatars/presets/modern_057.png differ diff --git a/public/assets/avatars/presets/modern_058.png b/public/assets/avatars/presets/modern_058.png new file mode 100644 index 0000000..7798f15 Binary files /dev/null and b/public/assets/avatars/presets/modern_058.png differ diff --git a/public/assets/avatars/presets/modern_059.png b/public/assets/avatars/presets/modern_059.png new file mode 100644 index 0000000..f207d88 Binary files /dev/null and b/public/assets/avatars/presets/modern_059.png differ diff --git a/public/assets/avatars/presets/modern_060.png b/public/assets/avatars/presets/modern_060.png new file mode 100644 index 0000000..61d0bbf Binary files /dev/null and b/public/assets/avatars/presets/modern_060.png differ diff --git a/public/assets/avatars/presets/modern_061.png b/public/assets/avatars/presets/modern_061.png new file mode 100644 index 0000000..0134325 Binary files /dev/null and b/public/assets/avatars/presets/modern_061.png differ diff --git a/public/assets/avatars/presets/modern_062.png b/public/assets/avatars/presets/modern_062.png new file mode 100644 index 0000000..67107c0 Binary files /dev/null and b/public/assets/avatars/presets/modern_062.png differ diff --git a/public/assets/avatars/presets/modern_063.png b/public/assets/avatars/presets/modern_063.png new file mode 100644 index 0000000..b18783b Binary files /dev/null and b/public/assets/avatars/presets/modern_063.png differ diff --git a/public/assets/avatars/presets/modern_064.png b/public/assets/avatars/presets/modern_064.png new file mode 100644 index 0000000..d1b8eb0 Binary files /dev/null and b/public/assets/avatars/presets/modern_064.png differ diff --git a/public/assets/avatars/presets/modern_065.png b/public/assets/avatars/presets/modern_065.png new file mode 100644 index 0000000..1af2bbe Binary files /dev/null and b/public/assets/avatars/presets/modern_065.png differ diff --git a/public/assets/avatars/presets/modern_066.png b/public/assets/avatars/presets/modern_066.png new file mode 100644 index 0000000..1d912f1 Binary files /dev/null and b/public/assets/avatars/presets/modern_066.png differ diff --git a/public/assets/avatars/presets/modern_067.png b/public/assets/avatars/presets/modern_067.png new file mode 100644 index 0000000..d8dd1f8 Binary files /dev/null and b/public/assets/avatars/presets/modern_067.png differ diff --git a/public/assets/avatars/presets/modern_068.png b/public/assets/avatars/presets/modern_068.png new file mode 100644 index 0000000..179e5fe Binary files /dev/null and b/public/assets/avatars/presets/modern_068.png differ diff --git a/public/assets/avatars/presets/modern_069.png b/public/assets/avatars/presets/modern_069.png new file mode 100644 index 0000000..18e63d2 Binary files /dev/null and b/public/assets/avatars/presets/modern_069.png differ diff --git a/public/assets/avatars/presets/modern_070.png b/public/assets/avatars/presets/modern_070.png new file mode 100644 index 0000000..fb39ea0 Binary files /dev/null and b/public/assets/avatars/presets/modern_070.png differ diff --git a/public/assets/avatars/presets/modern_071.png b/public/assets/avatars/presets/modern_071.png new file mode 100644 index 0000000..5928cd8 Binary files /dev/null and b/public/assets/avatars/presets/modern_071.png differ diff --git a/public/assets/avatars/presets/modern_072.png b/public/assets/avatars/presets/modern_072.png new file mode 100644 index 0000000..ab8ef9f Binary files /dev/null and b/public/assets/avatars/presets/modern_072.png differ diff --git a/public/assets/avatars/presets/modern_073.png b/public/assets/avatars/presets/modern_073.png new file mode 100644 index 0000000..a7bd5ba Binary files /dev/null and b/public/assets/avatars/presets/modern_073.png differ diff --git a/public/assets/avatars/presets/modern_074.png b/public/assets/avatars/presets/modern_074.png new file mode 100644 index 0000000..3906c85 Binary files /dev/null and b/public/assets/avatars/presets/modern_074.png differ diff --git a/public/assets/avatars/presets/modern_075.png b/public/assets/avatars/presets/modern_075.png new file mode 100644 index 0000000..3bf8a5d Binary files /dev/null and b/public/assets/avatars/presets/modern_075.png differ diff --git a/public/assets/avatars/presets/modern_076.png b/public/assets/avatars/presets/modern_076.png new file mode 100644 index 0000000..0bf1943 Binary files /dev/null and b/public/assets/avatars/presets/modern_076.png differ diff --git a/public/assets/avatars/presets/modern_077.png b/public/assets/avatars/presets/modern_077.png new file mode 100644 index 0000000..c3fc9e0 Binary files /dev/null and b/public/assets/avatars/presets/modern_077.png differ diff --git a/public/assets/avatars/presets/modern_078.png b/public/assets/avatars/presets/modern_078.png new file mode 100644 index 0000000..1bc700e Binary files /dev/null and b/public/assets/avatars/presets/modern_078.png differ diff --git a/public/assets/avatars/presets/modern_079.png b/public/assets/avatars/presets/modern_079.png new file mode 100644 index 0000000..e4cd130 Binary files /dev/null and b/public/assets/avatars/presets/modern_079.png differ diff --git a/public/assets/avatars/presets/modern_080.png b/public/assets/avatars/presets/modern_080.png new file mode 100644 index 0000000..f5d911b Binary files /dev/null and b/public/assets/avatars/presets/modern_080.png differ diff --git a/public/assets/avatars/presets/modern_081.png b/public/assets/avatars/presets/modern_081.png new file mode 100644 index 0000000..cd11baf Binary files /dev/null and b/public/assets/avatars/presets/modern_081.png differ diff --git a/public/assets/avatars/presets/modern_082.png b/public/assets/avatars/presets/modern_082.png new file mode 100644 index 0000000..e8061d7 Binary files /dev/null and b/public/assets/avatars/presets/modern_082.png differ diff --git a/public/assets/avatars/presets/modern_083.png b/public/assets/avatars/presets/modern_083.png new file mode 100644 index 0000000..23bb2fd Binary files /dev/null and b/public/assets/avatars/presets/modern_083.png differ diff --git a/public/assets/avatars/presets/modern_084.png b/public/assets/avatars/presets/modern_084.png new file mode 100644 index 0000000..c4bf80e Binary files /dev/null and b/public/assets/avatars/presets/modern_084.png differ diff --git a/public/assets/avatars/presets/modern_085.png b/public/assets/avatars/presets/modern_085.png new file mode 100644 index 0000000..ee90561 Binary files /dev/null and b/public/assets/avatars/presets/modern_085.png differ diff --git a/public/assets/avatars/presets/modern_086.png b/public/assets/avatars/presets/modern_086.png new file mode 100644 index 0000000..b11997f Binary files /dev/null and b/public/assets/avatars/presets/modern_086.png differ diff --git a/public/assets/avatars/presets/modern_087.png b/public/assets/avatars/presets/modern_087.png new file mode 100644 index 0000000..83b7504 Binary files /dev/null and b/public/assets/avatars/presets/modern_087.png differ diff --git a/public/assets/avatars/presets/modern_088.png b/public/assets/avatars/presets/modern_088.png new file mode 100644 index 0000000..86f8252 Binary files /dev/null and b/public/assets/avatars/presets/modern_088.png differ diff --git a/public/assets/avatars/presets/modern_089.png b/public/assets/avatars/presets/modern_089.png new file mode 100644 index 0000000..014371a Binary files /dev/null and b/public/assets/avatars/presets/modern_089.png differ diff --git a/public/assets/avatars/presets/modern_090.png b/public/assets/avatars/presets/modern_090.png new file mode 100644 index 0000000..0c1d71a Binary files /dev/null and b/public/assets/avatars/presets/modern_090.png differ diff --git a/public/assets/avatars/presets/modern_091.png b/public/assets/avatars/presets/modern_091.png new file mode 100644 index 0000000..08c43fc Binary files /dev/null and b/public/assets/avatars/presets/modern_091.png differ diff --git a/public/assets/avatars/presets/modern_092.png b/public/assets/avatars/presets/modern_092.png new file mode 100644 index 0000000..0507370 Binary files /dev/null and b/public/assets/avatars/presets/modern_092.png differ diff --git a/public/assets/avatars/presets/modern_093.png b/public/assets/avatars/presets/modern_093.png new file mode 100644 index 0000000..13b3469 Binary files /dev/null and b/public/assets/avatars/presets/modern_093.png differ diff --git a/public/assets/avatars/presets/modern_094.png b/public/assets/avatars/presets/modern_094.png new file mode 100644 index 0000000..7a331d2 Binary files /dev/null and b/public/assets/avatars/presets/modern_094.png differ diff --git a/public/assets/avatars/presets/modern_095.png b/public/assets/avatars/presets/modern_095.png new file mode 100644 index 0000000..dc20b49 Binary files /dev/null and b/public/assets/avatars/presets/modern_095.png differ diff --git a/public/assets/avatars/presets/modern_096.png b/public/assets/avatars/presets/modern_096.png new file mode 100644 index 0000000..54c40ed Binary files /dev/null and b/public/assets/avatars/presets/modern_096.png differ diff --git a/public/assets/avatars/presets/modern_097.png b/public/assets/avatars/presets/modern_097.png new file mode 100644 index 0000000..becb4ab Binary files /dev/null and b/public/assets/avatars/presets/modern_097.png differ diff --git a/public/assets/avatars/presets/modern_098.png b/public/assets/avatars/presets/modern_098.png new file mode 100644 index 0000000..7b9ecc3 Binary files /dev/null and b/public/assets/avatars/presets/modern_098.png differ diff --git a/public/assets/avatars/presets/modern_099.png b/public/assets/avatars/presets/modern_099.png new file mode 100644 index 0000000..ab25ead Binary files /dev/null and b/public/assets/avatars/presets/modern_099.png differ diff --git a/public/assets/avatars/presets/modern_100.png b/public/assets/avatars/presets/modern_100.png new file mode 100644 index 0000000..6406155 Binary files /dev/null and b/public/assets/avatars/presets/modern_100.png differ diff --git a/public/assets/css/app.css b/public/assets/css/app.css index f2e82a2..e8cf479 100755 --- a/public/assets/css/app.css +++ b/public/assets/css/app.css @@ -120,6 +120,7 @@ body { .pkt-avatar--forum { --avatar-size: 52px; border-radius: 16px; } .pkt-avatar--xl { --avatar-size: 120px; border-radius: 28px; } .pkt-avatar--xxl { --avatar-size: 168px; border-radius: 36px; } +.pkt-avatar__img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center top; } .pkt-avatar--layered::before { content: ""; position: absolute; inset: auto 8% -8% 8%; height: 28%; border-radius: 50%; background: radial-gradient(circle at center, rgba(74, 52, 38, 0.16), transparent 70%); filter: blur(10px); z-index: 0; pointer-events: none; } .pkt-avatar__layer { position: absolute; inset: 0; display: block; z-index: 1; pointer-events: none; } .pkt-avatar__layer--outfit { z-index: 1; } @@ -249,6 +250,21 @@ body { .avatar-builder__layout { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 24px; align-items: start; } .avatar-builder__preview { position: sticky; top: 0; display: grid; justify-items: center; gap: 12px; padding: 18px; background: linear-gradient(180deg, #fffdfa, #f8f4ec); border: 1px solid var(--color-border); border-radius: 18px; } .avatar-builder__controls { display: grid; gap: 18px; } +.avatar-preset-filters { display: flex; flex-wrap: wrap; gap: 10px; } +.avatar-preset-filter { border: 1px solid var(--color-border); background: #fff; color: var(--color-text); border-radius: 999px; padding: 10px 14px; font: inherit; font-weight: 700; cursor: pointer; transition: border-color .15s ease, box-shadow .15s ease, background .15s ease, color .15s ease; } +.avatar-preset-filter:hover { border-color: var(--color-primary); color: var(--color-primary); } +.avatar-preset-filter.is-active { background: var(--color-primary); color: var(--color-primary-contrast); border-color: var(--color-primary); box-shadow: 0 10px 20px rgba(41, 31, 22, 0.08); } +.avatar-preset-group { display: none; } +.avatar-preset-group.is-active { display: block; } +.avatar-preset-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 12px; } +.avatar-preset-card { position: relative; display: grid; gap: 8px; align-content: start; padding: 10px; border: 1px solid var(--color-border); border-radius: 16px; background: #fff; cursor: pointer; transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease; } +.avatar-preset-card:hover { border-color: var(--color-primary); box-shadow: 0 10px 20px rgba(41, 31, 22, 0.08); transform: translateY(-1px); } +.avatar-preset-card input { position: absolute; opacity: 0; pointer-events: none; } +.avatar-preset-card__thumb { display: block; aspect-ratio: 1; border-radius: 14px; overflow: hidden; background: linear-gradient(180deg, #f7efe6, #f0e4d7); border: 1px solid rgba(74, 52, 38, 0.08); } +.avatar-preset-card__thumb img { width: 100%; height: 100%; object-fit: cover; object-position: center top; display: block; } +.avatar-preset-card__label { font-size: 13px; font-weight: 700; color: var(--color-text); } +.avatar-preset-card:has(input:checked) { border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(52,72,90,0.14); } +@media (max-width: 860px){ .avatar-builder__layout { grid-template-columns: 1fr; } .avatar-builder__preview { position: static; } } .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__color { width: 18px; height: 18px; border-radius: 999px; background: var(--swatch-color); border: 1px solid rgba(0,0,0,0.12); } diff --git a/public/assets/js/app.js b/public/assets/js/app.js index 71ba718..874b275 100755 --- a/public/assets/js/app.js +++ b/public/assets/js/app.js @@ -726,15 +726,6 @@ document.addEventListener('DOMContentLoaded', () => { }); document.addEventListener('pkt:open-consent', openConsentModal); - const avatarPreviewClassPrefixes = [ - 'pkt-avatar--head-', - 'pkt-avatar--hair-', - 'pkt-avatar--beard-', - 'pkt-avatar--glasses-', - 'pkt-avatar--hat-', - 'pkt-avatar--outfit-', - ]; - const updateAvatarPreview = (form) => { const preview = form.querySelector('[data-avatar-preview] .pkt-avatar'); if (!preview) return; @@ -745,28 +736,13 @@ document.addEventListener('DOMContentLoaded', () => { const input = form.querySelector(`[data-avatar-field="${field}"]`); return input ? input.value : ''; }; - const readColor = (field) => { - const checked = form.querySelector(`[data-avatar-field="${field}"]:checked`); - return checked ? checked.getAttribute('data-avatar-color') || '' : ''; - }; + const image = preview.querySelector('.pkt-avatar__img'); + if (!image) return; - avatarPreviewClassPrefixes.forEach((prefix) => { - Array.from(preview.classList) - .filter((className) => className.startsWith(prefix)) - .forEach((className) => preview.classList.remove(className)); - }); + const preset = readValue('avatar_preset'); + if (!preset) return; - preview.classList.add(`pkt-avatar--head-${readValue('avatar_head_shape')}`); - preview.classList.add(`pkt-avatar--hair-${readValue('avatar_hair_style')}`); - preview.classList.add(`pkt-avatar--beard-${readValue('avatar_beard_style')}`); - preview.classList.add(`pkt-avatar--glasses-${readValue('avatar_glasses_style')}`); - preview.classList.add(`pkt-avatar--hat-${readValue('avatar_hat_style')}`); - preview.classList.add(`pkt-avatar--outfit-${readValue('avatar_outfit_style')}`); - preview.style.setProperty('--avatar-skin', readColor('avatar_skin_tone')); - preview.style.setProperty('--avatar-hair', readColor('avatar_hair_color')); - preview.style.setProperty('--avatar-eye', readColor('avatar_eye_color')); - preview.style.setProperty('--avatar-hat', readColor('avatar_hat_color')); - preview.style.setProperty('--avatar-outfit', readColor('avatar_outfit_color')); + image.src = `/assets/avatars/presets/${preset}.png`; }; document.querySelectorAll('[data-avatar-builder]').forEach((form) => { @@ -775,6 +751,37 @@ document.addEventListener('DOMContentLoaded', () => { field.addEventListener('change', () => updateAvatarPreview(form)); field.addEventListener('input', () => updateAvatarPreview(form)); }); + + const setActivePresetGroup = (groupKey) => { + form.querySelectorAll('[data-avatar-preset-filter]').forEach((button) => { + const active = button.getAttribute('data-avatar-preset-filter') === groupKey; + button.classList.toggle('is-active', active); + button.setAttribute('aria-selected', active ? 'true' : 'false'); + }); + form.querySelectorAll('[data-avatar-preset-group]').forEach((group) => { + group.classList.toggle('is-active', group.getAttribute('data-avatar-preset-group') === groupKey); + }); + }; + + const checkedPreset = form.querySelector('[data-avatar-field="avatar_preset"]:checked'); + if (checkedPreset) { + const activeGroup = checkedPreset.closest('[data-avatar-preset-group]')?.getAttribute('data-avatar-preset-group'); + if (activeGroup) setActivePresetGroup(activeGroup); + } + + form.querySelectorAll('[data-avatar-preset-filter]').forEach((button) => { + button.addEventListener('click', () => { + const groupKey = button.getAttribute('data-avatar-preset-filter'); + if (groupKey) setActivePresetGroup(groupKey); + }); + }); + + form.querySelectorAll('[data-avatar-field="avatar_preset"]').forEach((field) => { + field.addEventListener('change', () => { + const activeGroup = field.closest('[data-avatar-preset-group]')?.getAttribute('data-avatar-preset-group'); + if (activeGroup) setActivePresetGroup(activeGroup); + }); + }); }); document.querySelectorAll('[data-nav-events]').forEach(link => { diff --git a/schema.sql b/schema.sql index 94aa157..2ddd237 100755 --- a/schema.sql +++ b/schema.sql @@ -30,7 +30,7 @@ CREATE TABLE user_profiles ( lat DECIMAL(10,7) NULL, lng DECIMAL(10,7) NULL, location_tracking_preference ENUM('disabled','prompt','enabled') NOT NULL DEFAULT 'prompt', - avatar_preset VARCHAR(32) NOT NULL DEFAULT 'modern_01', + avatar_preset VARCHAR(32) NOT NULL DEFAULT 'modern_001', avatar_skin_tone VARCHAR(24) NOT NULL DEFAULT 'warm', avatar_hair_style VARCHAR(24) NOT NULL DEFAULT 'short', avatar_hair_color VARCHAR(24) NOT NULL DEFAULT 'brown', diff --git a/src/App/AccountPages.php b/src/App/AccountPages.php index 3670e96..c93d88c 100755 --- a/src/App/AccountPages.php +++ b/src/App/AccountPages.php @@ -338,7 +338,7 @@ final class AccountPages 'email' => '', 'contact_phone' => '', 'location_tracking_preference' => 'prompt', - 'avatar_preset' => 'modern_01', + 'avatar_preset' => 'modern_001', 'avatar_skin_tone' => 'warm', 'avatar_hair_style' => 'short', 'avatar_hair_color' => 'brown', @@ -421,6 +421,8 @@ final class AccountPages $section = 'profile'; } $avatarOptions = Avatar::options(); + $avatarPresetOptions = Avatar::presetOptions(); + $avatarPresetGroups = Avatar::presetGroups(); return compact( 'flash', @@ -438,6 +440,8 @@ final class AccountPages 'communityCanApply', 'communityRestrictions', 'avatarOptions', + 'avatarPresetOptions', + 'avatarPresetGroups', 'section', 'allowedSections' ); diff --git a/src/App/Avatar.php b/src/App/Avatar.php index 6b2dae9..921b4d7 100644 --- a/src/App/Avatar.php +++ b/src/App/Avatar.php @@ -8,7 +8,7 @@ final class Avatar public static function defaults(): array { return [ - 'avatar_preset' => 'modern_01', + 'avatar_preset' => 'modern_001', 'avatar_skin_tone' => 'warm', 'avatar_hair_style' => 'parted', 'avatar_hair_color' => 'brown', @@ -98,6 +98,35 @@ final class Avatar ]; } + public static function presetGroups(): array + { + return [ + 'fair' => ['label' => 'Helle Hauttöne', 'range' => [1, 20]], + 'warm' => ['label' => 'Warme Hauttöne', 'range' => [21, 40]], + 'golden' => ['label' => 'Goldene Hauttöne', 'range' => [41, 60]], + 'deep' => ['label' => 'Tiefere Hauttöne', 'range' => [61, 80]], + 'rich' => ['label' => 'Kräftige Hauttöne', 'range' => [81, 100]], + ]; + } + + public static function presetOptions(): array + { + $presets = []; + foreach (self::presetGroups() as $groupKey => $group) { + [$start, $end] = $group['range']; + for ($index = $start; $index <= $end; $index++) { + $value = sprintf('modern_%03d', $index); + $presets[$groupKey][$value] = [ + 'label' => 'Variante ' . $index, + 'group' => $groupKey, + 'image' => self::presetPublicPath($value), + ]; + } + } + + return $presets; + } + public static function selectColumns(string $alias = 'p'): string { $columns = array_keys(self::defaults()); @@ -127,8 +156,22 @@ final class Avatar public static function render(array $row, string $name = 'Mitglied', string $size = 'md'): string { $avatar = self::normalize($row); - $options = self::options(); + $presetPath = self::presetPublicPath($avatar['avatar_preset']); + if ($presetPath !== null) { + return sprintf( + '', + htmlspecialchars(implode(' ', [ + 'pkt-avatar', + 'pkt-avatar--' . preg_replace('/[^a-z0-9\-]/', '', strtolower($size)), + 'pkt-avatar--preset', + ]), ENT_QUOTES), + htmlspecialchars('Avatar von ' . $name, ENT_QUOTES), + htmlspecialchars($presetPath, ENT_QUOTES) + ); + } + + $options = self::options(); $classes = [ 'pkt-avatar', 'pkt-avatar--' . preg_replace('/[^a-z0-9\-]/', '', strtolower($size)), @@ -192,4 +235,15 @@ final class Avatar { return dirname(__DIR__, 2) . '/public/assets/avatars/layers/modern/' . $category . '/' . $variant . '.svg'; } + + public static function presetPublicPath(string $preset): ?string + { + $preset = preg_replace('/[^a-z0-9_]/', '', strtolower($preset)) ?: ''; + $file = dirname(__DIR__, 2) . '/public/assets/avatars/presets/' . $preset . '.png'; + if (!is_file($file)) { + return null; + } + + return '/assets/avatars/presets/' . $preset . '.png'; + } } diff --git a/src/App/ProfileSettings.php b/src/App/ProfileSettings.php index 0a2874e..6f13a5c 100644 --- a/src/App/ProfileSettings.php +++ b/src/App/ProfileSettings.php @@ -29,7 +29,7 @@ final class ProfileSettings } $avatarColumns = [ - 'avatar_preset' => "ALTER TABLE user_profiles ADD COLUMN avatar_preset VARCHAR(32) NOT NULL DEFAULT 'modern_01' AFTER location_tracking_preference", + 'avatar_preset' => "ALTER TABLE user_profiles ADD COLUMN avatar_preset VARCHAR(32) NOT NULL DEFAULT 'modern_001' AFTER location_tracking_preference", 'avatar_skin_tone' => "ALTER TABLE user_profiles ADD COLUMN avatar_skin_tone VARCHAR(24) NOT NULL DEFAULT 'warm' AFTER location_tracking_preference", 'avatar_hair_style' => "ALTER TABLE user_profiles ADD COLUMN avatar_hair_style VARCHAR(24) NOT NULL DEFAULT 'short' AFTER avatar_skin_tone", 'avatar_hair_color' => "ALTER TABLE user_profiles ADD COLUMN avatar_hair_color VARCHAR(24) NOT NULL DEFAULT 'brown' AFTER avatar_hair_style",