Terminplaner: Marke „Bald verfügbar“ (noch nicht für Kunden buchbar)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c1d775e090
commit
4139f31925
3 files changed
+44
-3
No files matched your search
@@ -96,8 +96,12 @@ type Funktion = {
|
|||||||
beschreibung?: string;
|
beschreibung?: string;
|
||||||
/** Hinweis unter dem MacBook (Live-Vorschau, Chat, Terminplaner, Pinnwand; bei der Website-Analyse steht dort die Diagnose). */
|
/** Hinweis unter dem MacBook (Live-Vorschau, Chat, Terminplaner, Pinnwand; bei der Website-Analyse steht dort die Diagnose). */
|
||||||
hinweis?: string;
|
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 ? <span className="kp-bald">Bald verfügbar</span> : null);
|
||||||
|
|
||||||
/** Mitte des Knopfes "Aufhängen" im Portal-Screenshot der News-Pinnwand (Designpunkte der iPhone-Fläche 402 x 874). */
|
/** 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 };
|
const AUFHAENGEN_PUNKT = { x: 201, y: 613 };
|
||||||
|
|
||||||
@@ -151,6 +155,7 @@ const FUNKTIONEN: Funktion[] = [
|
|||||||
id: "terminplaner",
|
id: "terminplaner",
|
||||||
titel: "Terminplaner",
|
titel: "Terminplaner",
|
||||||
demo: "termin",
|
demo: "termin",
|
||||||
|
bald: true,
|
||||||
adresse: "salon-schnittstelle.example",
|
adresse: "salon-schnittstelle.example",
|
||||||
beschreibung:
|
beschreibung:
|
||||||
"Beispiel-Website eines Friseursalons mit Buchungsformular und einem Kalender, in dem der neue Termin erscheint",
|
"Beispiel-Website eines Friseursalons mit Buchungsformular und einem Kalender, in dem der neue Termin erscheint",
|
||||||
@@ -553,7 +558,10 @@ const Buehne = () => {
|
|||||||
onClick={() => springe(d)}
|
onClick={() => springe(d)}
|
||||||
>
|
>
|
||||||
<span className="kp-eintrag__punkt" aria-hidden="true" />
|
<span className="kp-eintrag__punkt" aria-hidden="true" />
|
||||||
<span className="kp-untereintrag__titel">{FUNKTIONEN[d].titel}</span>
|
<span className="kp-untereintrag__titel">
|
||||||
|
{FUNKTIONEN[d].titel}
|
||||||
|
<BaldMarke f={FUNKTIONEN[d]} />
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
@@ -728,6 +736,7 @@ const DemoKarteRahmen = ({
|
|||||||
</HandyRahmen>
|
</HandyRahmen>
|
||||||
</div>
|
</div>
|
||||||
<h3 className="wk-h3 kp-karte__titel">{f.titel}</h3>
|
<h3 className="wk-h3 kp-karte__titel">{f.titel}</h3>
|
||||||
|
<BaldMarke f={f} />
|
||||||
<KartenUnterschrift f={f} />
|
<KartenUnterschrift f={f} />
|
||||||
<p className="kp-karte__beispiel">{beispielText(f)}</p>
|
<p className="kp-karte__beispiel">{beispielText(f)}</p>
|
||||||
{f.bedienhinweis ? <p className="kp-karte__bedienen">{f.bedienhinweis.tippen}</p> : null}
|
{f.bedienhinweis ? <p className="kp-karte__bedienen">{f.bedienhinweis.tippen}</p> : null}
|
||||||
|
|||||||
@@ -235,6 +235,20 @@
|
|||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
transition: color var(--dur-state) var(--ease);
|
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 {
|
.kp-untereintrag[aria-current="step"] .kp-untereintrag__titel {
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
}
|
}
|
||||||
@@ -495,6 +509,10 @@
|
|||||||
.kp-karte__titel {
|
.kp-karte__titel {
|
||||||
margin-bottom: 0.35rem;
|
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 {
|
.kp-karte__text {
|
||||||
max-width: 26ch;
|
max-width: 26ch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,10 +129,24 @@ describe("Kundenportal: Text und Reihenfolge", () => {
|
|||||||
expect(unterliste).toHaveAttribute("aria-label", "Funktionen");
|
expect(unterliste).toHaveAttribute("aria-label", "Funktionen");
|
||||||
expect(unterliste).not.toBeVisible();
|
expect(unterliste).not.toBeVisible();
|
||||||
const unter = within(unterliste).getAllByRole("button", { hidden: true });
|
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");
|
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“", () => {
|
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 { container } = zeigeTablet();
|
||||||
const hinweis = Array.from(container.querySelectorAll(".kp-beispiel")).find((h) => h.textContent?.includes("Tippen"));
|
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);
|
meldeMarke(4);
|
||||||
expect(gruppe).toHaveAttribute("aria-expanded", "true");
|
expect(gruppe).toHaveAttribute("aria-expanded", "true");
|
||||||
expect(screen.getByRole("list", { name: "Funktionen" })).toBeVisible();
|
expect(screen.getByRole("list", { name: "Funktionen" })).toBeVisible();
|
||||||
expect(aktiverEintrag()).toBe("Terminplaner");
|
expect(aktiverEintrag()).toBe("TerminplanerBald verfügbar");
|
||||||
meldeMarke(5);
|
meldeMarke(5);
|
||||||
expect(aktiverEintrag()).toBe("Website-Analyse");
|
expect(aktiverEintrag()).toBe("Website-Analyse");
|
||||||
meldeMarke(7);
|
meldeMarke(7);
|
||||||
|
|||||||
Reference in new issue
Block a user