Module: im Abo-Modell Reiter mit Kurzlabels an die Etage melden (C2)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b91ba1d5cb
commit
a50c5ef6c9
6 files changed
+366
-17
No files matched your search
+18
-5
@@ -16,6 +16,7 @@
|
||||
import { fehlerKarte, h, infoKarte, request } from './shop-dom.js'
|
||||
import { anfrageKarte, anfrageZeilen, renderAnfrageFormular } from './shop-anfrage.js'
|
||||
import { renderBestellen, statusKarte } from './funktion-bestellen.js'
|
||||
import { meldeReiter, reiterEintraege } from './fn-reiter.js'
|
||||
|
||||
/** Die Reiter: jeder ein Modul mit render(panel, ctx), erst beim ersten Oeffnen geladen. */
|
||||
export const REITER = [
|
||||
@@ -48,6 +49,10 @@ let S = null // aktuelle Sitzung der Ansicht; eine alte Antwort darf eine neuere
|
||||
|
||||
const zustandVon = (projekt) => projekt?.features?.shop?.state || 'off'
|
||||
const text = (wert) => (typeof wert === 'string' ? wert : '')
|
||||
// Abo-Modell (Antwort von GET /api/funktionen, strikt): die Reiter zeichnet die Etage, die Ansicht meldet sie (fn-reiter.js)
|
||||
const istAbo = (s) => s.funktionen?.modell === 'abo'
|
||||
/** Eine Ansicht ohne Reiter meldet die leere Liste, damit die Etage nicht die Reiter der vorigen stehen laesst. */
|
||||
const keineReiter = (s) => { if (istAbo(s)) meldeReiter(s.root, { eintraege: [] }) }
|
||||
|
||||
/* --------------------------------------------------------- Einstieg --- */
|
||||
/** Rueckkehr aus der Adresse lesen und diese bereinigen: #webshop?bestellt=1&projekt=<id> | #webshop?stripe=zurueck|neu&projekt=<id>. */
|
||||
@@ -81,10 +86,12 @@ async function starte(root, projectId) {
|
||||
}
|
||||
if (S !== s) return
|
||||
if (!s.funktionen?.shop?.verfuegbar) {
|
||||
keineReiter(s)
|
||||
root.replaceChildren(infoKarte(NICHT_VERFUEGBAR, 'Sobald er für dich bereit ist, findest du ihn hier.'))
|
||||
return
|
||||
}
|
||||
if (!s.projects.length) {
|
||||
keineReiter(s)
|
||||
root.replaceChildren(h('div', { class: 'kb-panel kb-empty' }, 'Noch keine Website-Projekte zugewiesen.'))
|
||||
return
|
||||
}
|
||||
@@ -151,6 +158,7 @@ async function zeigeProjekt(s, optionen = {}) {
|
||||
const projekt = s.projekt
|
||||
const lauf = ++s.lauf
|
||||
const aktuell = () => S === s && s.lauf === lauf
|
||||
keineReiter(s)
|
||||
s.buehne.replaceChildren(h('p', { class: 'kb-empty' }, 'Lade…'))
|
||||
let status
|
||||
try {
|
||||
@@ -179,6 +187,7 @@ async function ladeNeu(s, optionen = {}) {
|
||||
/** Die Ansicht zum Zustand aus dem frisch geladenen Stand (status.state). */
|
||||
async function zeichneAnsicht(s, { status, aktuell, bestellformular = false, meldung = null }) {
|
||||
s.status = status
|
||||
keineReiter(s) // die Ansicht mit Reitern (zeigeReiter) meldet ihre Liste gleich danach
|
||||
if (!status.verfuegbar) {
|
||||
s.buehne.replaceChildren(infoKarte(NICHT_VERFUEGBAR, 'Sobald er für dich bereit ist, findest du ihn hier.'))
|
||||
return
|
||||
@@ -318,15 +327,16 @@ function zeigeReiter(s, { status, aktuell, zustand }) {
|
||||
neuLaden,
|
||||
}
|
||||
|
||||
const abo = istAbo(s) // Abo-Modell: keine eigene Leiste, die Etage zeichnet sie (kn:reiter)
|
||||
const panel = h('div', { class: 'sh-panel', role: 'tabpanel', id: 'sh-panel', tabindex: '0' })
|
||||
let aktiv = null // Schluessel des gezeigten Reiters
|
||||
let zaehler = 0 // nur der zuletzt gewaehlte Reiter zeichnet in das Panel
|
||||
const knoepfe = REITER.map((r) => h('button', {
|
||||
const knoepfe = abo ? [] : REITER.map((r) => h('button', {
|
||||
type: 'button', role: 'tab', class: 'sh-reiter', id: `sh-tab-${r.key}`, 'aria-controls': 'sh-panel', 'data-reiter': r.key,
|
||||
onclick: () => waehleReiter(r.key),
|
||||
}, r.label))
|
||||
const leiste = h('div', { class: 'sh-reiterleiste', role: 'tablist', 'aria-label': 'Bereiche des Webshops' }, knoepfe)
|
||||
leiste.addEventListener('keydown', (ev) => {
|
||||
const leiste = abo ? null : h('div', { class: 'sh-reiterleiste', role: 'tablist', 'aria-label': 'Bereiche des Webshops' }, knoepfe)
|
||||
leiste?.addEventListener('keydown', (ev) => {
|
||||
const i = REITER.findIndex((r) => r.key === aktiv)
|
||||
const ziel = { ArrowRight: (i + 1) % REITER.length, ArrowLeft: (i + REITER.length - 1) % REITER.length, Home: 0, End: REITER.length - 1 }[ev.key]
|
||||
if (ziel === undefined) return
|
||||
@@ -345,7 +355,10 @@ function zeigeReiter(s, { status, aktuell, zustand }) {
|
||||
k.setAttribute('aria-selected', String(an))
|
||||
k.tabIndex = an ? 0 : -1
|
||||
}
|
||||
panel.setAttribute('aria-labelledby', `sh-tab-${reiter.key}`)
|
||||
if (abo) {
|
||||
panel.setAttribute('aria-label', reiter.label)
|
||||
meldeReiter(s.root, { eintraege: reiterEintraege('shop', REITER), aktiv: reiter.key, bei: (neu) => waehleReiter(neu) })
|
||||
} else panel.setAttribute('aria-labelledby', `sh-tab-${reiter.key}`)
|
||||
zeigeMeldung(s, '')
|
||||
panel.replaceChildren()
|
||||
reiter.laden()
|
||||
@@ -353,7 +366,7 @@ function zeigeReiter(s, { status, aktuell, zustand }) {
|
||||
.catch((err) => { if (nr === zaehler && aktuell()) panel.replaceChildren(fehlerKarte(err.message, () => waehleReiter(reiter.key))) })
|
||||
}
|
||||
|
||||
s.buehne.replaceChildren(hinweisBox, leiste, panel)
|
||||
s.buehne.replaceChildren(...[hinweisBox, leiste, panel].filter(Boolean))
|
||||
// vom Onboarding bei Stripe zurueck: die Uebersicht zeigt den Stand der Stripe-Karte
|
||||
waehleReiter(s.stripe && zustand !== 'disabled' ? 'uebersicht' : auswahl.reiter, { merken: false })
|
||||
if (s.danke && zustand === 'setup') zeigeMeldung(s, DANKE_SETUP)
|
||||
|
||||
Reference in new issue
Block a user