Verwaltungsseite perfektioniert: Team-Verwaltung für Modis/Scouts/Creator/Manager

Nutzer-Wunsch 21.08.2026: "überall wo Modis sind oder Scouts oder
Manager, oder Creator, will ich dass ich die easy über meine
Verwaltungsseite hinzufüge und die automatisch in der Website
hinzugefügt werden ... auch mit Fotos und TikTok Link."

Backend (server-internal, braucht Filipes manuellen Deploy):
- Neue Tabelle team_members (Migration 0007) für alle vier Kategorien
  gemeinsam -- ergänzt, überschreibt NIE die von Hand gepflegten
  Einträge in data-modis.js/data-scouts.js/data-creator.js.
- routes/team.js: öffentliches Lesen (nur aktive Mitglieder, optional
  nach Kategorie gefiltert), TEAM_MANAGE-geschütztes Anlegen/Bearbeiten/
  Löschen, Foto-Upload (gleiches Muster wie "Event des Jahres"),
  automatische Übersetzung von Rolle/Bio/Zitat wie bei anderen
  admin-gepflegten Texten. Slug global eindeutig (mit automatischer
  Kollisionsauflösung), TikTok-Kurzname wird zu voller URL ergänzt.
  27 Tests in isolierter Testumgebung geprüft (kein better-sqlite3
  lokal kompilierbar).

Frontend:
- window.dogiTeamLaden() in main.js: holt admin-gepflegte Mitglieder
  einer (oder aller) Kategorien und bringt sie in exakt dieselbe Form
  wie die bestehenden data-*.js-Einträge.
- team-scouts.html/team-modis.html/creator.html hängen das Ergebnis
  einfach an ihre bestehenden Arrays an und rendern erneut -- exakt
  derselbe Look wie die schon bestehenden Profile (Foto/Avatar-Initiale,
  Rolle, Zitat, TikTok-Button). creator.html hatte bisher ein "return"
  bei leerem CREATORS-Array, wodurch admin-Creator NIE geladen worden
  wären -- gefixt. team-modis.html berücksichtigt Rang/Rang-Bezeichnung
  für die Pyramide.
- Neue Sektion "Weitere Manager" auf manager.html, komplett unsichtbar
  bis der erste Manager angelegt wird (data-manager.js neu, wie
  data-creator.js aktuell leer).
- profil.html sucht jetzt kategorieübergreifend auch in admin-gepflegten
  Profilen, inkl. korrektem Theme/Zurück-Link auch für Manager.

Verwaltung: neue Sektion "Team verwalten" (TEAM_MANAGE-Berechtigung) --
ein Formular für alle vier Kategorien mit Foto-Sofort-Upload,
TikTok-Feld, Bio/Zitat, bedingten Rang-Feldern (nur Modi), Kategorie-
Filterleiste und Bearbeiten/Löschen pro Eintrag.

Beim Testen mit Playwright einen echten Syntaxfehler gefunden und
gefixt (ASCII-Anführungszeichen statt schließendem „" in einem
Statustext), der das GESAMTE Verwaltungs-Skript und damit die komplette
Seite lahmgelegt hätte.

Cache-Busting-Version auf 20260821j erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-08-21 03:06:21 +02:00
co-authored by Claude Sonnet 5
parent 8ead1b750b
commit 7060a4a6ae
45 changed files with 1077 additions and 247 deletions
+18
View File
@@ -0,0 +1,18 @@
/* =====================================================================
data-manager.js — Manager-Datenobjekt (21.08.2026)
DogFather (Filipe) selbst hat weiterhin seine eigene, feste Seite
(manager.html) — dieses Array ist für WEITERE Manager gedacht, die
künftig dazukommen könnten (siehe zeitreise.html, "Aufbau eines
eigenen Creator-Systems": "Eine langfristige Struktur für Creator,
Scouts und zukünftige Manager"). Noch niemand final geklärt, deshalb
bewusst leer — genau wie data-creator.js, bis echte Namen feststehen.
Einfach nach dem Muster in data-scouts.js Objekte ins Array einfügen,
sobald es so weit ist — manager.html liest automatisch aus.
Felder: siehe data-scouts.js (identisches Muster).
===================================================================== */
const MANAGERS = [];
if (typeof window !== "undefined") window.MANAGERS = MANAGERS;
+7
View File
@@ -39,6 +39,13 @@ window.I18N_PAGE = {
de: "Profil ansehen", "de-CH": "Profil aluege",
en: "View profile", fr: "Voir le profil", pt: "Ver perfil",
},
/* 21.08.2026: Fallback-Kategorie für über die Verwaltung angelegte
Creator ohne eigenes Genre (die Verwaltung fragt aktuell keine
Genre-Kategorie ab) -- verhindert einen "undefined"-Filterknopf. */
crt_kategorie_sonstige: {
de: "Sonstige", "de-CH": "Anders",
en: "Other", fr: "Autre", pt: "Outro",
},
crt_bewerben_btn: {
de: "Als Creator bewerben", "de-CH": "Als Creator bewärbe",
en: "Apply as a creator", fr: "Postuler comme créateur", pt: "Candidatar-se como creator",
+12
View File
@@ -177,4 +177,16 @@ window.I18N_PAGE = {
fr: "Les scouts trouvent et accompagnent de nouveaux talents pour Dogi.",
pt: "Os scouts encontram e acompanham novos talentos para o Dogi.",
},
/* 21.08.2026: Abschnitt für weitere, über die Verwaltung angelegte Manager
(siehe zeitreise.html, "Aufbau eines eigenen Creator-Systems" ->
"zukünftige Manager"). Bleibt komplett unsichtbar, solange keiner
eingetragen ist -- siehe renderWeitereManager() weiter unten. */
mgr_weitere_h2: {
de: "Weitere Manager", "de-CH": "Witeri Manager",
en: "More Managers", fr: "Autres managers", pt: "Outros managers",
},
mgr_weitere_profil_btn: {
de: "Profil ansehen", "de-CH": "Profil aluege",
en: "View profile", fr: "Voir le profil", pt: "Ver perfil",
},
};
+8
View File
@@ -30,6 +30,10 @@ window.I18N_PAGE = {
de: "Manager DogFather — Creator", "de-CH": "Manager DogFather — Creator",
en: "Manager DogFather — Creator", fr: "Manager DogFather — Creator", pt: "Manager DogFather — Creator",
},
pr_eyebrow_manager: {
de: "Manager DogFather — Spicy Media", "de-CH": "Manager DogFather — Spicy Media",
en: "Manager DogFather — Spicy Media", fr: "Manager DogFather — Spicy Media", pt: "Manager DogFather — Spicy Media",
},
pr_back_modis: {
de: "← Zurück zum Modi-Team", "de-CH": "← Zrugg zum Modi-Team",
en: "← Back to the Modi Team", fr: "← Retour à l'équipe Modi", pt: "← Voltar à equipe Modi",
@@ -42,6 +46,10 @@ window.I18N_PAGE = {
de: "← Zurück zu den Creatorn", "de-CH": "← Zrugg zu de Creator",
en: "← Back to the Creators", fr: "← Retour aux Creators", pt: "← Voltar aos Creators",
},
pr_back_manager: {
de: "← Zurück zu Manager DogFather", "de-CH": "← Zrugg zu Manager DogFather",
en: "← Back to Manager DogFather", fr: "← Retour à Manager DogFather", pt: "← Voltar a Manager DogFather",
},
pr_badge_prefix: {
de: "Stufe", "de-CH": "Stuefe",
en: "Level", fr: "Niveau", pt: "Nível",
+51
View File
@@ -1154,6 +1154,57 @@
return feld[sprache] || feld.de || "";
};
/* =====================================================================
dogiTeamLaden() — 21.08.2026, Nutzer-Wunsch: "überall wo Modis sind
oder Scouts oder Manager, oder Creator, will ich dass ich die easy
über meine Verwaltungsseite hinzufüge und die automatisch in der
Website hinzugefügt werden ... auch mit Fotos und TikTok Link."
Holt die über die Verwaltung angelegten Team-Mitglieder einer
Kategorie ("modi" | "scout" | "creator" | "manager") vom Server und
bringt sie in GENAU dieselbe Objektform wie die von Hand gepflegten
Einträge in data-modis.js/data-scouts.js/data-creator.js/
data-manager.js (name/slug/role/photo/bio/quote/social/...) — die
aufrufende Seite hängt das Ergebnis einfach hinten an ihr bestehendes
window.MODIS/SCOUTS/CREATORS/MANAGERS-Array an und ruft ihre eigene,
unveränderte Render-Funktion erneut auf. Kein kategorie-Parameter
liefert ALLE Kategorien zusammen (genutzt von profil.html, das vorab
nicht weiß, zu welcher Kategorie ein slug gehört).
Schlägt die Anfrage fehl (Server nicht erreichbar, Netz weg): leeres
Array statt Fehler -- die von Hand gepflegten Einträge bleiben davon
komplett unberührt sichtbar, nur admin-gepflegte kommen dann halt
(vorübergehend) nicht hinzu. */
const TEAM_API_BASIS = "https://postfach.dogfather-universe.com";
window.dogiTeamLaden = async function (kategorie) {
try {
const url = kategorie ? `${TEAM_API_BASIS}/team?kategorie=${encodeURIComponent(kategorie)}` : `${TEAM_API_BASIS}/team`;
const res = await fetch(url, { cache: "no-store" });
const data = await res.json();
if (!data || !data.ok || !Array.isArray(data.mitglieder)) return [];
return data.mitglieder.map((m) => ({
name: m.name,
slug: m.slug,
kategorie: m.kategorie,
role: m.rolle || "",
photo: m.foto || "",
avatar: m.foto || "",
bio: m.bio || "",
quote: m.zitat || "",
social: m.tiktok ? { tiktok: m.tiktok } : {},
status: "aktiv", // /team liefert ohnehin nur aktive Mitglieder
rank: m.rang || undefined,
rankLabel: m.rangLabel || undefined,
// Markiert admin-gepflegte Einträge (z.B. für profil.html, das
// sonst nicht zwischen fest einprogrammierten und dynamischen
// Personen unterscheiden könnte).
istAdminGepflegt: true,
}));
} catch {
return [];
}
};
/* ===================================================================
PWA: Service-Worker-Registrierung
Voraussetzung dafür, dass Chrome/Edge auf dem Desktop "App