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:
1 parent
a270ff51da
commit
83ac903ab3
18 files changed
+152
-96
No files matched your search
@@ -1,6 +1,8 @@
|
||||
/* Kundenansicht neu (P2): Bereich Verträge mit den Reitern Rechnungen, Abo, Stunden und E-Mail. Der Rahmen lädt Abo und Rechnungen
|
||||
parallel (jede Quelle mit eigenem Fehlerweg), wählt den Reiter allein aus route.reiter und gibt die schon geladenen Antworten an
|
||||
die Reiter-Inhalte weiter. Bestellen, Wechsel und Gutschrift sind Etagen, die die Hülle direkt ruft. */
|
||||
/* Kundenansicht neu (P2): Bereich Verträge mit den Reitern Abo und Rechnungen (Navigation leichter V7, vorher dazu Stunden und E-Mail).
|
||||
Das Stundenkonto des Wartungs-Abos steht als Abschnitt unter dem Abo; #stunden öffnet das Abo und springt dorthin. Der E-Mail-Speicher ist
|
||||
die Etage #speicher (Link „ändern“ im Abo). Der Rahmen lädt Abo und Rechnungen parallel (jede Quelle mit eigenem Fehlerweg), wählt den
|
||||
Reiter allein aus route.reiter und gibt die schon geladenen Antworten an die Reiter-Inhalte weiter. Bestellen, Wechsel, Gutschrift und
|
||||
Speicher sind Etagen, die die Hülle direkt ruft. */
|
||||
|
||||
import { api } from './api.js'
|
||||
import { h, leeren } from './dom.js'
|
||||
@@ -11,26 +13,24 @@ import { offeneRechnungen } from './rechnung-offen.js'
|
||||
import { zeigeRechnungen } from './vertraege-rechnungen.js'
|
||||
import { zeigeAbo } from './vertraege-abo.js'
|
||||
import { zeigeStunden } from './ansicht-stunden.js'
|
||||
import { zeigeSpeicher } from './ansicht-speicher.js'
|
||||
|
||||
/** Nach ?abo=success: so oft und in diesem Abstand wird auf ein laufendes Abo gewartet (Tests verkürzen es). */
|
||||
export const AUF_ABO_WARTEN = { versuche: 10, pauseMs: 2000 }
|
||||
|
||||
const LABEL = { rechnungen: 'Rechnungen', abo: 'Abo', stunden: 'Stunden', email: 'E-Mail' }
|
||||
const LABEL = { abo: 'Abo', rechnungen: 'Rechnungen' }
|
||||
// Reiterklicks navigieren mit den ausdrücklichen Hashes (P1 schreibt #wartung und #abo kanonisch um)
|
||||
const HASH = { rechnungen: '#rechnungen', abo: '#abo', stunden: '#stunden', email: '#speicher' }
|
||||
const HASH = { abo: '#abo', rechnungen: '#rechnungen' }
|
||||
const laeufe = new WeakMap() // Wurzel → Nummer des jüngsten Aufrufs
|
||||
let reiterWechsel = null // Reiterklick mit laufendem Router: der nächste Aufruf nimmt die schon geladenen Antworten
|
||||
|
||||
/** Sichtbare Reiter: ohne laufendes Abo Rechnungen und Abo; Hosting dazu E-Mail; Wartung dazu Stunden und E-Mail. */
|
||||
export function sichtbareReiter(daten) {
|
||||
const sub = daten?.subscription
|
||||
const reiter = ['rechnungen', 'abo']
|
||||
if (!sub?.active) return reiter
|
||||
if (sub.productKey === 'hosting') return [...reiter, 'email']
|
||||
return [...reiter, 'stunden', 'email']
|
||||
/** Sichtbare Reiter: immer Abo und Rechnungen (Navigation leichter V7). Stunden stehen im Abo, der E-Mail-Speicher ist die Etage #speicher. */
|
||||
export function sichtbareReiter() {
|
||||
return ['abo', 'rechnungen']
|
||||
}
|
||||
|
||||
/** Gibt es ein Stundenkonto unter dem Abo? Nur mit laufendem Wartungs-Abo. */
|
||||
export const mitStundenkonto = (daten) => Boolean(daten?.subscription?.active && daten.subscription.productKey === 'wartung')
|
||||
|
||||
/** Reiterwahl allein aus route.reiter (routeReiter) und den Daten, nie aus der Adressleiste. Nur der Bereichs-Einstieg (ohne Reiter) springt auf Rechnungen. */
|
||||
export function waehleReiter({ routeReiter, sichtbar, offeneRechnungen: offen }) {
|
||||
if (routeReiter) return sichtbar.includes(routeReiter) ? routeReiter : 'abo'
|
||||
@@ -79,7 +79,8 @@ export async function zeigeVertraege(wurzel, { route, me, nav } = {}) {
|
||||
const sichtbar = sichtbareReiter(daten)
|
||||
const offen = offeneRechnungen(rechnungen).length
|
||||
const gewaehlt = waehleReiter({ routeReiter: route?.reiter, sichtbar, offeneRechnungen: offen })
|
||||
const stundenOhneWartung = route?.reiter === 'stunden' && !sichtbar.includes('stunden')
|
||||
const stundenGewuenscht = route?.reiter === 'stunden' // #stunden: Abo zeigen und zum Stundenkonto springen
|
||||
const stundenkonto = mitStundenkonto(daten)
|
||||
const hinweis = nimmHinweis()
|
||||
|
||||
const inhalt = h('div', { class: 'kn-reiter-inhalt' })
|
||||
@@ -87,14 +88,20 @@ export async function zeigeVertraege(wurzel, { route, me, nav } = {}) {
|
||||
leeren(inhalt)
|
||||
if (key === 'rechnungen') return zeigeRechnungen(inhalt, { me, antwort: rechnungen ?? undefined })
|
||||
if (!daten) return Promise.resolve()
|
||||
if (key === 'abo') {
|
||||
if (stundenOhneWartung) inhalt.append(h('p', { class: 'kn-hinweis' }, 'Ein Stundenkonto gibt es im Wartungs-Abo.'))
|
||||
const platz = h('div', { class: 'kn-reiter-abo' })
|
||||
inhalt.append(platz)
|
||||
return zeigeAbo(platz, { daten, me })
|
||||
if (stundenGewuenscht && !stundenkonto) inhalt.append(h('p', { class: 'kn-hinweis' }, 'Ein Stundenkonto gibt es im Wartungs-Abo.'))
|
||||
const platz = h('div', { class: 'kn-reiter-abo' })
|
||||
inhalt.append(platz)
|
||||
const fertig = [zeigeAbo(platz, { daten, me })]
|
||||
if (stundenkonto) {
|
||||
const konto = h('div')
|
||||
const abschnitt = h('section', { class: 'kn-sektion kn-stundenkonto', id: 'kn-stundenkonto', 'aria-labelledby': 'kn-stundenkonto-titel' },
|
||||
h('h2', { class: K.abschnitt, id: 'kn-stundenkonto-titel' }, 'Stundenkonto'), konto)
|
||||
inhalt.append(abschnitt)
|
||||
fertig.push(zeigeStunden(konto, { route, me, nav, daten, eingebettet: true }).then(() => {
|
||||
if (stundenGewuenscht && nav !== 'back' && typeof abschnitt.scrollIntoView === 'function') abschnitt.scrollIntoView({ block: 'start' })
|
||||
}))
|
||||
}
|
||||
if (key === 'stunden') return zeigeStunden(inhalt, { route, me, nav, daten })
|
||||
return zeigeSpeicher(inhalt, { route, me, nav, daten })
|
||||
return Promise.all(fertig)
|
||||
}
|
||||
|
||||
const bei = (key) => {
|
||||
|
||||
Reference in new issue
Block a user