Make checkout's login prompt reactive instead of persistent, and give the confirmation email real style and voice

The always-visible "Schon Kundin?" toggle was gendered and shown to every
logged-out visitor regardless of relevance. Card 1's email field now
checks on blur (/api/account/check-email) whether that address already
has an account, and only then swaps in a gender-neutral login form,
pre-filled — the collision check in handleSubmit stays as a fallback.

The order-confirmation and password-reset emails also got a real visual
pass: same warm background/brand color/circular success-icon treatment as
the on-screen /bestellbestaetigung page, serif heading, thin brand
divider, table-based layout for email-client compatibility. Copy is
on-brand and a little playful now instead of generic transactional
boilerplate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-07-22 08:38:41 +00:00
parent ec75a480bd
commit fa02d95dff
6 changed files with 258 additions and 81 deletions
+17
View File
@@ -43,6 +43,23 @@ export type AuthResult =
| { ok: true; token: string; customer: CustomerSummary }
| { ok: false; reason: string; emailExists?: boolean };
// Called from app/api/account/check-email/route.ts — lets the checkout
// form detect an existing account *before* a submit attempt fails (see
// CheckoutContent.tsx's email field onBlur), not just after. Service-secret
// authenticated (same reasoning as the other service calls in this file) —
// Customers' read access isn't public, and there's no customer session yet
// at this point either way.
export async function checkEmailExists(email: string): Promise<boolean> {
const params = new URLSearchParams({ "where[email][equals]": email, limit: "1" });
const res = await fetch(`${PAYLOAD_URL}/api/customers?${params}`, {
headers: { "x-order-service-secret": SERVICE_SECRET },
cache: "no-store",
});
if (!res.ok) return false;
const data: { docs?: unknown[] } = await res.json();
return (data.docs?.length ?? 0) > 0;
}
export async function registerCustomer(input: {
firstName: string;
lastName: string;