Modi-Bewerbung: vierte Kategorie neben Creator/Scout/Kooperation

- bewerben.html: neuer Reiter "Modi" mit eigenem Formular (Name, E-Mail,
  Discord/TikTok-Handle, Community-Erfahrung, Verfuegbarkeit, Motivation)
- Reiter wechselt jetzt nicht nur das Hintergrundbild, sondern auch die
  Farbwelt: Creator/Scout/Kooperation bleiben Spicy-Media-rot (Agentur),
  Modi wird babyblau (Team Dogi) -- passend zur bestehenden Regel
  "Rot ist NUR die Agentur"
- Direkt-Link bewerben.html#modi oeffnet die Bewerbung gleich auf dem
  richtigen Reiter; team-modis.html hat jetzt einen "Als Modi bewerben"
  Knopf, der genau dahin fuehrt
- Worker: "modi" als vierter erlaubter Bewerbungstyp, laeuft ueber
  dieselbe Sichtbarkeits-Berechtigung wie Scout/Kooperation (der feste
  Rechte-Katalog aus dem Anforderungsdokument kennt nur zwei Bewerbungs-
  Sichtbereiche -- es wurde bewusst KEIN neuer Permission-Key erfunden)

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-07-31 22:16:57 +02:00
co-authored by Claude Opus 5
parent 823ff52903
commit 755d0c7a0e
4 changed files with 72 additions and 17 deletions
+25 -11
View File
@@ -22,6 +22,7 @@ const CONTACT_EMAIL = "[email protected]"; // TODO: echte Konta
const FORM_TYPES = { const FORM_TYPES = {
"form-creator": "creator", "form-creator": "creator",
"form-scout": "scout", "form-scout": "scout",
"form-modi": "modi",
"form-kooperation": "kooperation", "form-kooperation": "kooperation",
}; };
@@ -108,21 +109,27 @@ function setupForm(formId, subjectLabel) {
}); });
} }
/* Der Kopfbereich wechselt sein Hintergrundbild mit dem gewählten Reiter: /* Der Kopfbereich wechselt Hintergrundbild, Welt-Farbe (Theme) und Eyebrow-
Creator bekommt sein eigenes Motiv, Scout und Kooperation das Text mit dem gewählten Reiter: Creator/Scout/Kooperation sind Spicy-Media-
Spicy-Media-Motiv. So passt das Bild immer zur gewählten Bewerbung. */ Agentur (rot), Modi ist Dogfathers persönliches Team (babyblau) — genau
wie überall sonst auf der Seite (Rot = NUR Agentur). So passt Bild UND
Farbwelt immer zur gerade gewählten Bewerbung. */
const TAB_HINTERGRUENDE = { const TAB_HINTERGRUENDE = {
"tab-creator": "bg-bewerben-creator", "tab-creator": { bg: "bg-bewerben-creator", theme: "spicymedia", eyebrow: "Manager Dogfather" },
"tab-scout": "bg-bewerben", "tab-scout": { bg: "bg-bewerben", theme: "spicymedia", eyebrow: "Manager Dogfather" },
"tab-kooperation": "bg-bewerben", "tab-modi": { bg: "bg-dogfather", theme: "dogfather", eyebrow: "🩵 Team Dogi" },
"tab-kooperation": { bg: "bg-bewerben", theme: "spicymedia", eyebrow: "Manager Dogfather" },
}; };
function setzeTabHintergrund(tabId) { function setzeTabHintergrund(tabId) {
const basis = TAB_HINTERGRUENDE[tabId]; const einstellung = TAB_HINTERGRUENDE[tabId];
if (!basis) return; if (!einstellung) return;
// Die Bildvariablen hängen am <body> — das Motiv trägt die ganze Seite. // Die Bildvariablen hängen am <body> — das Motiv trägt die ganze Seite.
document.body.style.setProperty("--page-bg", `url('/assets/img/${basis}.jpg')`); document.body.style.setProperty("--page-bg", `url('/assets/img/${einstellung.bg}.jpg')`);
document.body.style.setProperty("--page-bg-mobile", `url('/assets/img/${basis}-mobile.jpg')`); document.body.style.setProperty("--page-bg-mobile", `url('/assets/img/${einstellung.bg}-mobile.jpg')`);
document.documentElement.setAttribute("data-theme", einstellung.theme);
const eyebrow = document.getElementById("bewerben-eyebrow");
if (eyebrow) eyebrow.textContent = einstellung.eyebrow;
} }
function setupTabs() { function setupTabs() {
@@ -138,7 +145,13 @@ function setupTabs() {
}); });
}); });
// Beim Laden passend zum bereits aktiven Reiter setzen // Direkt-Link auf einen Reiter, z.B. bewerben.html#modi von der Modi-
// Team-Seite aus — öffnet die Bewerbung gleich auf dem richtigen Tab.
const gewuenscht = location.hash.replace("#", "");
const linkBtn = gewuenscht && document.querySelector(`.tab-btn[data-tab="tab-${gewuenscht}"]`);
if (linkBtn) linkBtn.click();
// Beim Laden passend zum aktiven Reiter setzen (bereits aktiv ODER gerade per Hash geöffnet)
const aktiv = document.querySelector(".tab-btn.active"); const aktiv = document.querySelector(".tab-btn.active");
if (aktiv) setzeTabHintergrund(aktiv.dataset.tab); if (aktiv) setzeTabHintergrund(aktiv.dataset.tab);
} }
@@ -147,5 +160,6 @@ document.addEventListener("DOMContentLoaded", () => {
setupTabs(); setupTabs();
setupForm("form-creator", "Creator"); setupForm("form-creator", "Creator");
setupForm("form-scout", "Scout"); setupForm("form-scout", "Scout");
setupForm("form-modi", "Modi");
setupForm("form-kooperation", "Kooperation"); setupForm("form-kooperation", "Kooperation");
}); });
+39 -5
View File
@@ -4,17 +4,17 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bewerben — DOGFATHER UNIVERSE</title> <title>Bewerben — DOGFATHER UNIVERSE</title>
<meta name="description" content="Bewirb dich als Creator, Scout oder für eine Kooperation bei Spicy Media / Team Dogi." /> <meta name="description" content="Bewirb dich als Creator, Scout, Modi oder für eine Kooperation bei Team Dogi / Spicy Media." />
<link rel="icon" type="image/png" href="assets/img/favicon.png" /> <link rel="icon" type="image/png" href="assets/img/favicon.png" />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:site_name" content="DOGFATHER UNIVERSE" /> <meta property="og:site_name" content="DOGFATHER UNIVERSE" />
<meta property="og:title" content="Bewerben — DOGFATHER UNIVERSE" /> <meta property="og:title" content="Bewerben — DOGFATHER UNIVERSE" />
<meta property="og:description" content="Bewirb dich als Creator, Scout oder für eine Kooperation bei Spicy Media / Team Dogi." /> <meta property="og:description" content="Bewirb dich als Creator, Scout, Modi oder für eine Kooperation bei Team Dogi / Spicy Media." />
<meta property="og:image" content="https://REPLACE-WITH-YOUR-DOMAIN.tld/assets/img/og-cover.jpg" /> <meta property="og:image" content="https://REPLACE-WITH-YOUR-DOMAIN.tld/assets/img/og-cover.jpg" />
<meta property="og:url" content="https://REPLACE-WITH-YOUR-DOMAIN.tld/bewerben.html" /> <meta property="og:url" content="https://REPLACE-WITH-YOUR-DOMAIN.tld/bewerben.html" />
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Bewerben — DOGFATHER UNIVERSE" /> <meta name="twitter:title" content="Bewerben — DOGFATHER UNIVERSE" />
<meta name="twitter:description" content="Bewirb dich als Creator, Scout oder für eine Kooperation bei Spicy Media / Team Dogi." /> <meta name="twitter:description" content="Bewirb dich als Creator, Scout, Modi oder für eine Kooperation bei Team Dogi / Spicy Media." />
<meta name="twitter:image" content="https://REPLACE-WITH-YOUR-DOMAIN.tld/assets/img/og-cover.jpg" /> <meta name="twitter:image" content="https://REPLACE-WITH-YOUR-DOMAIN.tld/assets/img/og-cover.jpg" />
<link rel="stylesheet" href="assets/css/main.css" /> <link rel="stylesheet" href="assets/css/main.css" />
@@ -28,9 +28,9 @@
<main> <main>
<section class="hero page-bg"> <section class="hero page-bg">
<div class="container"> <div class="container">
<span class="eyebrow">Manager Dogfather</span> <span class="eyebrow" id="bewerben-eyebrow">Manager Dogfather</span>
<h1>Werde Teil vom Team</h1> <h1>Werde Teil vom Team</h1>
<p class="lead worlds">Als Creator, Scout oder Kooperationspartner.</p> <p class="lead worlds">Als Creator, Scout, Modi oder Kooperationspartner.</p>
</div> </div>
</section> </section>
@@ -39,6 +39,7 @@
<div class="tabs"> <div class="tabs">
<button class="tab-btn active" data-tab="tab-creator">Creator</button> <button class="tab-btn active" data-tab="tab-creator">Creator</button>
<button class="tab-btn" data-tab="tab-scout">Scout</button> <button class="tab-btn" data-tab="tab-scout">Scout</button>
<button class="tab-btn" data-tab="tab-modi">Modi</button>
<button class="tab-btn" data-tab="tab-kooperation">Kooperation</button> <button class="tab-btn" data-tab="tab-kooperation">Kooperation</button>
</div> </div>
@@ -91,6 +92,39 @@
</form> </form>
</div> </div>
<div class="tab-panel" id="tab-modi">
<form class="app-form" id="form-modi" novalidate>
<div class="field">
<label for="m-name">Name *</label>
<input id="m-name" name="name" type="text" required />
</div>
<div class="field">
<label for="m-email">E-Mail *</label>
<input id="m-email" name="email" type="email" required />
<span class="error-msg">Bitte gültige E-Mail-Adresse eingeben.</span>
</div>
<div class="field">
<label for="m-kontakt">Discord- oder TikTok-Handle *</label>
<input id="m-kontakt" name="kontakt" type="text" placeholder="z.B. Discord: dein-tag" required />
</div>
<div class="field">
<label for="m-erfahrung">Hast du schon Erfahrung als Moderator:in / in einer Community? *</label>
<textarea id="m-erfahrung" name="erfahrung" required></textarea>
</div>
<div class="field">
<label for="m-verfuegbarkeit">Wie viel Zeit kannst du pro Woche investieren? *</label>
<input id="m-verfuegbarkeit" name="verfuegbarkeit" type="text" required />
</div>
<div class="field">
<label for="m-warum">Warum willst du Modi bei Team Dogi werden? *</label>
<textarea id="m-warum" name="warum" required></textarea>
</div>
<p class="small muted">Modis sind Dogfathers persönliches Team — Chat, Community und Zusammenhalt im Alltag. 🩵</p>
<button class="btn btn-primary" type="submit">Bewerbung als Modi senden</button>
<div class="form-status"></div>
</form>
</div>
<div class="tab-panel" id="tab-kooperation"> <div class="tab-panel" id="tab-kooperation">
<form class="app-form" id="form-kooperation" novalidate> <form class="app-form" id="form-kooperation" novalidate>
<div class="field"> <div class="field">
+5 -1
View File
@@ -8,7 +8,7 @@ import { hasPermission } from "../lib/permissions.js";
import { logAction } from "../lib/audit.js"; import { logAction } from "../lib/audit.js";
import { json } from "../lib/http.js"; import { json } from "../lib/http.js";
const ALLOWED_TYPES = ["creator", "scout", "kooperation"]; const ALLOWED_TYPES = ["creator", "scout", "kooperation", "modi"];
function can(session, key) { function can(session, key) {
if (!session) return false; if (!session) return false;
@@ -17,6 +17,10 @@ function can(session, key) {
} }
function viewPermissionForType(type) { function viewPermissionForType(type) {
// Der Rechte-Katalog kommt fest aus dem Anforderungsdokument und kennt nur
// zwei Bewerbungs-Sichtbereiche (Creator / "Rest"). Scout, Kooperation und
// Modi laufen deshalb alle über APPLICATIONS_VIEW_MANAGER_SCOUT — es wird
// bewusst KEIN neuer Permission-Key erfunden, der nicht im Dokument steht.
return type === "creator" ? "APPLICATIONS_VIEW_CREATOR" : "APPLICATIONS_VIEW_MANAGER_SCOUT"; return type === "creator" ? "APPLICATIONS_VIEW_CREATOR" : "APPLICATIONS_VIEW_MANAGER_SCOUT";
} }
+3
View File
@@ -55,6 +55,9 @@
<div id="modis-grid" class="grid grid-4"></div> <div id="modis-grid" class="grid grid-4"></div>
<!-- TODO: Hinweis: Reihenfolge/Rollen basieren auf: VanVan (rechte Hand) → Diene (rechte Hand von VanVan) → Funny (Modi) → Miss (Modi + Cutterin) → Marina/Michi (Clip-Account-Kommentare). Änderungen einfach in assets/js/data-modis.js pflegen. --> <!-- TODO: Hinweis: Reihenfolge/Rollen basieren auf: VanVan (rechte Hand) → Diene (rechte Hand von VanVan) → Funny (Modi) → Miss (Modi + Cutterin) → Marina/Michi (Clip-Account-Kommentare). Änderungen einfach in assets/js/data-modis.js pflegen. -->
<div class="btn-row" style="justify-content:center;">
<a class="btn btn-primary" href="bewerben.html#modi">Als Modi bewerben 🩵</a>
</div>
</div> </div>
</section> </section>
</main> </main>