Navigation leichter: Handy-Leiste, Schwarz nur für die Hauptaktion, Verträge mit zwei Reitern, kürzeres Konto (V3, V5, V7, V8)

V3: In der Fahrstuhl-Zeile läuft unter dem aktiven Wort eine dünne Linie statt des schwarzen Blocks; das Wort wird dunkel und fett. Die weiße Overlay-Kopie bleibt im Baum, wird aber nicht mehr gezeigt.
V5: Terminplaner: Tag/Woche/Monat als hellgrauer Umschalter mit weißer Auswahl, Filter als leise Chips. „Einschalten“ in der Liste Entdecken ist ein heller Knopf; schwarz bleibt der Knopf der Bestätigungsseite.
V7: Verträge nur noch mit Abo und Rechnungen. Das Stundenkonto steht beim Wartungs-Abo als Abschnitt unter dem Abo (ohne doppelte Warnungen), #stunden springt dorthin. Der E-Mail-Speicher ist die Unterseite #speicher (Link „ändern“ in der Abo-Zeile), ohne Widerrufsstreifen wie die anderen Bestellseiten. Alte Links bleiben gültig.
V8: Konto mit vier Zeilen (Passwort, Verträge kündigen, Vertrag widerrufen, Abmelden), Datenschutz und Impressum klein darunter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-29 17:27:30 +00:00
1 parent a270ff51da
commit 83ac903ab3
18 files changed
+152 -96

No files matched your search

+9 -6
View File
@@ -5,10 +5,11 @@ import { h } from '../public/neu/dom.js'
import { initialenVon, installAngebot, kontoEintraege, baueAvatar, baueKonto } from '../public/neu/konto.js'
import { lies, handyTeil } from './support/knHuelle.js'
test('Reihenfolge, Texte und Ziele des Kontos (V3); Widerrufen immer da, "Frist läuft" nur in der Frist', () => {
test('Reihenfolge, Texte und Ziele des Kontos (V3 mit Navigation leichter V8); Widerrufen immer da, "Frist läuft" nur in der Frist', () => {
const ids = (o) => kontoEintraege(o).map((e) => e.id)
assert.deepEqual(ids({ fristen: null, install: null }), ['passwort', 'datenschutz', 'impressum', 'kuendigen', 'widerrufen', 'abmelden'])
assert.deepEqual(ids({ fristen: null, install: 'ios' }), ['passwort', 'datenschutz', 'impressum', 'installieren', 'kuendigen', 'widerrufen', 'abmelden'])
assert.deepEqual(ids({ fristen: null, install: null }), ['passwort', 'kuendigen', 'widerrufen', 'abmelden', 'datenschutz', 'impressum'])
assert.deepEqual(ids({ fristen: null, install: 'ios' }), ['passwort', 'installieren', 'kuendigen', 'widerrufen', 'abmelden', 'datenschutz', 'impressum'])
assert.deepEqual(kontoEintraege({ fristen: null, install: null }).filter((e) => e.klein).map((e) => e.id), ['datenschutz', 'impressum'])
const e = Object.fromEntries(kontoEintraege({ fristen: null, install: 'prompt' }).map((x) => [x.id, x]))
assert.deepEqual([e.passwort.text, e.passwort.href, e.datenschutz.href, e.impressum.href, e.kuendigen.href, e.kuendigen.betont], ['Passwort ändern', '#passwort', '/datenschutz.html', 'https://webklar.com/impressum', '/kuendigen.html', true])
assert.deepEqual([e.widerrufen.text, e.widerrufen.href, e.widerrufen.pille, e.installieren.text, e.abmelden.text], ['Vertrag widerrufen', '/widerrufen.html', undefined, 'App installieren', 'Abmelden'])
@@ -37,12 +38,13 @@ test('baueKonto: Kopf als Text, Sheet-Verhalten, Overlay-Kopplung, Navigation, A
const k = baueKonto({ me, fristen: null, install: null, onAbmelden: () => log.push('abmelden'), onInstall() {}, overlay: { oeffne: (o) => log.push(['overlay', typeof o.schliesse]), beende: () => log.push('beende') }, navigiere: (hash) => log.push(['geheZu', hash]) })
fx.document.body.append(k.wurzel); const zeilen = () => fx.alle(k.wurzel, '.kn-konto-zeile')
assert.deepEqual([fx.finde(k.wurzel, '.kn-konto-name').textContent, fx.finde(k.wurzel, '.kn-konto-mail').textContent], ['<img src=x onerror=alert(1)>Salon', 'a@b.de'])
assert.deepEqual(zeilen().map((z) => z.textContent), ['Passwort ändern', 'Datenschutz', 'Impressum', 'Verträge kündigen', 'Vertrag widerrufen', 'Abmelden'])
assert.deepEqual(zeilen().map((z) => z.textContent), ['Passwort ändern', 'Verträge kündigen', 'Vertrag widerrufen', 'Abmelden', 'Datenschutz', 'Impressum'])
assert.deepEqual(zeilen().filter((z) => z.classList.contains('kn-konto-zeile--klein')).map((z) => z.textContent), ['Datenschutz', 'Impressum'])
assert.deepEqual([k.wurzel.getAttribute('role'), k.wurzel.getAttribute('aria-modal')], ['dialog', 'true'])
k.oeffne(trigger); assert.deepEqual([k.istOffen(), trigger.getAttribute('aria-expanded'), log[0]], [true, 'true', ['overlay', 'function']])
await fx.sende(k.wurzel, 'keydown', { key: 'Escape' }); assert.deepEqual([k.istOffen(), log.at(-1), fx.document.activeElement === trigger], [false, 'beende', true])
k.oeffne(trigger); await fx.klick(zeilen()[0]); assert.deepEqual(log.at(-1), ['geheZu', '#passwort'])
await fx.klick(zeilen().at(-1)); assert.equal(log.at(-1), 'abmelden')
await fx.klick(zeilen().find((z) => z.getAttribute('data-konto') === 'abmelden')); assert.equal(log.at(-1), 'abmelden')
k.aktualisiere({ fristen: { anzeigen: true }, install: 'ios' }); assert.ok(k.istOffen()); assert.match(fx.text(k.wurzel), /App installieren[\s\S]*Vertrag widerrufen.*Frist läuft/)
await fx.klick(fx.finde(k.wurzel, '.kn-konto-scrim')); assert.equal(k.istOffen(), false)
} finally { fx.restore() }
@@ -62,7 +64,8 @@ test('Konto: Router schließt ohne zweites Zurück, Links öffnen richtig, Tab b
overlay: { oeffne: (o) => { vomRouter = o.schliesse }, beende: () => log.push('beende') }, navigiere() {} })
fx.document.body.append(k.wurzel); const zeilen = () => fx.alle(k.wurzel, '.kn-konto-zeile')
assert.equal(fx.finde(k.wurzel, '.kn-konto-name').textContent, 'a@b.de') // ohne Firma und Namen die E-Mail
const [pw, ds, im, inst] = zeilen()
const zeile = (id) => zeilen().find((z) => z.getAttribute('data-konto') === id)
const [pw, ds, im, inst] = ['passwort', 'datenschutz', 'impressum', 'installieren'].map(zeile)
assert.deepEqual([ds.getAttribute('target'), ds.getAttribute('rel'), im.getAttribute('target'), pw.hasAttribute('target')], ['_blank', 'noopener', '_blank', false])
assert.match(inst.textContent, /Tippe auf Teilen und dann auf Zum Home-Bildschirm\./)
k.oeffne(trigger); assert.equal(fx.document.activeElement, pw) // Fokus auf der ersten Zeile