Files
dogfather-universe/workspace/assets/js/bereiche.js
T
DogFatherGitandClaude Opus 5 d4cd8952b7 Checklisten-Gruppen klappen zu, Markierungen tragen ein Zeichen
Zwei Wuensche vom 01.09.2026:
  "neben den Titel soll immer ein Knopf sein, wo man die Liste aufmacht
   oder wieder zumacht -- die sollen auch zu, damit die Seiten nicht so
   lang sind."
  "und wenn die Ansprechpartner was markieren, sollen die da so ein
   Zeichen haben, so dass die sehen, da ist was -- und es soll auch oben
   in der Kachel angezeigt werden."

ZUKLAPPEN. Der Gruppenkopf ist jetzt ein Knopf ueber die volle Breite
(49 px hoch, mit dem Daumen treffbar), nicht ein Pfeilchen daneben. Zu
ist der Standard. Gemessen: Die LIVE-Analyse ist damit 1100 statt 2081
Pixel lang -- 47 Prozent gespart. Welche Gruppen offen waren, merkt sich
der Browser; sonst waere jede Bewertung ein Ruecksprung an den Anfang.

DAS ZEICHEN. Eine Raute mit Ausrufestrich, in Bernstein. Drei
Entscheidungen, keine davon Geschmack:
  * FORM -- alles andere auf dem Bildschirm ist rund oder eckig. Eine
    Spitze nach oben gibt es sonst nirgends, und deshalb findet das Auge
    sie zwischen zwanzig Kacheln ohne Suchen.
  * FARBE -- immer dieselbe, nie die der Kachel. Ein Zeichen, das die
    Farbe wechselt, muss gelesen werden; eines, das immer gleich
    aussieht, wird erkannt. Rot waere falsch: "verbessern" ist ein
    Auftrag, kein Fehler.
  * BEWEGUNG -- ein Atmen ueber 3,2 s, kein Blinken; bei "weniger
    Bewegung" bleibt der Schein stehen statt zu verschwinden.

Es steht an drei Stellen, immer aus derselben Quelle (bereiche.js): am
Gruppenkopf, am Punkt selbst und oben auf der Kachel der Startseite.

WARUM DAS ZEICHEN AM GRUPPENKOPF PFLICHT IST. Ohne es waere Zuklappen
ein Rueckschritt gewesen: Der Betreuer markiert etwas, die Gruppe ist zu,
und der Creator erfaehrt es nie. Die Zahl "zu verbessern" in der Bilanz
klappt die betroffenen Gruppen jetzt auf und springt hin.

Auf der Kachel nur fuer Creator. Fuer einen Betreuer waere es die Liste
dessen, was er selbst angehakt hat -- sie waechst mit seiner Arbeit, und
nur der Creator kann sie abbauen. Ein Zaehler, den man nicht auf null
bringen kann, wird ignoriert, und dann sind auch die daneben nichts wert.

ZWEI FEHLER, DIE DIE PRUEFUNG GEFUNDEN HAT:
  1. Das Zeichen stiess auf der Kachel mit der Zahl zusammen (zwei
     Pixel). Behoben an der Ursache: Besteht die Zahl NUR aus
     Markierungen, ist sie dieselbe Auskunft ein zweites Mal und
     entfaellt; sonst ruecken Zahl und Pfeil nach unten.
  2. Danach war die Pruefung wertlos -- sie verglich mit einem Element,
     das es nun nicht mehr gab, und war ohne einen einzigen Vergleich
     gruen. Sie zaehlt jetzt die geprueften Nachbarn mit; null Nachbarn
     ist ein Fehler, kein Erfolg.

Geprueft wird SICHTBARKEIT, nicht Vorhandensein: Ein zugeklappter Punkt
steht weiterhin im Dokument, alle bisherigen Pruefungen waeren gruen
geblieben, auch wenn der Creator seine Markierung nie zu Gesicht
bekaeme. Dazu Gegenproben: keine Markierung ohne Grund, und wer nichts
markiert bekommen hat, sieht auch kein Zeichen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-01 19:42:34 +02:00

260 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ===================================================================
Die Bereiche -- EINE Quelle für die ganze Anwendung.
Zeichen, Farbton, Rolle und Ziel jedes Bereichs standen bis zum
01.09.2026 nur in start.js. Seit jede Unterseite Zeichen und Farbe
ihrer Kachel trägt, brauchen sie auch die Kopfleisten -- und eine
zweite, abgeschriebene Liste wäre der sichere Weg, dass "Aufgaben"
irgendwann auf der Startseite gelb und auf der Aufgabenseite grün ist.
Deshalb liegt beides jetzt hier und wird von start.js UND kopf.js
benutzt. Wer eine Kachel ändert, ändert damit automatisch auch den
Kopf der zugehörigen Seite.
=================================================================== */
(() => {
'use strict';
/* ---------- Zeichen ------------------------------------------------------
Alle im selben Raster (24×24), alle nur aus Linien -- gefüllte Zeichen
wirken neben Text wie Flecken. Eigene statt einer Fremdbibliothek:
siebzehn Pfade sind kleiner als jede Schriftart und kosten keine
zusätzliche Lieferkette. */
const ZEICHEN = {
dashboard: ['M4.5 4.5h6v6h-6z', 'M13.5 4.5h6v4h-6z', 'M13.5 11.5h6v8h-6z', 'M4.5 13.5h6v6h-6z'],
aufgaben: ['M4.5 5h4v14h-4z', 'M10 5h4v9h-4z', 'M15.5 5h4v11.5h-4z'],
kalender: ['M4 6.5h16v13H4z', 'M4 10.5h16', 'M8.5 3.5v4', 'M15.5 3.5v4'],
calls: ['M3.5 7h11v10h-11z', 'M14.5 11l6-3.5v9l-6-3.5z'],
dateien: ['M3.5 6.5h5.5l2 2h9.5v11h-17z'],
/* Der Steckbrief: eine Person IN einer Karte -- unterscheidbar vom
Profil-Zeichen (nur die Person), damit die beiden Kacheln nicht
gleich aussehen. */
steckbrief: ['M3.5 5.5h17v13h-17z', 'M8.5 11.2a1.9 1.9 0 1 0 0-3.8 1.9 1.9 0 0 0 0 3.8z',
'M5.6 16.2c0-1.7 1.3-3 2.9-3s2.9 1.3 2.9 3', 'M14.5 9.5h4', 'M14.5 13h4'],
profil: ['M12 7a3.2 3.2 0 1 0 0 6.4A3.2 3.2 0 0 0 12 7z',
'M5.5 20c.7-3.3 3.3-5.3 6.5-5.3s5.8 2 6.5 5.3'],
startcheck: ['M6 4.5h12v15H6z', 'M9.2 9.6l1.7 1.7 3.6-3.7', 'M9.2 15.2h5.6'],
live: ['M12 10.2a1.8 1.8 0 1 0 0 3.6 1.8 1.8 0 0 0 0-3.6z',
'M8.2 8.2a5.4 5.4 0 0 0 0 7.6', 'M15.8 15.8a5.4 5.4 0 0 0 0-7.6',
'M5.4 5.4a9.4 9.4 0 0 0 0 13.2', 'M18.6 18.6a9.4 9.4 0 0 0 0-13.2'],
content: ['M3.5 6h17v13h-17z', 'M3.5 10h17', 'M8 6l-1.4 4', 'M13 6l-1.4 4', 'M18 6l-1.4 4'],
technik: ['M4 7.5h16', 'M4 12h16', 'M4 16.5h16',
'M9 7.5a1.4 1.4 0 1 0 0-.02z', 'M15 12a1.4 1.4 0 1 0 0-.02z',
'M7.5 16.5a1.4 1.4 0 1 0 0-.02z'],
community: ['M9 8.6a2.7 2.7 0 1 0 0 5.4 2.7 2.7 0 0 0 0-5.4z',
'M3.5 19.5c.6-2.8 2.8-4.5 5.5-4.5s4.9 1.7 5.5 4.5',
'M16 8.8a2.4 2.4 0 1 1 1.6 4.3', 'M17 15.2c2 .5 3.3 2 3.7 4.3'],
schutz: ['M12 3.6 5.6 6.3v5.1c0 3.8 2.6 7.2 6.4 8.4 3.8-1.2 6.4-4.6 6.4-8.4V6.3z',
'M9.4 11.8l1.9 1.9 3.4-3.6'],
reports: ['M4 19.5h16', 'M7.5 16.5V9.5', 'M12 16.5V5.5', 'M16.5 16.5v-5'],
personen: ['M14.4 6.2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z', 'M11.6 12.2 4 19.8',
'M6.4 17.4l2 2', 'M8.6 15.2l2 2'],
scouting: ['M3.5 5.5h17l-6.6 7.6v6.4l-3.8-2.1v-4.3z'],
wissen: ['M4 5h6.4c.9 0 1.6.7 1.6 1.6V19c0-.9-.7-1.6-1.6-1.6H4z',
'M20 5h-6.4c-.9 0-1.6.7-1.6 1.6V19c0-.9.7-1.6 1.6-1.6H20z'],
automation: ['M13.2 3.2 6 13.4h5.2l-.8 7.4 7.6-10.6h-5.2z'],
};
/* ---------- Die Bereiche -------------------------------------------------
`rollen` steuert, wem ein Bereich überhaupt erscheint -- serverseitig
wird es ohnehin noch einmal geprüft, das hier ist nur Höflichkeit.
`ton` ist der Farbplatz 1..17 -- JEDE Kachel hat ihre eigene Farbe.
Ein erster Versuch mit frei gewählten Farben ergab Paare mit einem
Abstand von 1,4: praktisch dieselbe Farbe, das sieht nach Zufall aus
statt nach Absicht. Deshalb sind Farben UND Zuordnung gerechnet, von
tools/kachel-farben.mjs. Die Überlegung dahinter: Das Auge vergleicht
nur, was nebeneinander liegt. Siebzehn Farben müssen sich also nicht
alle voneinander unterscheiden, sondern nur von ihren Nachbarn im
Raster -- und da sind es jetzt mindestens 105,9 Grad.
Wer hier Kacheln umsortiert oder eine hinzufügt, ändert damit die
Nachbarschaften. Dann gehört tools/kachel-farben.mjs neu gelaufen
(dort die Liste NACHBARN anpassen), sonst stimmt der Abstand nicht
mehr und niemand merkt es. */
const GRUPPEN = [
{
name: 'Täglich',
unter: 'Was du sowieso jeden Tag aufmachst',
bereiche: [
{ name: 'Dashboard', unter: 'Alle Creator auf einen Blick', zeichen: 'dashboard', ton: 3,
gross: true, rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'uebersicht.html', szene: 'showbuehne' },
{ name: 'Aufgaben', unter: 'Offen, in Arbeit, Review', zeichen: 'aufgaben', ton: 11,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'aufgaben.html', szene: 'garage' },
{ name: 'Kalender', unter: 'Termine und Calls', zeichen: 'kalender', ton: 16,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'kalender.html', szene: 'skyline' },
{ name: 'Calls & Protokolle', unter: 'Gespräche mit To-dos', zeichen: 'calls', ton: 9,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'calls.html', szene: 'lounge' },
{ name: 'Dateien', unter: 'Ablage und Freigaben', zeichen: 'dateien', ton: 2,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'dateien.html', szene: 'arena' },
],
},
{
name: 'Rund um den Creator',
unter: 'Die Betreuungsakte – Stand, Zahlen, Verlauf',
bereiche: [
/* ZWEI VERSCHIEDENE DINGE, zwei Kacheln (01.09.2026).
Vorher war beides dieselbe Seite, und das war verwirrend:
Oben stand "Profil: SpongBobSchwammKopf" und mitten darin
"MEIN PROFIL - Dogfather". Zwei Personen auf einem Bildschirm,
ohne dass klar war, welche gerade gemeint ist.
Es sind auch wirklich zwei Sachen:
MEIN STECKBRIEF gehoert MIR -- Bild, ein Satz ueber mich,
meine Kanaele. Fuehre ich selbst, hat
jeder (auch Scouts und Manager).
CREATOR-PROFILE die BETREUUNGSAKTE eines Creators --
Ziele, 90-Tage-Plan, interne Notizen.
Fuehren die Betreuer.
Ein Creator sieht nur seine eigene Akte (dort steht auch sein
Steckbrief mit drin, er hat ja nur eine Seite). Alle anderen
bekommen beide Kacheln getrennt. */
{ name: 'Mein Steckbrief', unter: 'Dein Bild und deine Kanäle', zeichen: 'steckbrief', ton: 15,
rollen: ['admin', 'manager', 'scout'], ziel: 'steckbrief.html', szene: 'halle' },
{ name: 'Creator-Profile', unter: 'Ziele und 90-Tage-Plan', zeichen: 'profil', ton: 8,
rollen: ['admin', 'manager', 'scout'], ziel: 'profil.html', szene: 'halle' },
{ name: 'Mein Profil', unter: 'Dein Steckbrief, Ziele und Pläne', zeichen: 'profil', ton: 8,
rollen: ['creator'], ziel: 'profil.html', szene: 'halle' },
{ name: 'Start-Check', unter: 'Erstanalyse, 16 Punkte', zeichen: 'startcheck', ton: 18,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'startcheck.html', szene: 'wald' },
{ name: 'LIVE-Analyse', unter: 'Vorher, während, danach', zeichen: 'live', ton: 7,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=live', szene: 'portal' },
{ name: 'Content-Ideen', unter: 'Idee bis Upload', zeichen: 'content', ton: 13,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'content.html', szene: 'portal' },
{ name: 'Community', unter: 'Moderation und Konflikte', zeichen: 'community', ton: 6,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=community', szene: 'lounge' },
{ name: 'Technik', unter: 'Setup, Fehler, Lösungen', zeichen: 'technik', ton: 12,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=technik', szene: 'garage' },
{ name: 'Schutz & Regeln', unter: 'Richtlinien und Vorfälle', zeichen: 'schutz', ton: 1,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'bereich.html?b=schutz', szene: 'halle' },
{ name: 'Reports & Review', unter: 'Woche und Entscheidung', zeichen: 'reports', ton: 14,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'report.html', szene: 'showbuehne' },
],
},
{
name: 'Team & System',
unter: 'Was den Laden am Laufen hält',
/* Für einen Creator bleibt von dieser Gruppe genau eine Kachel übrig:
die Wissens-Bibliothek. "Team & System" wäre dann eine Überschrift,
die etwas verspricht, was gar nicht da ist -- und die klingt, als
gäbe es dahinter noch einen Bereich, den er nicht sehen darf. Er
liest stattdessen "Wissen", und das beschreibt genau, was dort
steht. Der Untertitel wechselt mit. */
nameCreator: 'Wissen',
unterCreator: 'Nachschlagen, wenn du etwas brauchst',
bereiche: [
{ name: 'Personen & Zugänge', unter: 'Rollen und Codes', zeichen: 'personen', ton: 10,
rollen: ['admin', 'manager'], ziel: 'personen.html', szene: 'halle' },
{ name: 'Scout-Pipeline', unter: 'Entdeckt bis übergeben', zeichen: 'scouting', ton: 17,
rollen: ['admin', 'manager', 'scout'], ziel: 'scouting.html', szene: 'wald' },
{ name: 'Wissens-Bibliothek', unter: 'Anleitungen und PDFs', zeichen: 'wissen', ton: 4,
rollen: ['admin', 'manager', 'creator', 'scout'], ziel: 'wissen.html', szene: 'arena' },
{ name: 'Automationen', unter: 'Was von allein passiert', zeichen: 'automation', ton: 5,
rollen: ['admin', 'manager'], ziel: 'automation.html', szene: 'garage' },
],
},
];
/* Ein Bereich anhand des Dateinamens finden. Die Bereichsseite
(bereich.html?b=live) trägt ihren Bereich in der Adresse -- deshalb
wird auch die Abfrage verglichen, nicht nur der Dateiname. */
function zuSeite(pfad, abfrage) {
const datei = String(pfad).split('/').pop() || 'start.html';
const gesucht = datei + (abfrage || '');
let treffer = null;
for (const g of GRUPPEN) {
for (const b of g.bereiche) {
if (b.ziel === gesucht) return b;
/* Ohne Abfrage: der erste Bereich mit passendem Dateinamen.
"Mein Profil" und "Creator-Profile" zeigen auf dieselbe Datei
und teilen sich Zeichen und Ton -- da ist beides richtig. */
if (!treffer && b.ziel.split('?')[0] === datei) treffer = b;
}
}
return treffer;
}
/* Ein SVG mit dem Zeichen eines Bereichs. Klasse frei wählbar, damit
Kachel, Hinweiszeile und Seitenkopf dieselbe Form in
unterschiedlicher Größe benutzen können. */
function zeichenBauen(name, klasse = 'kachel__svg') {
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('viewBox', '0 0 24 24');
svg.setAttribute('aria-hidden', 'true');
svg.setAttribute('class', klasse);
for (const d of (ZEICHEN[name] || [])) {
const p = document.createElementNS('http://www.w3.org/2000/svg', 'path');
p.setAttribute('d', d);
svg.append(p);
}
return svg;
}
/* ---------- Das Merkzeichen ----------------------------------------------
Wunsch vom 01.09.2026: "wenn die Ansprechpartner was markieren, sollen
die da so ein Zeichen/Symbol haben, so dass die sehen, da ist was --
und es soll auch oben in der Kachel angezeigt werden."
Es ist bewusst das EINZIGE Zeichen der ganzen Anwendung, das eine
eigene Form hat statt der 24×24-Linienzeichen oben: eine Raute mit
Ausrufestrich. Der Grund ist nicht Geschmack, sondern Erkennbarkeit --
alle anderen Zeichen sind Rechtecke und Kreise; eine Raute ist die
einzige Form auf dem Bildschirm, die spitz nach oben zeigt, und
genau deshalb findet das Auge sie zwischen zwanzig Kacheln sofort.
Und es ist immer DIESELBE Farbe (Bernstein), egal auf welcher Kachel
es sitzt. Ein Zeichen, das seine Farbe wechselt, muss gelesen werden;
eines, das immer gleich aussieht, wird erkannt. Rot wäre falsch --
"verbessern" ist kein Fehler, sondern ein Auftrag.
anzahl > 1 schreibt die Zahl daneben, sonst steht nur das Zeichen.
Der Satz für Vorleseprogramme wird immer gesetzt: Ein Symbol ohne
Text ist für sie nicht vorhanden. */
function merkzeichenBauen(anzahl = 0, klasse = 'merk') {
const s = document.createElement('span');
s.className = klasse;
s.setAttribute('role', 'img');
s.setAttribute('aria-label', anzahl > 0
? `${anzahl} ${anzahl === 1 ? 'Punkt ist' : 'Punkte sind'} zum Verbessern markiert`
: 'Zum Verbessern markiert');
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('viewBox', '0 0 24 24');
svg.setAttribute('aria-hidden', 'true');
svg.setAttribute('class', klasse + '__svg');
/* Drei Pfade: die gefüllte Raute, der Strich, der Punkt. Getrennt,
damit die Fläche eine andere Deckkraft bekommen kann als die
Linie -- eine durchgehend volle Raute wäre auf dunklem Grund ein
Klecks. */
const teile = [
['M12 1.9 22.1 12 12 22.1 1.9 12z', 'flaeche'],
['M12 7.5v5.6', 'strich'],
['M12 16.9h.01', 'punkt'],
];
for (const [d, art] of teile) {
const p = document.createElementNS('http://www.w3.org/2000/svg', 'path');
p.setAttribute('d', d);
p.setAttribute('class', `${klasse}__${art}`);
svg.append(p);
}
s.append(svg);
if (anzahl > 1) {
const n = document.createElement('span');
n.className = klasse + '__n';
n.textContent = String(anzahl);
n.setAttribute('aria-hidden', 'true');
s.append(n);
}
return s;
}
window.Bereiche = { ZEICHEN, GRUPPEN, zuSeite, zeichenBauen, merkzeichenBauen };
})();