diff --git a/src/components/home/Kundenportal.tsx b/src/components/home/Kundenportal.tsx
index fa52b99..9c44027 100644
--- a/src/components/home/Kundenportal.tsx
+++ b/src/components/home/Kundenportal.tsx
@@ -96,8 +96,12 @@ type Funktion = {
beschreibung?: string;
/** Hinweis unter dem MacBook (Live-Vorschau, Chat, Terminplaner, Pinnwand; bei der Website-Analyse steht dort die Diagnose). */
hinweis?: string;
+ /** Noch nicht für Kunden buchbar: Marke „Bald verfügbar“ am Titel (Terminplaner läuft bisher nur im Pilot, Stand 04.10.2026). */
+ bald?: boolean;
};
+const BaldMarke = ({ f }: { f: Funktion }) => (f.bald ? Bald verfügbar : null);
+
/** Mitte des Knopfes "Aufhängen" im Portal-Screenshot der News-Pinnwand (Designpunkte der iPhone-Fläche 402 x 874). */
const AUFHAENGEN_PUNKT = { x: 201, y: 613 };
@@ -151,6 +155,7 @@ const FUNKTIONEN: Funktion[] = [
id: "terminplaner",
titel: "Terminplaner",
demo: "termin",
+ bald: true,
adresse: "salon-schnittstelle.example",
beschreibung:
"Beispiel-Website eines Friseursalons mit Buchungsformular und einem Kalender, in dem der neue Termin erscheint",
@@ -553,7 +558,10 @@ const Buehne = () => {
onClick={() => springe(d)}
>
- {FUNKTIONEN[d].titel}
+
+ {FUNKTIONEN[d].titel}
+
{beispielText(f)}
{f.bedienhinweis ?{f.bedienhinweis.tippen}
: null} diff --git a/src/components/home/kundenportal.css b/src/components/home/kundenportal.css index cb54a8b..882f971 100644 --- a/src/components/home/kundenportal.css +++ b/src/components/home/kundenportal.css @@ -235,6 +235,20 @@ line-height: 1.2; transition: color var(--dur-state) var(--ease); } +/* „Bald verfügbar“: Funktion noch nicht buchbar */ +.kp-bald { + display: inline-block; + margin-left: 0.5rem; + padding: 0.125rem 0.5rem; + border: 1px solid var(--line-strong); + border-radius: 999px; + color: var(--fg-muted); + font-size: 0.75rem; + font-weight: 600; + line-height: 1.4; + white-space: nowrap; + vertical-align: 0.15em; +} .kp-untereintrag[aria-current="step"] .kp-untereintrag__titel { color: var(--fg); } @@ -495,6 +509,10 @@ .kp-karte__titel { margin-bottom: 0.35rem; } +/* auf der Karte steht die Marke unter dem Titel (die Überschrift bleibt der reine Titel) */ +.kp-karte > .kp-bald { + margin: 0 0 0.5rem; +} .kp-karte__text { max-width: 26ch; } diff --git a/src/test/relaunch-kundenportal.test.tsx b/src/test/relaunch-kundenportal.test.tsx index 04f0767..17debe9 100644 --- a/src/test/relaunch-kundenportal.test.tsx +++ b/src/test/relaunch-kundenportal.test.tsx @@ -129,10 +129,24 @@ describe("Kundenportal: Text und Reihenfolge", () => { expect(unterliste).toHaveAttribute("aria-label", "Funktionen"); expect(unterliste).not.toBeVisible(); const unter = within(unterliste).getAllByRole("button", { hidden: true }); - expect(unter.map((b) => b.textContent)).toEqual(["Terminplaner", "Website-Analyse", "News-Pinnwand"]); + expect(unter.map((b) => b.textContent)).toEqual(["TerminplanerBald verfügbar", "Website-Analyse", "News-Pinnwand"]); expect(liste).not.toHaveTextContent("Heatmap: wohin Besucher klicken"); }); + it("der Terminplaner trägt „Bald verfügbar“ (noch nicht buchbar), die anderen Stationen nicht", () => { + zeigeDesktop(); + const liste = screen.getByRole("list", { name: "Funktionen des Kundenportals" }); + const marken = liste.querySelectorAll(".kp-bald"); + expect(marken).toHaveLength(1); + expect(marken[0].closest("button")).toHaveTextContent(/^Terminplaner/); + cleanup(); + + zeigeHandy(); + const karten = screen.getAllByText("Bald verfügbar"); + expect(karten).toHaveLength(1); + expect(karten[0].closest(".kp-karte")).toContainElement(screen.getByRole("heading", { level: 3, name: "Terminplaner" })); + }); + it("Tablet quer (Bühne ohne Maus): der Bedienhinweis der Website-Analyse sagt „Tippen Sie“ statt „Zeigen Sie mit der Maus“", () => { const { container } = zeigeTablet(); const hinweis = Array.from(container.querySelectorAll(".kp-beispiel")).find((h) => h.textContent?.includes("Tippen")); @@ -335,7 +349,7 @@ describe("Kundenportal: Bühne wechselt mit dem IntersectionObserver", () => { meldeMarke(4); expect(gruppe).toHaveAttribute("aria-expanded", "true"); expect(screen.getByRole("list", { name: "Funktionen" })).toBeVisible(); - expect(aktiverEintrag()).toBe("Terminplaner"); + expect(aktiverEintrag()).toBe("TerminplanerBald verfügbar"); meldeMarke(5); expect(aktiverEintrag()).toBe("Website-Analyse"); meldeMarke(7);