Add password reset, order confirmation email with editable templates, and fix missing account entry points

Password reset uses Payload's built-in forgot/reset-password flow,
customized to link to this app instead of the Payload admin. Order
confirmation email and the password-reset email's wording both come from
a new Payload email-templates collection, editable without a deploy and
previewable via Live Preview at /email-preview/[type] (same mechanism as
Posts/LegalPages/Testimonials, sample data instead of a real document).

Also: order numbers get a random suffix (prevents guessing, motivated by
a considered-and-deferred guest order-lookup feature); the discount code
field only shows in the cart when a code is actually active (codes now
apply via a ?code= link instead of manual entry); and three navigation
gaps found while testing — no reachable login link with an empty cart, no
logout link anywhere, no way back from profile to order history.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-07-22 08:14:08 +00:00
parent adca6e0f64
commit f0df359db4
26 changed files with 865 additions and 81 deletions
+16 -10
View File
@@ -311,16 +311,22 @@ export function CheckoutContent({
{/* Only needed for the inline-registration path — an existing
session already has an account, no password to collect. */}
{!customerEmail && (
<FormField
label="Passwort (für dein neues Konto)"
name="password"
type="password"
placeholder="Mind. 8 Zeichen"
autoComplete="new-password"
required
minLength={8}
wrapperClassName="w-full sm:w-[calc(50%-0.5rem)] sm:flex-none min-w-0"
/>
<div className="flex flex-col gap-2 w-full sm:w-[calc(50%-0.5rem)] sm:flex-none min-w-0">
<FormField
label="Passwort (für dein neues Konto)"
name="password"
type="password"
placeholder="Mind. 8 Zeichen"
autoComplete="new-password"
required
minLength={8}
wrapperClassName="w-full"
/>
<p className="text-label text-text-muted">
Mit dem Kauf legen wir automatisch ein Konto für dich an damit du deine Bestellungen später
einsehen und bei Bedarf stornieren oder zurücksenden kannst.
</p>
</div>
)}
{/* Segmented control, same sm:w-[calc(50%-0.5rem)] half-row
width as the field(s) below it — Lieferadresse keeps