Files
dogfather-universe/workspace/assets/js/willkommen.js
T
DogFatherGit 4b87f27451 Niemand erfaehrt, was er nicht hat -- und die Kacheln tragen ihre Farbe
ZWEI WUENSCHE, DIE ZUSAMMENGEHOEREN: die Willkommensseite.

1. "KEINER SOLL WISSEN WAS ER NICHT SIEHT"

Filipe: "das geht keinen was an. sie sehen die sachen ja nicht weil es
sie nichts angeht und das muss auch nicht erwaehnt werden.
kontrollier das ueberall bitte."

Durchgesehen: Das Haus macht es ueberall sonst schon richtig -- der
Server antwortet mit 404 statt 403, damit ein "das darfst du nicht"
gar nicht erst verraet, dass es etwas gibt. GENAU ZWEI Stellen taten
das Gegenteil, beide auf der Willkommensseite:

  der Hinweis "Was du nicht siehst" (linke Hand),
  und in ihrer Einleitung "Was du NICHT hast: Personen anlegen,
  Rollen aendern und den vertraulichen Meldeweg".

Beide entfernt, der Hinweis mit einem Kommentar an seiner Stelle --
damit ihn niemand spaeter "nachtraegt", weil er ihn fuer vergessen
haelt. Im Kopf derselben Datei stand die Ueberlegung uebrigens schon:
"Eine Liste von Dingen, die man nicht darf, ist keine Orientierung,
sondern eine Kraenkung."

Die Pruefung verlangte bis heute das GEGENTEIL ("ihr wird gesagt, was
sie nicht hat"). Sie misst jetzt alle fuenf Rollen gegen acht Muster,
mit Gegenprobe -- das "ueberall" aus dem Auftrag.

2. DIE FARBEN DER STARTSEITE

Der Server reicht `ton` durch, die Kachel traegt `data-ton="N"`, und
start.css macht daraus `--ton`. Keine eigene Farbtabelle: Die waere
die, die beim naechsten Farbwechsel stehen bleibt -- genau das ist am
19.09. elf Seiten passiert.

Drei Stellen tragen die Farbe, keine davon eine Flaeche: das Zeichen,
eine schmale Kante links und ein leiser Schimmer in der oberen Ecke.
Eine eingefaerbte Kachelflaeche waere bunt und schlecht lesbar.

UND EIN FEHLER, DEN NUR DAS MESSEN GEZEIGT HAT: Mein erster Anlauf
setzte `--ton: var(--akzent)` als Vorgabe auf `.w-kachel`. Gleiche
Spezifitaet wie `[data-ton="N"]` in start.css -- und willkommen.css
laedt SPAETER. Ergebnis: 0 von 14 Kacheln trugen die richtige Farbe,
alle waren blau. Der Rueckfall gehoert an die Verwendung
(`var(--ton, …)`), nicht an die Deklaration. Danach: 14 von 14.

Geprueft: pruef-willkommen 67/0, pruef-css-klassen 30/0.
2026-09-22 01:43:31 +02:00

138 lines
5.1 KiB
JavaScript

/* =====================================================================
willkommen.js — die persönliche Einführung
=====================================================================
Auftrag vom 21.09.2026, Abschnitte 7 und 8.
DIESE DATEI ENTHÄLT KEINEN EINZIGEN ROLLENNAMEN und keine Liste von
Kacheln. Beides kommt vom Server, der die Rechte ohnehin kennt.
Stünde es hier, stünde es in einer Datei, die jeder herunterlädt —
und wäre am Tag nach der nächsten Änderung falsch.
Die Seite ist damit für jede Rolle dieselbe Datei und trotzdem für
jeden ein anderer Text. Genau das verlangt Abschnitt 8.
===================================================================== */
(() => {
'use strict';
const $ = (id) => document.getElementById(id);
const el = (was, klasse, text) => {
const e = document.createElement(was);
if (klasse) e.className = klasse;
if (text !== undefined) e.textContent = text;
return e;
};
/* Ein Zeichen aus dem Vorrat der Startseite, damit dieselbe Kachel
hier dasselbe Bild trägt wie dort. Fehlt es, bleibt die Stelle
leer -- lieber kein Zeichen als ein falsches. */
function zeichen(name) {
if (!name || !window.Bereiche || !window.Bereiche.zeichenBauen) return null;
try { return window.Bereiche.zeichenBauen(name); } catch (e) { return null; }
}
function kachelBauen(k) {
const a = el('a', 'w-kachel');
a.href = k.ziel;
/* Der Farbton kommt vom Server und wird hier nur gesetzt --
`[data-ton="N"]` in start.css macht daraus `--ton`. Damit traegt
jede Kachel hier genau die Farbe, die sie auf der Startseite
auch hat, ohne dass diese Datei eine einzige Farbe kennt. */
if (k.ton !== null && k.ton !== undefined) a.dataset.ton = String(k.ton);
if (k.gross) a.dataset.gross = 'ja';
const z = zeichen(k.zeichen);
if (z) {
const huelle = el('span', 'w-kachel__zeichen');
huelle.setAttribute('aria-hidden', 'true');
huelle.append(z);
a.append(huelle);
}
const text = el('span', 'w-kachel__text');
text.append(el('span', 'w-kachel__name', k.name));
if (k.unter) text.append(el('span', 'w-kachel__unter', k.unter));
/* Der lange Satz nur, wo es einen gibt. Ein leerer Absatz unter
jeder Kachel wäre ein Raster aus Lücken. */
if (k.lang) text.append(el('span', 'w-kachel__lang', k.lang));
a.append(text);
return a;
}
async function bauen() {
const laedt = $('laedt');
try {
const antwort = await fetch('/workspace/api/willkommen');
if (!antwort.ok) {
/* DER DRITTE AUSGANG: nicht "nichts da", sondern "konnte nicht
nachsehen" -- mit einem Weg zurück. */
window.ladefehler?.({ nochmal: bauen });
if (laedt) laedt.hidden = true;
$('haupt')?.removeAttribute('aria-busy');
return;
}
const d = await antwort.json();
$('gruss').textContent = d.gruss || 'Willkommen!';
document.title = `Willkommen, ${d.name} · Team Dogi`;
if (d.rollentext) {
const r = $('rollentext');
r.textContent = d.rollentext;
r.hidden = false;
}
$('einleitung-was').textContent = d.einleitung?.was || '';
$('einleitung-dazu').textContent = d.einleitung?.dazu || '';
/* ---- Die Hinweise zur Rolle ---- */
const hk = $('hinweise');
const hinweise = d.hinweise || [];
if (hinweise.length) {
hk.replaceChildren();
for (const h of hinweise) {
const k = el('div', 'w-hinweis');
k.append(el('h2', 'w-hinweis__titel', h.titel));
k.append(el('p', 'w-hinweis__text', h.text));
hk.append(k);
}
hk.hidden = false;
}
/* ---- Die Kacheln, nach Gruppen ---- */
const ziel = $('gruppen');
ziel.replaceChildren();
const gruppen = d.gruppen || [];
if (!gruppen.length) {
/* KEIN LEERER BILDSCHIRM. Das kommt vor, wenn jemand gerade
erst angelegt wurde -- dann ist das kein Fehler, sondern ein
Zustand, und er gehört erklärt. */
ziel.append(el('p', 'w-leer',
'Für dich ist im Moment noch nichts freigeschaltet. '
+ 'Sag DogFather Bescheid — das ist schnell gemacht.'));
}
for (const g of gruppen) {
const abschnitt = el('section', 'w-gruppe');
abschnitt.append(el('h3', 'w-gruppe__titel', g.name));
const raster = el('div', 'w-raster');
for (const k of (g.kacheln || [])) raster.append(kachelBauen(k));
abschnitt.append(raster);
ziel.append(abschnitt);
}
const satz = $('bereiche-satz');
if (satz && d.kachelzahl) {
satz.textContent = d.kachelzahl + (d.kachelzahl === 1
? ' Bereich ist für dich freigeschaltet — und wofür er da ist. '
: ' Bereiche sind für dich freigeschaltet — und wofür sie da sind. ')
+ 'Tipp einen an, um hinzugehen.';
}
if (laedt) laedt.hidden = true;
$('haupt')?.removeAttribute('aria-busy');
} catch (f) {
window.ladefehler?.({ nochmal: bauen });
if (laedt) laedt.hidden = true;
$('haupt')?.removeAttribute('aria-busy');
}
}
bauen();
})();