Kampagnen-Kacheln: gegliederte Texte, Geschenke mit Preis, aufklappbar
Filipe, mit einem Bildschirmfoto des Regelblocks: "man soll die titel
in den texten besser erkennen und sehen was zu was passt. ich will
auch dass man sieht welche geschenke bei dem event zaehlen und so.
ich will alle informationen die moeglich sind wenn man den link
hochlaedt. ... auch wenn man teilt soll es einfach perfekt sein. man
soll alle infos sehen die man braucht. die kacheln von den events
soll auch nicht so lang sein, die soll man aufklappen koennen. genau
wie eine trennung fuer heute, letzte woche letzten monat und so."
DER FEHLER LAG NICHT IM TEXT, SONDERN IN SEINER ANZEIGE. Im Feld
stand die ganze Zeit eine Gliederung -- Hinweise mit "* ", eine
Ueberschrift mit Untertitel hinter einem Gedankenstrich, Absaetze
ohne Zeichen, Aufzaehlungen mit "- ". Die Kachel hat daraus mit
punkteAusText() EINE flache Liste gemacht: jede Zeile derselbe
Strich, alle gleich gross.
gliederung() liest die Gliederung, die schon dasteht, statt
den Text umzuschreiben. Die beiden Kampagnen, die
heute in der Datenbank liegen, sehen dadurch
sofort richtig aus -- ohne Umstellung.
Geschenke kommen aus der gelesenen LISTE, nicht aus dem
Text, und stehen OHNE Aufklappen auf der Kachel.
Aufklappen alles Uebrige hinter einem Druck: gemessen 555 px
weniger je Kachel bei Gipfelstuermer.
Gruppen je Spalte laeuft / kommt / vorbei, Vergangenes
nach diese Woche, dieser Monat, aelter.
NEU GELESEN (stand in allen vier gespeicherten Seiten und wurde nie
angesehen): die Rangliste mit ihren Gruppen ("Superstars" bis
"5. Liga", bei Glow Up "Team Glow"/"Team Shine"), die Beschreibung je
Missionsgruppe, der Steckbrief (Kurznummer, Markt, Sprache, Zone),
der zweite Bildbaustein, und Ueberschriften INNERHALB der Klapptexte
-- "WELCHE LIGA BIN ICH?" hat jetzt sechs eingerueckte Unterpunkte
statt zwoelf gleichrangiger Zeilen.
EVENT_TEXT_MAX 6000 -> 20000. Der Regeltext von Gipfelstuermer ist
7679 Zeichen lang; es fielen bisher jedes Mal rund 1600 Zeichen
echter Inhalt weg. Die Zahl steht jetzt an EINER Stelle.
TEILEN: Was die KAMPAGNE sagt, geht hinaus (Aufgaben, Geschenke,
Regeln) -- wer WIR sind, nicht (Name, Rolle, Haus, Kampagnennummer,
Steckbrief). Und keine Hinweiszeile: "Die Preise konnten nicht
gelesen werden -- bitte nachtragen" ist eine Notiz an DogFather und
hat auf einer Seite, die er in Discord postet, nichts zu suchen.
BERICHTIGT, WEIL NACHGEMESSEN:
- Number(null) ist 0 und 0 ist endlich -- "Feuerwerk" bekam an drei
Stellen "0 Coins" angeschrieben, also eine falsche Preisangabe.
- Ein Kommentar im Leser behauptete, der Wertungszeitraum weiche
vom Kampagnenzeitraum ab. Nachgemessen ist er in allen drei
Seiten mit Rangliste auf die Millisekunde gleich; ich hatte zwei
verschiedene Kampagnen verglichen.
- bild-kampagne.mjs verlangte "jede Kachel traegt den Ton ihrer
Seite" und war damit seit dem 07.10. rot, weil an dem Tag bewusst
das Gegenteil entschieden wurde (Zustandston, Seitenkante). Nicht
aufgefallen, weil nach dem Lauf nur die Zahl der MESSUNGEN notiert
wurde, nicht die der FEHLER.
- .kv-seite > .eintrag-karte wird .kv-seite .eintrag-karte: Die
Karten haengen durch die Gruppen eine Ebene tiefer. Das waere der
fuenfte Direktkind-Selektor gewesen, der nach einem Umbau still
ausfaellt -- diesmal vorher gesehen.
GEPRUEFT: 186 (lesen, +58), 148 (Route/Teilen, +25), 158 (Kachel,
+64), 67 (Agentur, +5), 67 Messungen (Bild, +14), dazu struktur,
css-klassen, zeichen, deutsche-texte, tippziele, lesbarkeit und
haus-trennung (107, unveraendert). Sechs Gegenproben: alle sechs
Sabotagen werden bemerkt, alle Dateien byte-gleich wiederhergestellt.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
+394
-25
@@ -375,6 +375,61 @@
|
||||
}
|
||||
|
||||
|
||||
/* ==== IN WELCHE GRUPPE EINER SPALTE GEHOERT DIESES EVENT? ====
|
||||
|
||||
Filipe: „genau wie eine trennung fuer heute, letzte woche
|
||||
letzten monat und so."
|
||||
|
||||
DIE ERSTE FRAGE AN EIN EVENT IST NICHT SEIN ALTER, SONDERN
|
||||
SEIN ZUSTAND. „Laeuft gerade" und „ist vorbei" entscheiden,
|
||||
ob man heute etwas tut; ob es vorgestern oder vorletzten
|
||||
Monat vorbei war, entscheidet nichts mehr. Deshalb zuerst
|
||||
laeuft / kommt / vorbei.
|
||||
|
||||
DAS ALTER TEILT DANN DAS AUF, WAS SICH ANSAMMELT -- und das
|
||||
ist genau eines: das Vergangene. Von „laeuft gerade" gibt es
|
||||
nie viele, von „vorbei" mit der Zeit beliebig viele. Genau
|
||||
dort setzt Filipes Wunsch an, und nur dort traegt er etwas.
|
||||
|
||||
GERECHNET WIRD AUF DEM ENDE, nicht auf dem Anlagedatum: Ein
|
||||
Event, das letzte Woche angelegt wurde und naechsten Monat
|
||||
endet, ist nicht „letzte Woche".
|
||||
|
||||
KALENDERBEZOGEN, NICHT IN TAGEN GEZAEHLT -- dieselbe
|
||||
Ueberlegung wie bei ZEITSTUFEN weiter unten: „diese Woche"
|
||||
heisst seit Montag. Am Dienstag ist der Freitag davor nicht
|
||||
„diese Woche".
|
||||
|
||||
EINE LEERE GRUPPE ERSCHEINT NICHT (siehe `continue` beim
|
||||
Bauen) -- fuenf leere Ueberschriften waeren schlimmer als
|
||||
eine lange Spalte. */
|
||||
const EV_GRUPPEN = [
|
||||
['laeuft', 'Läuft gerade', false],
|
||||
['kommt', 'Kommt noch', false],
|
||||
['vorbei_woche', 'Vorbei — diese Woche', true],
|
||||
['vorbei_monat', 'Vorbei — dieser Monat', true],
|
||||
['vorbei_alt', 'Vorbei — älter', true],
|
||||
];
|
||||
|
||||
function evGruppeVon(e) {
|
||||
const st = eventStand(e);
|
||||
if (!st) return 'vorbei_alt';
|
||||
if (st.schluessel !== 'vorbei') return st.schluessel;
|
||||
const heute = window.heuteLokal
|
||||
? window.heuteLokal() : new Date().toISOString().slice(0, 10);
|
||||
const tag = new Date(heute + 'T00:00:00');
|
||||
const ende = new Date(String(e.event_ende || e.datum || '').slice(0, 10) + 'T00:00:00');
|
||||
if (Number.isNaN(ende.getTime()) || Number.isNaN(tag.getTime())) return 'vorbei_alt';
|
||||
/* Montag als Wochenanfang -- getDay() liefert Sonntag = 0, und
|
||||
in Deutschland steht der am Ende. */
|
||||
const montag = new Date(tag);
|
||||
montag.setDate(tag.getDate() - ((tag.getDay() + 6) % 7));
|
||||
if (ende >= montag) return 'vorbei_woche';
|
||||
const ersterDesMonats = new Date(tag.getFullYear(), tag.getMonth(), 1);
|
||||
if (ende >= ersterDesMonats) return 'vorbei_monat';
|
||||
return 'vorbei_alt';
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
WIE LANGE NOCH? (03.10.2026)
|
||||
|
||||
@@ -798,6 +853,30 @@
|
||||
kopf.append(zaehler);
|
||||
block.append(kopf);
|
||||
|
||||
/* WAS ZU EINER AUFGABE NOCH DASTEHT (07.10.2026).
|
||||
|
||||
Bei „LIVE Glow Up" hat jede Missionsgruppe eine eigene
|
||||
Beschreibung (`displayInfo.descText`) und einen eigenen
|
||||
Zeitraum (`config[0].startTime/endTime`) -- beides stand in
|
||||
der Kampagnenseite und wurde bis heute nicht gelesen. Es
|
||||
gehoert UNTER die Aufgabe, nicht in den Regeltext: „Erfuelle
|
||||
diese Missionen taeglich" ist eine Auskunft ueber DIESE
|
||||
Aufgabe.
|
||||
|
||||
NICHT IN DEN KNOPF. Der Knopf ist die Beschriftung des
|
||||
Hakens; was darunter steht, hakt man nicht ab. Wer auf die
|
||||
Beschreibung tippt, soll nichts umschalten. */
|
||||
const zusatzAnhaengen = (zeile, p) => {
|
||||
if (!p.beschreibung && !(p.von_tag && p.bis_tag)) return;
|
||||
const z = el('div', 'ev-punkt__zusatz');
|
||||
if (p.von_tag && p.bis_tag) {
|
||||
z.append(el('span', 'ev-punkt__spanne',
|
||||
datum(p.von_tag) + ' – ' + datum(p.bis_tag)));
|
||||
}
|
||||
if (p.beschreibung) z.append(el('span', 'ev-punkt__worte', p.beschreibung));
|
||||
zeile.append(z);
|
||||
};
|
||||
|
||||
const liste = el('ul', 'ev-liste');
|
||||
for (const p of punkte) {
|
||||
const zeile = el('li', 'ev-punkt');
|
||||
@@ -807,6 +886,7 @@
|
||||
zeile.dataset.abgehakt = p.meiner ? 'ja' : '';
|
||||
zeile.append(el('span', 'ev-punkt__kaestchen'));
|
||||
zeile.append(el('span', 'ev-punkt__text', p.text));
|
||||
zusatzAnhaengen(zeile, p);
|
||||
liste.append(zeile);
|
||||
continue;
|
||||
}
|
||||
@@ -851,6 +931,7 @@
|
||||
} finally { knopf.disabled = false; }
|
||||
});
|
||||
zeile.append(knopf);
|
||||
zusatzAnhaengen(zeile, p);
|
||||
liste.append(zeile);
|
||||
}
|
||||
block.append(liste);
|
||||
@@ -873,30 +954,229 @@
|
||||
return block;
|
||||
}
|
||||
|
||||
/** Die Regeln -- dieselbe Liste, aber ohne Haken.
|
||||
/* =====================================================================
|
||||
DIE INFOS EINER KACHEL -- GEGLIEDERT STATT FLACH (07.10.2026)
|
||||
|
||||
Filipe, mit einem Bildschirmfoto des Regelblocks: „man soll die
|
||||
titel in den texten besser erkennen und sehen was zu was passt.
|
||||
ich will auch dass man sieht welche geschenke bei dem event
|
||||
zaehlen und so. ... die kacheln von den events soll auch nicht
|
||||
so lang sein, die soll man aufklappen koennen."
|
||||
|
||||
HIER STAND EINE EINZIGE FLACHE LISTE. Jede Zeile derselbe
|
||||
Strich, gleiche Groesse, gleiche Farbe -- „INFOS ZUR KAMPAGNE"
|
||||
sah aus wie der Absatz darunter, und die Hinweise („Diese
|
||||
Kampagne hat keine Preisliste") standen zwischen den Regeln,
|
||||
als waeren sie welche.
|
||||
|
||||
DIE GLIEDERUNG KOMMT VOM SERVER (`event_regelabschnitte`, aus
|
||||
`gliederung()` in kampagne-lesen.mjs). Hier wird nur gemalt --
|
||||
und zwar genau einmal im Haus: Die Teilen-Seite benutzt
|
||||
dieselbe Zerlegung. Haetten Kachel und Teilen-Seite je ihre
|
||||
eigene, wuerden sie irgendwann Verschiedenes zeigen, und
|
||||
niemand koennte sagen, welche von beiden recht hat.
|
||||
|
||||
DREI SORTEN INHALT, DREI ORTE:
|
||||
Geschenke immer sichtbar, als Plaketten mit Coinpreis --
|
||||
das ist die Frage, die am haeufigsten gestellt
|
||||
wird, und sie passt in eine Zeile.
|
||||
Hinweise immer sichtbar, aber still und abgesetzt. „Die
|
||||
Preise konnten nicht gelesen werden -- bitte
|
||||
nachtragen" ist eine Aufgabe; sie hinter einen
|
||||
Druck zu legen heisst, sie zu verstecken.
|
||||
Alles Uebrige hinter EINEM Druck. Bei „Gipfelstuermer" sind
|
||||
das rund 7000 Zeichen -- sechs Preisgruppen, sechs
|
||||
Ligen, Teilnahmebedingungen. Das ist die Laenge,
|
||||
die Filipe gemeint hat.
|
||||
===================================================================== */
|
||||
|
||||
/** Eine Coinzahl, wie man sie liest: 12000 -> 12.000 Coins.
|
||||
*
|
||||
* BEWUSST ANDERS ALS DIE AUFGABEN. Vorher waren beide derselbe graue
|
||||
* Kasten mit derselben Ueberschriftzeile; nebeneinander sahen "was
|
||||
* ich tun soll" und "was dabei gilt" gleich wichtig aus. Eine Regel
|
||||
* ist aber kein Schritt: Man hakt sie nicht ab, man haelt sie ein. */
|
||||
function eventRegeln(e) {
|
||||
const punkte = Array.isArray(e.event_regelpunkte) ? e.event_regelpunkte : [];
|
||||
if (!punkte.length) return null;
|
||||
const block = el('section', 'ev-block ev-block--regeln');
|
||||
* `Number(null)` IST 0, UND 0 IST ENDLICH -- derselbe Fehler
|
||||
* wie in `gliederung()`, und er ist mir am 07.10.2026 an EINEM
|
||||
* Tag ZWEIMAL passiert: einmal auf dem Server, einmal hier. Der
|
||||
* Server lieferte danach brav `coins: null`, und die Kachel
|
||||
* schrieb „0 Coins" an das Feuerwerk -- also eine Preisangabe,
|
||||
* und zwar eine falsche.
|
||||
*
|
||||
* Gefunden hat es nicht die Serverpruefung (die war gruen),
|
||||
* sondern die Gegenprobe im Browser. Zwei Stellen, zwei
|
||||
* Messungen -- eine Pruefung auf der einen Seite beweist nichts
|
||||
* ueber die andere. */
|
||||
function coinText(n) {
|
||||
if (n === null || n === undefined || n === '') return null;
|
||||
const z = Number(n);
|
||||
if (!Number.isFinite(z)) return null;
|
||||
/* „1 Coins" ist der Schoenheitsfehler, der wie ein Fehler im
|
||||
Einlesen aussieht -- und das Erste, was jemand meldet. */
|
||||
return z.toLocaleString('de-DE') + (z === 1 ? ' Coin' : ' Coins');
|
||||
}
|
||||
|
||||
/** Ein Geschenk als Plakette: Name, Coinpreis, Hinweis. */
|
||||
function evGabe(z) {
|
||||
const li = el('li', 'ev-gabe');
|
||||
li.append(el('span', 'ev-gabe__name', z.text));
|
||||
const c = coinText(z.coins);
|
||||
/* KEIN PREIS IST NICHT NULL COINS. „Feuerwerk" bei LIVE Glow Up
|
||||
ist ein Kampagnengeschenk ohne Coinpreis; „0 Coins" daneben
|
||||
waere eine Preisangabe, und zwar eine falsche. */
|
||||
if (c) li.append(el('span', 'ev-gabe__coins', c));
|
||||
if (z.zusatz) li.append(el('span', 'ev-gabe__zusatz', z.zusatz));
|
||||
return li;
|
||||
}
|
||||
|
||||
/** Eine Zeile eines Abschnitts -- Absatz, Frage, Punkt, Geschenk. */
|
||||
function evZeile(z) {
|
||||
if (z.art === 'geschenk') return evGabe(z);
|
||||
if (z.art === 'punkt') {
|
||||
const li = el('li', 'ev-zeile');
|
||||
li.append(el('span', 'ev-zeile__zeichen'));
|
||||
li.append(el('span', 'ev-zeile__text', z.text));
|
||||
return li;
|
||||
}
|
||||
if (z.art === 'hinweis') return el('p', 'ev-hinweis', z.text);
|
||||
if (z.art === 'frage') return el('p', 'ev-frage', z.text);
|
||||
return el('p', 'ev-absatz', z.text);
|
||||
}
|
||||
|
||||
/** Zeilen in ihrer REIHENFOLGE anhaengen.
|
||||
*
|
||||
* Aufeinanderfolgende Punkte kommen in EINE Liste, ein Absatz
|
||||
* dazwischen beendet sie. Erst alle Absaetze und dann alle Punkte
|
||||
* zu malen waere einfacher und falsch: Bei den
|
||||
* Teilnahmebedingungen steht zwischen zwei Aufzaehlungen ein
|
||||
* Satz, der sich auf die ZWEITE bezieht -- umsortiert bezieht er
|
||||
* sich auf nichts. */
|
||||
function evZeilenAnhaengen(ziel, zeilen) {
|
||||
let liste = null;
|
||||
for (const z of zeilen || []) {
|
||||
const k = evZeile(z);
|
||||
if (k.tagName === 'LI') {
|
||||
if (!liste) {
|
||||
liste = el('ul', 'ev-zeilen');
|
||||
if (z.art === 'geschenk') liste.classList.add('ev-gaben');
|
||||
ziel.append(liste);
|
||||
}
|
||||
liste.append(k);
|
||||
continue;
|
||||
}
|
||||
liste = null;
|
||||
ziel.append(k);
|
||||
}
|
||||
}
|
||||
|
||||
/** Ein Abschnitt mit seiner Ueberschrift. */
|
||||
function evAbschnitt(a) {
|
||||
const s = el('section', 'ev-abschnitt');
|
||||
s.dataset.stufe = String(a.stufe || 2);
|
||||
if (a.art) s.dataset.art = a.art;
|
||||
if (a.titel) s.append(el('h5', 'ev-abschnitt__titel', a.titel));
|
||||
if (a.unter) s.append(el('p', 'ev-abschnitt__unter', a.unter));
|
||||
evZeilenAnhaengen(s, a.zeilen);
|
||||
return s;
|
||||
}
|
||||
|
||||
/** Die Geschenke, die zaehlen -- der eigene Block oben auf der Kachel. */
|
||||
function evGabenBlock(a) {
|
||||
const gaben = (a.zeilen || []).filter((z) => z.art === 'geschenk');
|
||||
if (!gaben.length) return null;
|
||||
const block = el('section', 'ev-block ev-block--gaben');
|
||||
const kopf = el('div', 'ev-block__kopf');
|
||||
kopf.append(el('h4', 'ev-block__schild', 'Regeln'));
|
||||
kopf.append(el('h4', 'ev-block__schild', 'Diese Geschenke zählen'));
|
||||
kopf.append(el('span', 'ev-zaehler', String(gaben.length)));
|
||||
block.append(kopf);
|
||||
const liste = el('ul', 'ev-liste ev-liste--still');
|
||||
for (const p of punkte) {
|
||||
const zeile = el('li', 'ev-punkt ev-punkt--regel');
|
||||
zeile.append(el('span', 'ev-punkt__zeichen'));
|
||||
zeile.append(el('span', 'ev-punkt__text', p.text));
|
||||
liste.append(zeile);
|
||||
/* DIE UEBERSCHRIFT DER KAMPAGNE BLEIBT STEHEN. „Sammle dein
|
||||
Feuerwerk -- Erhalte doppelte Punkte fuer die Rangliste" sagt,
|
||||
WARUM diese Geschenke zaehlen. Ein selbst erfundenes
|
||||
„Geschenke" daneben haette diese Auskunft verschluckt. */
|
||||
if (a.titel) {
|
||||
const woher = el('p', 'ev-gaben__woher', a.titel);
|
||||
if (a.unter) woher.append(el('span', 'ev-gaben__unter', a.unter));
|
||||
block.append(woher);
|
||||
}
|
||||
const liste = el('ul', 'ev-zeilen ev-gaben');
|
||||
for (const z of gaben) liste.append(evGabe(z));
|
||||
block.append(liste);
|
||||
/* Was im Geschenkabschnitt steht und KEIN Geschenk ist, geht
|
||||
nicht verloren -- sonst haengt die Vollstaendigkeit der
|
||||
Kachel daran, dass TikTok dort nie etwas anderes hinschreibt. */
|
||||
evZeilenAnhaengen(block, (a.zeilen || []).filter((z) => z.art !== 'geschenk'));
|
||||
return block;
|
||||
}
|
||||
|
||||
/** Was beim Einlesen gefehlt hat -- still, aber sichtbar. */
|
||||
function evHinweisBlock(zeilen) {
|
||||
if (!zeilen.length) return null;
|
||||
const kasten = el('aside', 'ev-hinweise');
|
||||
for (const z of zeilen) kasten.append(el('p', 'ev-hinweis', z.text));
|
||||
return kasten;
|
||||
}
|
||||
|
||||
/** Der Steckbrief: die harten Tatsachen aus der Kampagnenseite. */
|
||||
const STECK_NAME = {
|
||||
nummer: 'Kampagnennummer', kurznummer: 'Kurznummer',
|
||||
region: 'Markt', sprache: 'Sprache', verbund: 'Verbund',
|
||||
zeitzone: 'Zeitzone',
|
||||
anmeldung_ab: 'Anmeldung ab', ergebnis_bis: 'Ergebnisse bis',
|
||||
};
|
||||
const STECK_DATUM = new Set(['anmeldung_ab', 'ergebnis_bis']);
|
||||
function evSteckbrief(e) {
|
||||
const s = e.event_steckbrief;
|
||||
if (!s || typeof s !== 'object') return null;
|
||||
/* UEBER STECK_NAME GELAUFEN, nicht ueber die Felder des Servers:
|
||||
So bestimmt die Reihenfolge dieser Liste die Reihenfolge auf
|
||||
dem Bildschirm, und ein neues Feld erscheint erst, wenn es
|
||||
hier auch einen deutschen Namen hat. Sonst stuende irgendwann
|
||||
„activity_kind_flag: 1" auf der Kachel. */
|
||||
const paare = Object.keys(STECK_NAME)
|
||||
.filter((f) => s[f] !== null && s[f] !== undefined && s[f] !== '')
|
||||
.map((f) => [STECK_NAME[f], STECK_DATUM.has(f) ? datum(s[f]) : String(s[f])]);
|
||||
if (!paare.length) return null;
|
||||
const block = el('section', 'ev-block ev-block--steck');
|
||||
const kopf = el('div', 'ev-block__kopf');
|
||||
kopf.append(el('h4', 'ev-block__schild', 'Steckbrief'));
|
||||
block.append(kopf);
|
||||
const liste = el('dl', 'ev-steck');
|
||||
for (const [name, wert] of paare) {
|
||||
liste.append(el('dt', 'ev-steck__name', name));
|
||||
liste.append(el('dd', 'ev-steck__wert', wert));
|
||||
}
|
||||
block.append(liste);
|
||||
return block;
|
||||
}
|
||||
|
||||
/** Die Abschnitte des Regeltextes -- Hinweise und Geschenke heraus. */
|
||||
function evInfos(e) {
|
||||
const alle = Array.isArray(e.event_regelabschnitte) ? e.event_regelabschnitte : null;
|
||||
if (!alle) return null;
|
||||
const hinweise = [];
|
||||
let gaben = null;
|
||||
const rest = [];
|
||||
for (const a of alle) {
|
||||
/* Der Block GANZ OBEN ohne Ueberschrift sind die Hinweise des
|
||||
Lesers. Ein Hinweis MITTEN in einem Abschnitt bleibt dort --
|
||||
er bezieht sich dann auf diesen Abschnitt. */
|
||||
if (a.art === 'hinweise' && !a.titel) { hinweise.push(...(a.zeilen || [])); continue; }
|
||||
if (!gaben && a.art === 'geschenke') { gaben = a; continue; }
|
||||
rest.push(a);
|
||||
}
|
||||
return { hinweise, gaben, rest };
|
||||
}
|
||||
|
||||
/** Alles Uebrige in einem Block. */
|
||||
function evRegelBlock(abschnitte) {
|
||||
if (!abschnitte.length) return null;
|
||||
const block = el('section', 'ev-block ev-block--regeln');
|
||||
const kopf = el('div', 'ev-block__kopf');
|
||||
kopf.append(el('h4', 'ev-block__schild', 'Regeln & Infos'));
|
||||
kopf.append(el('span', 'ev-zaehler', String(abschnitte.length)));
|
||||
block.append(kopf);
|
||||
const kasten = el('div', 'ev-abschnitte');
|
||||
for (const a of abschnitte) kasten.append(evAbschnitt(a));
|
||||
block.append(kasten);
|
||||
return block;
|
||||
}
|
||||
|
||||
/** Der dritte Ausgang fuer die Event-Bloecke.
|
||||
*
|
||||
* Kommt vom Server keine Punkteliste (alte Fassung im Netz, Feld
|
||||
@@ -1340,8 +1620,27 @@
|
||||
schlichte Liste als eine Karte, auf der die Aufgaben fehlen. */
|
||||
const auf = eventAufgaben(e, stand)
|
||||
|| (e.event_aufgaben ? eventRueckfall('Aufgaben', e.event_aufgaben) : null);
|
||||
const reg = eventRegeln(e)
|
||||
|| (e.event_regeln ? eventRueckfall('Regeln', e.event_regeln) : null);
|
||||
|
||||
/* DER DRITTE AUSGANG (CLAUDE.md, 03.09.2026): in Ordnung /
|
||||
nicht in Ordnung / konnte nicht nachsehen.
|
||||
|
||||
`evInfos` gibt `null`, wenn der Server keine Gliederung
|
||||
geschickt hat -- alte Serverfassung, leeres Feld, Abfrage
|
||||
gescheitert. Dann steht der ROHTEXT da (`event_regeln`
|
||||
kommt weiterhin mit). Eine Kachel ohne Regeln waere der
|
||||
schlechteste von drei Ausgaengen; eine schlichte Textwand
|
||||
ist ein Schoenheitsfehler.
|
||||
|
||||
GLIEDERUNG DA, ABER LEER ist etwas anderes als „keine
|
||||
Gliederung": Dann hat das Event wirklich keine Regeln, und
|
||||
dann soll auch nichts dastehen. */
|
||||
const infos = evInfos(e);
|
||||
const gaben = infos?.gaben ? evGabenBlock(infos.gaben) : null;
|
||||
const hinweise = infos ? evHinweisBlock(infos.hinweise) : null;
|
||||
const reg = infos
|
||||
? evRegelBlock(infos.rest)
|
||||
: (e.event_regeln ? eventRueckfall('Regeln', e.event_regeln) : null);
|
||||
const steck = evSteckbrief(e);
|
||||
/* BEIDE IN EINE REIHE, nicht untereinander an die Karte.
|
||||
|
||||
Auf 1280 px ist eine Karte rund 1160 px breit. "30
|
||||
@@ -1353,12 +1652,57 @@
|
||||
zwar durch MESSEN (auto-fit mit Mindestbreite), nicht durch
|
||||
eine Fensterbreite in einer Zahl. Eine feste Schwelle waere
|
||||
beim naechsten zusaetzlichen Block wieder falsch. */
|
||||
if (auf || reg) {
|
||||
/* IMMER SICHTBAR: was man tun soll, und was dabei zaehlt. */
|
||||
if (auf || gaben) {
|
||||
const reihe = el('div', 'ev-bloecke');
|
||||
if (auf) reihe.append(auf);
|
||||
if (reg) reihe.append(reg);
|
||||
if (gaben) reihe.append(gaben);
|
||||
k.append(reihe);
|
||||
}
|
||||
|
||||
/* HINTER EINEM DRUCK: alles Uebrige (07.10.2026).
|
||||
|
||||
Filipe: „die kacheln von den events soll auch nicht so
|
||||
lang sein, die soll man aufklappen koennen damit die nicht
|
||||
zu lange sind." Gemessen an „Gipfelstuermer" sind das rund
|
||||
7000 Zeichen -- sechs Preisgruppen, sechs Ligen,
|
||||
Teilnahmebedingungen, Themenideen.
|
||||
|
||||
DERSELBE KLAPPMECHANISMUS WIE IM GANZEN HAUS
|
||||
(`abschnittKlappbar` aus kopf.js). Ein eigener waere ein
|
||||
zweiter, der sich anders verhaelt -- und er merkt sich die
|
||||
eigene Wahl, was hier wichtig ist: Das Brett baut sich bei
|
||||
jeder Aktualisierung neu auf, und eine Kachel, die dabei
|
||||
wieder zuklappt, waehrend man liest, ist aergerlicher als
|
||||
eine lange.
|
||||
|
||||
ZU ALS VORGABE. Das ist der Zweck der Uebung. Die Zahl im
|
||||
Knopf sagt, was dahinter steht -- ein zugeklappter Kasten
|
||||
ohne Zahl sieht aus, als sei er leer. */
|
||||
if (reg || steck) {
|
||||
const mehr = el('div', 'ev-mehr');
|
||||
const knopf = el('button', 'ev-mehr__knopf');
|
||||
knopf.type = 'button';
|
||||
knopf.append(el('span', 'ev-mehr__wort', 'Alle Infos'));
|
||||
const n = (infos?.rest.length || 0) + (steck ? 1 : 0);
|
||||
knopf.append(el('span', 'ev-mehr__zahl',
|
||||
n === 1 ? '1 Abschnitt' : n + ' Abschnitte'));
|
||||
if (window.klappPfeil) knopf.append(window.klappPfeil());
|
||||
const inhalt = el('div', 'ev-mehr__inhalt');
|
||||
if (reg) inhalt.append(reg);
|
||||
if (steck) inhalt.append(steck);
|
||||
mehr.append(knopf);
|
||||
mehr.append(inhalt);
|
||||
k.append(mehr);
|
||||
window.abschnittKlappbar?.(knopf, inhalt, 'event:' + e.id + ':infos', true);
|
||||
}
|
||||
|
||||
/* DIE HINWEISE ZULETZT UND SICHTBAR. „Die Preise konnten
|
||||
nicht gelesen werden -- bitte nachtragen" ist eine
|
||||
Aufgabe; hinter dem Aufklappen waere sie verborgen. Sie
|
||||
stehen unter den Bloecken, nicht zwischen den Regeln --
|
||||
genau das war der Fehler im Bildschirmfoto. */
|
||||
if (hinweise) k.append(hinweise);
|
||||
}
|
||||
|
||||
/* ---- STEHT IM KALENDER (17.09.2026) ------------------------------
|
||||
@@ -3353,11 +3697,36 @@
|
||||
? 'Noch keine Einladung eingelesen.'
|
||||
: 'Noch kein eigenes Event angelegt.'));
|
||||
}
|
||||
for (const e of drin) {
|
||||
const k = karte(e);
|
||||
k.dataset.quelle = seite;
|
||||
karten.set(e.id, k);
|
||||
spalte.append(k);
|
||||
/* NACH ZUSTAND UND ALTER GEGLIEDERT (07.10.2026) --
|
||||
Begruendung bei EV_GRUPPEN. „Laeuft gerade" steht
|
||||
offen, Vergangenes zu: Es ist Nachschlagewerk, nicht
|
||||
das, weswegen jemand die Seite oeffnet.
|
||||
|
||||
DER MERKER TRAEGT DIE SEITE MIT. Ohne ihn teilten sich
|
||||
„Laeuft gerade" links und rechts denselben Zustand,
|
||||
und wer die eine zuklappt, klappt die andere mit --
|
||||
derselbe Fehler, der bei den Zeitstufen schon einmal
|
||||
behoben wurde. */
|
||||
for (const [schluessel, name, zuVorgabe] of EV_GRUPPEN) {
|
||||
const fach = drin.filter((e) => evGruppeVon(e) === schluessel);
|
||||
if (!fach.length) continue;
|
||||
const gkopf = el('button', 'ev-gruppe__kopf');
|
||||
gkopf.type = 'button';
|
||||
gkopf.dataset.gruppe = schluessel;
|
||||
gkopf.append(el('span', 'ev-gruppe__wort', name));
|
||||
gkopf.append(el('span', 'ev-gruppe__zahl', String(fach.length)));
|
||||
if (window.klappPfeil) gkopf.append(window.klappPfeil());
|
||||
spalte.append(gkopf);
|
||||
const kasten = el('div', 'ev-gruppe__inhalt');
|
||||
for (const e of fach) {
|
||||
const k = karte(e);
|
||||
k.dataset.quelle = seite;
|
||||
karten.set(e.id, k);
|
||||
kasten.append(k);
|
||||
}
|
||||
spalte.append(kasten);
|
||||
window.abschnittKlappbar?.(gkopf, kasten,
|
||||
'agentur:' + seite + ':' + schluessel, zuVorgabe);
|
||||
}
|
||||
trennung.append(spalte);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user