"Stimmen" verwandelt: Fans reichen selbst Testimonials ein

Nutzer-Wunsch 20.08.2026: "eine richtig geile kachel ... wo die leute mit
namen und tiktok namen mir eine nachricht schreiben können die ich in die
verwaltung kriege, und dann kann ich die ausgewählten über die
verwaltungsseite auf die website hinzufügen ... das wird mega persoenlich
zu den fans, bitte wirklich krass geil speziell."

- Neue, augenschonend gestaltete Einreich-Kachel auf stimmen.html: Name,
  TikTok-Name (optional), Nachricht -- landet NIE automatisch oeffentlich,
  sondern immer erst als Entwurf in der Verwaltung.
  Warmer Babyblau/Rosé-Farbverlauf, wandernder Lichtschein, pulsierendes
  Herz -- ersetzt die 3 ewigen "Hier steht bald..."-Platzhalterkarten.
- Neue Verwaltungs-Sektion "💬 Stimmen verwalten": Warteschlange (offene
  zuerst), Freigeben/Ablehnen/Löschen pro Eintrag.
- Freigegebene Stimmen erscheinen automatisch in einer neuen, spezielleren
  Zitat-Kartenoptik (großes Anführungszeichen, Name + TikTok-Chip) --
  Abschnitt bleibt komplett unsichtbar, solange keine einzige freigegeben
  wurde.
- Backend: neue Tabelle `testimonials` (Migration 0006), routes/
  testimonials.js (oeffentliches Einreichen + Lesen freigegebener,
  admin-Warteschlange + Status/Loeschen mit neuer TESTIMONIALS_MANAGE-
  Berechtigung). 18 automatisierte Tests gegen eine Fake-DB bestanden.
- Alles per Playwright visuell durchgespielt: leerer Zustand, Einreichen
  -> Erfolgsmeldung, freigegebene Stimmen-Anzeige, Verwaltungs-Warteschlange
  mit allen Aktionen.

Backend-Teil (server-internal/, cloudflare-worker/migrations/) noch ohne
Deploy-Zugriff -- Dogi muss ihn manuell auf dogiintern ausrollen.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-08-20 23:37:31 +02:00
co-authored by Claude Opus 5
parent 519e209bce
commit 399260b805
43 changed files with 693 additions and 275 deletions
+72
View File
@@ -3716,3 +3716,75 @@ body.start-seite .music-toggle:focus-visible {
.stream-radar-watch-btn[hidden] { display: none; }
.stream-radar-watch-btn { margin-top: 1.1rem; }
.stream-radar-hinweis { margin-top: 1rem; opacity: .8; }
/* ===================================================================
"Stimmen" — eigene Nachricht einreichen (20.08.2026, Nutzer-Wunsch:
"eine richtig geile kachel ... das wird mega persoenlich zu den fans,
bitte wirklich krass geil speziell"). Warmer Babyblau/Rosé/Lila-
Farbverlauf statt der neutralen Standardkarte, wandernder Lichtschein
am Rand (dieselbe Zwei-Ebenen-Technik wie schon an mehreren Stellen
dieses Projekts, siehe .supp-card::before) — bewusst augenschonend
(gedeckte Farben, sanfte Bewegung, respektiert reduzierte Bewegung). ================================================================= */
.stimmen-einreichen-kachel {
position: relative;
overflow: hidden;
max-width: 560px;
margin: 0 auto;
padding: 2rem 2.2rem 2.4rem;
border-radius: var(--radius);
border: 1.5px solid rgba(143, 217, 234, .35);
background:
radial-gradient(circle at 15% 0%, rgba(255, 154, 208, .1), transparent 55%),
radial-gradient(circle at 85% 100%, rgba(143, 217, 234, .1), transparent 55%),
var(--card-bg);
box-shadow: 0 24px 60px rgba(0, 0, 0, .35);
}
.stimmen-einreichen-glanz {
content: "";
position: absolute;
top: 0; left: 8%; right: 8%;
height: 1.5px;
background: linear-gradient(90deg, transparent, rgba(255, 154, 208, .9), rgba(143, 217, 234, .9), transparent);
animation: stimmen-glanz-wandert 5s ease-in-out infinite;
}
@keyframes stimmen-glanz-wandert { 0%, 100% { opacity: .4; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .stimmen-einreichen-glanz { animation: none; opacity: .7; } }
.stimmen-einreichen-kopf { text-align: center; margin-bottom: 1.6rem; }
.stimmen-einreichen-herz {
display: inline-block;
font-size: 2.4rem;
filter: drop-shadow(0 0 16px rgba(255, 154, 208, .6));
animation: stimmen-herz-puls 3s ease-in-out infinite;
}
@keyframes stimmen-herz-puls { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }
@media (prefers-reduced-motion: reduce) { .stimmen-einreichen-herz { animation: none; } }
.stimmen-einreichen-kopf h2 { margin: .5rem 0 .6rem; }
.stimmen-einreichen-kopf p { color: var(--text-muted); }
#stimmen-formular .field { margin-bottom: 1rem; }
.stimmen-erfolg { color: #baf7d6; font-size: .9rem; margin-top: 1rem; display: none; text-align: center; }
.stimmen-erfolg.zeige { display: block; }
.stimmen-fehler { color: #ff9a9a; font-size: .88rem; margin-top: 1rem; display: none; text-align: center; }
.stimmen-fehler.zeige { display: block; }
/* Freigegebene Stimmen — gehobenere Zitat-Karte statt der schlichten
.card, mit farbigem Anführungszeichen + TikTok-Chip. */
.stimmen-karte {
position: relative;
padding: 1.8rem 1.8rem 1.5rem;
border-radius: calc(var(--radius) - 4px);
border: 1px solid var(--border);
background: var(--card-bg);
}
.stimmen-karte::before {
content: "„";
position: absolute;
top: .2rem; left: 1.1rem;
font-size: 3.5rem;
font-family: Georgia, serif;
color: rgba(143, 217, 234, .35);
line-height: 1;
}
.stimmen-karte-text { position: relative; z-index: 1; margin: 1.2rem 0 1rem; line-height: 1.7; }
.stimmen-karte-fuss { display: flex; align-items: center; gap: .5rem; font-size: .88rem; }
.stimmen-karte-name { font-weight: 700; color: var(--text); }
.stimmen-karte-tiktok { color: var(--accent); font-size: .82rem; }