diff --git a/README.md b/README.md index f6588d7..ac306d2 100644 --- a/README.md +++ b/README.md @@ -994,11 +994,26 @@ field appears there when nobody's logged in). There's no persistent and shown to every logged-out visitor regardless of relevance. Instead, the email field's `onBlur` calls `/api/account/check-email` (`checkEmailExists()` in `customerAuth.ts`, service-secret authenticated — -Customers isn't public-read) and only *then* swaps Card 1's password field -out for an inline login form, gender-neutral copy, pre-filled with the -email just typed. `handleSubmit`'s own `emailExists` handling (see -"Checkout registration collisions" below) is the fallback for the case -this check was skipped or raced. +Customers isn't public-read) and only *then* swaps Card 1's own +"Passwort (für dein neues Konto)" field out for an inline login prompt +(password field + "Einloggen" button), gender-neutral copy, rendered +right under the same email field the shopper just typed into rather than +asking for it a second time in a separate field. `handleSubmit`'s own +`emailExists` handling (see "Checkout registration collisions" below) is +the fallback for the case this check was skipped or raced. + +**Fixed 2026-07-24** — this login prompt used to render in a completely +separate block above the whole form (before `
` even opens), which on +a shopper who'd already scrolled down to reach Card 1's email field meant +the prompt popped in off-screen, above their current scroll position, with +no auto-scroll wired up for this common blur-triggered path (only the +submit-time fallback had one). Moved inline into Card 1 itself instead — +no scrolling needed in the common case since it now appears exactly where +the shopper is already looking. The submit-time fallback (see "Checkout +registration collisions" below) still scrolls it into view, now via a +`useEffect` watching `showLogin` rather than a synchronous call at the +`setShowLogin(true)` site — the prompt is conditionally rendered, so its +ref isn't attached to anything yet at that exact synchronous point. - **`app/lib/customerAuth.ts`** (server-only) is the single place that talks to Payload's `customers` collection — a second, fully separate @@ -1080,13 +1095,22 @@ in the header itself, which stays visible above the panel throughout. error, since Payload's own message text doesn't distinguish "duplicate" from other email-field failures) rather than just surfacing a generic error. `CheckoutContent.tsx`'s `handleSubmit` reacts by switching - straight to the login toggle with that email pre-filled and - scroll-into-view, instead of leaving the customer stuck with an error - and no obvious next step. + `showLogin` on (same inline prompt described above — reuses Card 1's + own email field, nothing to pre-fill) and scrolling it into view via a + `useEffect`, instead of leaving the customer stuck with an error and no + obvious next step. `handleLogin()` itself posts the live `email` field + value, not a separate `loginEmail` state — there's only ever one email + input on this form now. - **`/konto/profil`** edits name + the one saved default address (deliberately a single address, not a full address book — see the assistant's memory note on optionally expanding this later), changes the password, shows the email-verification banner, and has the GDPR export/delete section. + Its "Land" ` reads + * (Payload's shipping-countries collection) — this form used to hardcode + * its own Deutschland/Österreich/Schweiz options independently, so a + * country added/removed there never reached the profile page. */ + shippingCountries: ShippingCountry[]; +}) { const router = useRouter(); const [deliveryMethod, setDeliveryMethod] = useState<"address" | "packstation">(profile.deliveryMethod ?? "address"); const [error, setError] = useState(null); @@ -147,9 +158,9 @@ export function ProfileForm({ profile }: { profile: CustomerProfile }) { diff --git a/app/konto/profil/page.tsx b/app/konto/profil/page.tsx index ce8e1da..f4f7a2f 100644 --- a/app/konto/profil/page.tsx +++ b/app/konto/profil/page.tsx @@ -3,6 +3,7 @@ import { redirect } from "next/navigation"; import Link from "next/link"; import { Footer } from "../../components/Footer"; import { getSessionCustomer, getCustomerProfile } from "../../lib/customerAuth"; +import { getShippingCountries } from "../../lib/payload"; import { ProfileForm } from "./components/ProfileForm"; import { PasswordForm } from "./components/PasswordForm"; import { VerificationBanner } from "./components/VerificationBanner"; @@ -21,7 +22,7 @@ export default async function KontoProfilPage({ const session = await getSessionCustomer(); if (!session) redirect("/konto/login"); - const profile = await getCustomerProfile(session.token); + const [profile, shippingCountries] = await Promise.all([getCustomerProfile(session.token), getShippingCountries()]); if (!profile) redirect("/konto/login"); const { verified } = await searchParams; @@ -34,7 +35,7 @@ export default async function KontoProfilPage({ ← Meine Bestellungen - +