@asteby/storefront-react 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/account.cjs +114 -0
- package/dist/account.cjs.map +1 -1
- package/dist/account.d.cts +60 -4
- package/dist/account.d.ts +60 -4
- package/dist/account.js +113 -1
- package/dist/account.js.map +1 -1
- package/dist/checkout.cjs +65 -14
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.d.cts +7 -0
- package/dist/checkout.d.ts +7 -0
- package/dist/checkout.js +65 -14
- package/dist/checkout.js.map +1 -1
- package/dist/payments.cjs +86 -15
- package/dist/payments.cjs.map +1 -1
- package/dist/payments.css +65 -0
- package/dist/payments.d.cts +24 -3
- package/dist/payments.d.ts +24 -3
- package/dist/payments.js +86 -15
- package/dist/payments.js.map +1 -1
- package/package.json +2 -2
package/dist/account.js
CHANGED
|
@@ -207,7 +207,119 @@ function AccountAuth({ capabilities, data, next, pending = false, initialView, f
|
|
|
207
207
|
] })
|
|
208
208
|
] });
|
|
209
209
|
}
|
|
210
|
+
var ES2 = {
|
|
211
|
+
title: "Crea tu cuenta para seguir tu pedido",
|
|
212
|
+
benefit: "Con {email} ver\xE1s aqu\xED tu pedido y su env\xEDo, y la pr\xF3xima compra ser\xE1 m\xE1s r\xE1pida. No te pedimos tu direcci\xF3n ni tu tel\xE9fono otra vez.",
|
|
213
|
+
benefitBasic: "Guarda tus datos para que la pr\xF3xima compra sea m\xE1s r\xE1pida.",
|
|
214
|
+
accountFor: "Cuenta para {email}",
|
|
215
|
+
password: "Contrase\xF1a",
|
|
216
|
+
passwordHint: "Entre 10 y 128 caracteres.",
|
|
217
|
+
code: "C\xF3digo",
|
|
218
|
+
codeSentTo: "Enviamos un c\xF3digo a {email}. Puede tardar un minuto.",
|
|
219
|
+
submit: "Crear cuenta",
|
|
220
|
+
submitOtp: "Enviarme un c\xF3digo",
|
|
221
|
+
submitCode: "Confirmar",
|
|
222
|
+
skipNote: "Si no quieres cuenta, no pasa nada: te avisaremos por correo de tu pedido.",
|
|
223
|
+
loginLink: "Ya tengo cuenta",
|
|
224
|
+
errors: {
|
|
225
|
+
invalid_credentials: "El correo o la contrase\xF1a no coinciden.",
|
|
226
|
+
invalid_code: "El c\xF3digo no es v\xE1lido o ya venci\xF3.",
|
|
227
|
+
email_taken: "Ya existe una cuenta con este correo. Entra para ver tu pedido.",
|
|
228
|
+
rate_limited: "Demasiados intentos. Espera unos minutos e int\xE9ntalo de nuevo.",
|
|
229
|
+
validation: "Revisa los datos e int\xE9ntalo de nuevo.",
|
|
230
|
+
unsupported: "Esta tienda no permite crear cuentas por ahora.",
|
|
231
|
+
store_misconfigured: "No pudimos crear tu cuenta por un problema de configuraci\xF3n de la tienda. Tu pedido sigue en pie.",
|
|
232
|
+
unavailable: "No pudimos completar la acci\xF3n. Int\xE9ntalo de nuevo en un momento."
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
var EN2 = {
|
|
236
|
+
title: "Create your account to follow your order",
|
|
237
|
+
benefit: "With {email} you will see your order and its shipment here, and your next purchase will be faster. We will not ask for your address or phone again.",
|
|
238
|
+
benefitBasic: "Save your details so your next purchase is faster.",
|
|
239
|
+
accountFor: "Account for {email}",
|
|
240
|
+
password: "Password",
|
|
241
|
+
passwordHint: "Between 10 and 128 characters.",
|
|
242
|
+
code: "Code",
|
|
243
|
+
codeSentTo: "We sent a code to {email}. It can take a minute.",
|
|
244
|
+
submit: "Create account",
|
|
245
|
+
submitOtp: "Email me a code",
|
|
246
|
+
submitCode: "Confirm",
|
|
247
|
+
skipNote: "If you do not want an account, that is fine: we will email you about your order.",
|
|
248
|
+
loginLink: "I already have an account",
|
|
249
|
+
errors: {
|
|
250
|
+
invalid_credentials: "The email and password do not match.",
|
|
251
|
+
invalid_code: "The code is not valid or has expired.",
|
|
252
|
+
email_taken: "An account with this email already exists. Sign in to see your order.",
|
|
253
|
+
rate_limited: "Too many attempts. Wait a few minutes and try again.",
|
|
254
|
+
validation: "Check the details and try again.",
|
|
255
|
+
unsupported: "This store does not allow creating accounts right now.",
|
|
256
|
+
store_misconfigured: "We could not create your account because of a store configuration problem. Your order is safe.",
|
|
257
|
+
unavailable: "We could not complete that. Try again in a moment."
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
function postPurchaseAccountPromptMessages(locale, overrides) {
|
|
261
|
+
const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN2 : ES2;
|
|
262
|
+
if (!overrides) return base;
|
|
263
|
+
return { ...base, ...overrides, errors: { ...base.errors, ...overrides.errors } };
|
|
264
|
+
}
|
|
265
|
+
var validEmail = (v) => typeof v === "string" && v.length <= 254 && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v.trim());
|
|
266
|
+
function PostPurchaseAccountPrompt({
|
|
267
|
+
email,
|
|
268
|
+
capabilities,
|
|
269
|
+
data,
|
|
270
|
+
next,
|
|
271
|
+
pending = false,
|
|
272
|
+
form: FormTag = "form",
|
|
273
|
+
action,
|
|
274
|
+
headingLevel = 2,
|
|
275
|
+
loginHref,
|
|
276
|
+
locale,
|
|
277
|
+
messages,
|
|
278
|
+
classNames: cx = {},
|
|
279
|
+
children
|
|
280
|
+
}) {
|
|
281
|
+
const m = postPurchaseAccountPromptMessages(locale, messages);
|
|
282
|
+
const ref = useRef(null);
|
|
283
|
+
const passwordOn = capabilities.password;
|
|
284
|
+
const otpOn = capabilities.otp_channels.includes("email");
|
|
285
|
+
const errorText = data?.error ? m.errors[data.error.code] : null;
|
|
286
|
+
const v = useFieldErrors(ref, { ...locale ? { locale } : {}, serverFields: data?.error?.field === "code" || data?.error?.field === "password" ? [data.error.field] : null, serverMessages: data?.error?.field && errorText ? { [data.error.field]: errorText } : null });
|
|
287
|
+
if (!validEmail(email) || !passwordOn && !otpOn) return null;
|
|
288
|
+
const address = email.trim().toLowerCase();
|
|
289
|
+
const step = data?.step === "verify" || data?.step === "otp" ? data.step : null;
|
|
290
|
+
const view = step ?? (passwordOn ? "register" : "otp-request");
|
|
291
|
+
const intent = step === "verify" ? "verify" : step === "otp" ? "otp-login" : passwordOn ? "register" : "otp-request";
|
|
292
|
+
const label = view === "verify" || view === "otp" ? m.submitCode : view === "otp-request" ? m.submitOtp : m.submit;
|
|
293
|
+
const Heading = `h${headingLevel}`;
|
|
294
|
+
const fieldProps = { classNames: cx.field, ...locale ? { locale } : {} };
|
|
295
|
+
const showAlert = errorText && !(data?.error?.field === "code" || data?.error?.field === "password");
|
|
296
|
+
const benefit = (capabilities.email_verification ? m.benefit : m.benefitBasic).replace("{email}", address);
|
|
297
|
+
return /* @__PURE__ */ jsxs("section", { className: cx.root, "data-sf-ppa": true, "data-sf-ppa-view": view, "aria-labelledby": "sf-ppa-title", children: [
|
|
298
|
+
/* @__PURE__ */ jsx(Heading, { id: "sf-ppa-title", className: cx.title, children: m.title }),
|
|
299
|
+
/* @__PURE__ */ jsx("p", { className: cx.text, "data-sf-ppa-benefit": true, children: benefit }),
|
|
300
|
+
/* @__PURE__ */ jsxs(FormTag, { ref, method: "post", ...action ? { action } : {}, className: cx.form, "data-sf-ppa-form": true, children: [
|
|
301
|
+
/* @__PURE__ */ jsx(ErrorSummary, { items: v.summary, focusKey: v.summaryKey, ...locale ? { locale } : {} }),
|
|
302
|
+
showAlert ? /* @__PURE__ */ jsx("p", { role: "alert", className: cx.error, "data-sf-ppa-error": data.error.code, children: errorText }) : null,
|
|
303
|
+
/* @__PURE__ */ jsx("input", { type: "hidden", name: "email", value: address }),
|
|
304
|
+
next ? /* @__PURE__ */ jsx("input", { type: "hidden", name: "next", value: next }) : null,
|
|
305
|
+
/* @__PURE__ */ jsx("p", { className: cx.email, "data-sf-ppa-email": true, children: m.accountFor.replace("{email}", address) }),
|
|
306
|
+
step ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
307
|
+
/* @__PURE__ */ jsx("p", { className: cx.notice, role: "status", "data-sf-ppa-notice": true, children: m.codeSentTo.replace("{email}", address) }),
|
|
308
|
+
/* @__PURE__ */ jsx(CheckoutField, { ...fieldProps, name: "code", label: m.code, autoComplete: "one-time-code", inputMode: "numeric", pattern: "[0-9]*", error: v.errors.code ?? null })
|
|
309
|
+
] }) : passwordOn ? /* @__PURE__ */ jsx(CheckoutField, { ...fieldProps, name: "password", type: "password", label: m.password, autoComplete: "new-password", minLength: 10, maxLength: 128, hint: m.passwordHint, error: v.errors.password ?? null }) : null,
|
|
310
|
+
/* @__PURE__ */ jsx("div", { className: cx.actions, children: /* @__PURE__ */ jsx("button", { type: "submit", name: "intent", value: intent, disabled: pending, className: cx.submit, "data-sf-ppa-submit": true, children: label }) })
|
|
311
|
+
] }),
|
|
312
|
+
/* @__PURE__ */ jsxs("p", { className: cx.note, "data-sf-ppa-note": true, children: [
|
|
313
|
+
m.skipNote,
|
|
314
|
+
loginHref ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
315
|
+
" ",
|
|
316
|
+
/* @__PURE__ */ jsx("a", { href: loginHref, className: cx.link, "data-sf-ppa-login": true, children: m.loginLink })
|
|
317
|
+
] }) : null
|
|
318
|
+
] }),
|
|
319
|
+
children
|
|
320
|
+
] });
|
|
321
|
+
}
|
|
210
322
|
|
|
211
|
-
export { AccountAuth, accountAuthMessages };
|
|
323
|
+
export { AccountAuth, PostPurchaseAccountPrompt, accountAuthMessages, postPurchaseAccountPromptMessages };
|
|
212
324
|
//# sourceMappingURL=account.js.map
|
|
213
325
|
//# sourceMappingURL=account.js.map
|
package/dist/account.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/account/account-auth.tsx"],"names":[],"mappings":"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","file":"account.js","sourcesContent":["/**\n * The account screen: sign in with password, create an account, verify the emailed code, sign in with a code and\n * recover a forgotten password, in one `<form method=\"post\">` driven by `createAuthAction` (`./server`). What the store\n * offers comes from `loadAuthCapabilities`; the form shows only that. Plain HTML: it works without JavaScript for the\n * password sign-in and the steps the action sends back; the view switches (links) need JavaScript.\n *\n * Styling: `data-sf-account-*` attributes and `classNames` slots, fields reuse `CheckoutField` (and `checkout.css`);\n * `account.css` is an optional neutral sheet. Texts are Spanish by default, English with `locale=\"en\"`, any with `messages`.\n */\nimport { useEffect, useRef, useState, type ComponentType, type ReactNode } from 'react'\nimport type { CustomerCapabilities } from '@asteby/storefront'\nimport { CheckoutField, ErrorSummary, useFieldErrors, type CheckoutFieldClassNames } from '../checkout/fields.js'\nimport type { AuthActionData, AuthErrorCode, AuthStep } from './types.js'\n\nexport type AccountAuthView = 'login' | 'register' | 'otp-email' | 'forgot' | AuthStep\n\nexport type AccountAuthMessages = {\n titles: Record<AccountAuthView, string>\n email: string\n password: string\n newPassword: string\n passwordHint: string\n firstName: string\n lastName: string\n code: string\n codeSentTo: string\n submit: Record<AccountAuthView, string>\n resend: string\n forgotLink: string\n registerLink: string\n loginLink: string\n otpLink: string\n backToLogin: string\n nothingAvailable: string\n errors: Record<AuthErrorCode, string>\n}\n\nconst ES: AccountAuthMessages = {\n titles: {\n login: 'Entrar a tu cuenta',\n register: 'Crear una cuenta',\n verify: 'Confirma tu correo',\n 'otp-email': 'Entrar con un código',\n otp: 'Escribe tu código',\n forgot: 'Recuperar contraseña',\n reset: 'Elige una contraseña nueva',\n },\n email: 'Correo electrónico',\n password: 'Contraseña',\n newPassword: 'Contraseña nueva',\n passwordHint: 'Entre 10 y 128 caracteres.',\n firstName: 'Nombre',\n lastName: 'Apellido',\n code: 'Código',\n codeSentTo: 'Enviamos un código a {email}. Puede tardar un minuto.',\n submit: {\n login: 'Entrar',\n register: 'Crear cuenta',\n verify: 'Confirmar',\n 'otp-email': 'Enviarme el código',\n otp: 'Entrar',\n forgot: 'Enviarme el código',\n reset: 'Guardar y entrar',\n },\n resend: 'Reenviar código',\n forgotLink: '¿Olvidaste tu contraseña?',\n registerLink: 'Crear una cuenta',\n loginLink: 'Ya tengo cuenta',\n otpLink: 'Entrar con un código por correo',\n backToLogin: 'Volver a entrar con contraseña',\n nothingAvailable: 'Esta tienda no admite iniciar sesión por ahora.',\n errors: {\n invalid_credentials: 'El correo o la contraseña no coinciden.',\n invalid_code: 'El código no es válido o ya venció.',\n email_taken: 'Ya existe una cuenta con este correo. Entra o recupera tu contraseña.',\n rate_limited: 'Demasiados intentos. Espera unos minutos e inténtalo de nuevo.',\n validation: 'Revisa los datos e inténtalo de nuevo.',\n unsupported: 'Esta forma de entrar no está disponible en esta tienda.',\n store_misconfigured: 'No pudimos crear tu cuenta por un problema de configuración de la tienda. Puedes comprar como invitado; ya avisamos a la tienda.',\n unavailable: 'No pudimos completar la acción. Inténtalo de nuevo en un momento.',\n },\n}\n\nconst EN: AccountAuthMessages = {\n titles: {\n login: 'Sign in',\n register: 'Create an account',\n verify: 'Confirm your email',\n 'otp-email': 'Sign in with a code',\n otp: 'Enter your code',\n forgot: 'Reset your password',\n reset: 'Choose a new password',\n },\n email: 'Email',\n password: 'Password',\n newPassword: 'New password',\n passwordHint: 'Between 10 and 128 characters.',\n firstName: 'First name',\n lastName: 'Last name',\n code: 'Code',\n codeSentTo: 'We sent a code to {email}. It can take a minute.',\n submit: {\n login: 'Sign in',\n register: 'Create account',\n verify: 'Confirm',\n 'otp-email': 'Email me the code',\n otp: 'Sign in',\n forgot: 'Email me the code',\n reset: 'Save and sign in',\n },\n resend: 'Resend code',\n forgotLink: 'Forgot your password?',\n registerLink: 'Create an account',\n loginLink: 'I already have an account',\n otpLink: 'Sign in with an emailed code',\n backToLogin: 'Back to password sign-in',\n nothingAvailable: 'This store does not support signing in right now.',\n errors: {\n invalid_credentials: 'The email and password do not match.',\n invalid_code: 'The code is not valid or has expired.',\n email_taken: 'An account with this email already exists. Sign in or reset your password.',\n rate_limited: 'Too many attempts. Wait a few minutes and try again.',\n validation: 'Check the details and try again.',\n unsupported: 'This way of signing in is not available in this store.',\n store_misconfigured: 'We could not create your account because of a store configuration problem. You can check out as a guest; we have already told the store.',\n unavailable: 'We could not complete that. Try again in a moment.',\n },\n}\n\n/** Messages for a locale (`es*` default, `en*`), with optional overrides (nested `titles`/`submit`/`errors` merge). */\nexport function accountAuthMessages(locale?: string | null, overrides?: DeepPartial<AccountAuthMessages> | null): AccountAuthMessages {\n const base = (locale ?? 'es-MX').toLowerCase().startsWith('en') ? EN : ES\n if (!overrides) return base\n return {\n ...base,\n ...(overrides as Partial<AccountAuthMessages>),\n titles: { ...base.titles, ...overrides.titles },\n submit: { ...base.submit, ...overrides.submit },\n errors: { ...base.errors, ...overrides.errors },\n }\n}\n\ntype DeepPartial<T> = { [K in keyof T]?: T[K] extends Record<string, string> ? Partial<T[K]> : T[K] }\n\nexport type AccountAuthClassNames = Partial<Record<'root' | 'title' | 'form' | 'notice' | 'error' | 'actions' | 'submit' | 'links' | 'link', string>> & {\n field?: CheckoutFieldClassNames\n}\n\n/** What `<AccountAuth>` passes to its `form` component: the few props a router `Form` and the HTML `<form>` both accept. */\nexport type AccountFormProps = {\n method?: 'post'\n action?: string\n className?: string\n children?: ReactNode\n /** Loose on purpose: a router `Form` types its ref with its own copy of `@types/react`. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ref?: any\n 'data-sf-account-form'?: boolean | string\n}\n\nexport type AccountAuthProps = {\n /** From `loadAuthCapabilities` (the loader). */\n capabilities: CustomerCapabilities\n /** What the action returned (`useActionData()`); drives the next screen and the errors. */\n data?: AuthActionData | null\n /** Where to go after signing in (sent as `next`; the server validates it). */\n next?: string | null\n /** A submit is in flight (`navigation.state !== 'idle'`): disables the buttons. */\n pending?: boolean\n /** First screen. Default `login`, or `otp-email` when the store has no password sign-in. */\n initialView?: AccountAuthView\n /** Form component, e.g. React Router's `Form`, to submit without a reload. It must forward `ref` to the `<form>` (React 19: a prop). Default: the HTML `<form>`. */\n form?: 'form' | ComponentType<AccountFormProps>\n /** `action` of the form (default: the current URL). */\n action?: string\n locale?: string\n messages?: DeepPartial<AccountAuthMessages>\n classNames?: AccountAuthClassNames\n /** Shown above the form (a logo, a welcome text). */\n header?: ReactNode\n}\n\nconst initialOf = (caps: CustomerCapabilities, initialView?: AccountAuthView): AccountAuthView =>\n initialView ?? (caps.password ? 'login' : caps.otp_channels.includes('email') ? 'otp-email' : 'login')\n\n/**\n * The whole account screen. Headless enough to restyle, complete enough to drop in:\n * `export default function Account() { return <AccountAuth capabilities={useLoaderData()} data={useActionData()} form={Form} /> }`.\n */\nexport function AccountAuth({ capabilities, data, next, pending = false, initialView, form: FormTag = 'form', action, locale, messages, classNames: cx = {}, header }: AccountAuthProps) {\n const m = accountAuthMessages(locale, messages)\n const passwordOn = capabilities.password\n const otpOn = capabilities.otp_channels.includes('email')\n const [view, setView] = useState<AccountAuthView>(() => data?.step ?? initialOf(capabilities, initialView))\n const [email, setEmail] = useState(data?.email ?? '')\n const ref = useRef<HTMLFormElement>(null)\n const serverFields = data?.error?.field ? [data.error.field] : null\n const errorText = data?.error ? m.errors[data.error.code] : null\n const v = useFieldErrors(ref, { ...(locale ? { locale } : {}), serverFields, serverMessages: data?.error?.field && errorText ? { [data.error.field]: errorText } : null })\n\n // The action decides the next screen; the email it carries survives it.\n useEffect(() => {\n if (data?.step) setView(data.step)\n if (data?.email) setEmail(data.email)\n }, [data])\n\n const go = (to: AccountAuthView) => {\n v.clear()\n setView(to)\n }\n const fieldProps = { classNames: cx.field, ...(locale ? { locale } : {}) }\n const emailField = (\n <CheckoutField {...fieldProps} name=\"email\" type=\"email\" label={m.email} autoComplete=\"email\" inputMode=\"email\" value={email} onChange={(e) => setEmail(e.currentTarget.value)} error={v.errors.email ?? null} />\n )\n const codeField = (\n <CheckoutField {...fieldProps} name=\"code\" label={m.code} autoComplete=\"one-time-code\" inputMode=\"numeric\" pattern=\"[0-9]*\" error={v.errors.code ?? null} />\n )\n const passwordField = (label: string, autoComplete: string, newPassword: boolean) => (\n <CheckoutField\n {...fieldProps}\n name=\"password\"\n type=\"password\"\n label={label}\n autoComplete={autoComplete}\n error={v.errors.password ?? null}\n {...(newPassword ? { minLength: 10, maxLength: 128, hint: m.passwordHint } : {})}\n />\n )\n const link = (to: AccountAuthView, text: string) => (\n <button type=\"button\" className={cx.link} data-sf-account-link={to} onClick={() => go(to)}>\n {text}\n </button>\n )\n\n let body: ReactNode\n let links: ReactNode = null\n switch (view) {\n case 'register':\n body = (\n <>\n <CheckoutField {...fieldProps} name=\"first_name\" label={m.firstName} autoComplete=\"given-name\" optional />\n <CheckoutField {...fieldProps} name=\"last_name\" label={m.lastName} autoComplete=\"family-name\" optional />\n {emailField}\n {passwordField(m.password, 'new-password', true)}\n </>\n )\n links = link('login', m.loginLink)\n break\n case 'verify':\n case 'otp':\n body = (\n <>\n <p className={cx.notice} data-sf-account-notice>\n {m.codeSentTo.replace('{email}', email)}\n </p>\n <input type=\"hidden\" name=\"email\" value={email} />\n {codeField}\n </>\n )\n links = (\n <>\n {view === 'otp' ? (\n <button type=\"submit\" name=\"intent\" value=\"otp-request\" formNoValidate className={cx.link} data-sf-account-link=\"resend\">\n {m.resend}\n </button>\n ) : null}\n {link('login', m.backToLogin)}\n </>\n )\n break\n case 'otp-email':\n case 'forgot':\n body = emailField\n links = link('login', m.backToLogin)\n break\n case 'reset':\n body = (\n <>\n <p className={cx.notice} data-sf-account-notice>\n {m.codeSentTo.replace('{email}', email)}\n </p>\n <input type=\"hidden\" name=\"email\" value={email} />\n {codeField}\n {passwordField(m.newPassword, 'new-password', true)}\n </>\n )\n links = link('login', m.backToLogin)\n break\n default:\n body = (\n <>\n {emailField}\n {passwordField(m.password, 'current-password', false)}\n </>\n )\n links = (\n <>\n {otpOn ? link('forgot', m.forgotLink) : null}\n {link('register', m.registerLink)}\n {otpOn ? link('otp-email', m.otpLink) : null}\n </>\n )\n }\n\n const intent = { login: 'login', register: 'register', verify: 'verify', 'otp-email': 'otp-request', otp: 'otp-login', forgot: 'forgot', reset: 'reset' }[view]\n // Without password accounts the password views do not exist; only the code sign-in does.\n const available = view === 'login' || view === 'register' || view === 'forgot' || view === 'reset' || view === 'verify' ? passwordOn : otpOn\n const showSummary = !data?.error?.field\n const title = m.titles[view]\n if (!available && !passwordOn && !otpOn) {\n return (\n <section className={cx.root} data-sf-account-auth data-sf-account-view=\"unavailable\">\n <p className={cx.notice} role=\"status\">\n {capabilities.unavailable_reason === 'missing_scope' ? m.errors.store_misconfigured : m.nothingAvailable}\n </p>\n </section>\n )\n }\n return (\n <section className={cx.root} data-sf-account-auth data-sf-account-view={view} aria-labelledby=\"sf-account-title\">\n {header}\n <h1 id=\"sf-account-title\" className={cx.title}>\n {title}\n </h1>\n <FormTag ref={ref as never} method=\"post\" {...(action ? { action } : {})} className={cx.form} data-sf-account-form>\n <ErrorSummary items={v.summary} focusKey={v.summaryKey} {...(locale ? { locale } : {})} />\n {errorText && showSummary ? (\n <p role=\"alert\" className={cx.error} data-sf-account-error={data!.error!.code}>\n {errorText}\n </p>\n ) : null}\n {next ? <input type=\"hidden\" name=\"next\" value={next} /> : null}\n {body}\n <div className={cx.actions}>\n <button type=\"submit\" name=\"intent\" value={intent} disabled={pending} className={cx.submit} data-sf-account-submit>\n {m.submit[view]}\n </button>\n </div>\n <div className={cx.links} data-sf-account-links>\n {links}\n </div>\n </FormTag>\n </section>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/account/account-auth.tsx","../src/account/post-purchase-prompt.tsx"],"names":["ES","EN","useRef","jsxs","jsx","Fragment"],"mappings":"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","file":"account.js","sourcesContent":["/**\n * The account screen: sign in with password, create an account, verify the emailed code, sign in with a code and\n * recover a forgotten password, in one `<form method=\"post\">` driven by `createAuthAction` (`./server`). What the store\n * offers comes from `loadAuthCapabilities`; the form shows only that. Plain HTML: it works without JavaScript for the\n * password sign-in and the steps the action sends back; the view switches (links) need JavaScript.\n *\n * Styling: `data-sf-account-*` attributes and `classNames` slots, fields reuse `CheckoutField` (and `checkout.css`);\n * `account.css` is an optional neutral sheet. Texts are Spanish by default, English with `locale=\"en\"`, any with `messages`.\n */\nimport { useEffect, useRef, useState, type ComponentType, type ReactNode } from 'react'\nimport type { CustomerCapabilities } from '@asteby/storefront'\nimport { CheckoutField, ErrorSummary, useFieldErrors, type CheckoutFieldClassNames } from '../checkout/fields.js'\nimport type { AuthActionData, AuthErrorCode, AuthStep } from './types.js'\n\nexport type AccountAuthView = 'login' | 'register' | 'otp-email' | 'forgot' | AuthStep\n\nexport type AccountAuthMessages = {\n titles: Record<AccountAuthView, string>\n email: string\n password: string\n newPassword: string\n passwordHint: string\n firstName: string\n lastName: string\n code: string\n codeSentTo: string\n submit: Record<AccountAuthView, string>\n resend: string\n forgotLink: string\n registerLink: string\n loginLink: string\n otpLink: string\n backToLogin: string\n nothingAvailable: string\n errors: Record<AuthErrorCode, string>\n}\n\nconst ES: AccountAuthMessages = {\n titles: {\n login: 'Entrar a tu cuenta',\n register: 'Crear una cuenta',\n verify: 'Confirma tu correo',\n 'otp-email': 'Entrar con un código',\n otp: 'Escribe tu código',\n forgot: 'Recuperar contraseña',\n reset: 'Elige una contraseña nueva',\n },\n email: 'Correo electrónico',\n password: 'Contraseña',\n newPassword: 'Contraseña nueva',\n passwordHint: 'Entre 10 y 128 caracteres.',\n firstName: 'Nombre',\n lastName: 'Apellido',\n code: 'Código',\n codeSentTo: 'Enviamos un código a {email}. Puede tardar un minuto.',\n submit: {\n login: 'Entrar',\n register: 'Crear cuenta',\n verify: 'Confirmar',\n 'otp-email': 'Enviarme el código',\n otp: 'Entrar',\n forgot: 'Enviarme el código',\n reset: 'Guardar y entrar',\n },\n resend: 'Reenviar código',\n forgotLink: '¿Olvidaste tu contraseña?',\n registerLink: 'Crear una cuenta',\n loginLink: 'Ya tengo cuenta',\n otpLink: 'Entrar con un código por correo',\n backToLogin: 'Volver a entrar con contraseña',\n nothingAvailable: 'Esta tienda no admite iniciar sesión por ahora.',\n errors: {\n invalid_credentials: 'El correo o la contraseña no coinciden.',\n invalid_code: 'El código no es válido o ya venció.',\n email_taken: 'Ya existe una cuenta con este correo. Entra o recupera tu contraseña.',\n rate_limited: 'Demasiados intentos. Espera unos minutos e inténtalo de nuevo.',\n validation: 'Revisa los datos e inténtalo de nuevo.',\n unsupported: 'Esta forma de entrar no está disponible en esta tienda.',\n store_misconfigured: 'No pudimos crear tu cuenta por un problema de configuración de la tienda. Puedes comprar como invitado; ya avisamos a la tienda.',\n unavailable: 'No pudimos completar la acción. Inténtalo de nuevo en un momento.',\n },\n}\n\nconst EN: AccountAuthMessages = {\n titles: {\n login: 'Sign in',\n register: 'Create an account',\n verify: 'Confirm your email',\n 'otp-email': 'Sign in with a code',\n otp: 'Enter your code',\n forgot: 'Reset your password',\n reset: 'Choose a new password',\n },\n email: 'Email',\n password: 'Password',\n newPassword: 'New password',\n passwordHint: 'Between 10 and 128 characters.',\n firstName: 'First name',\n lastName: 'Last name',\n code: 'Code',\n codeSentTo: 'We sent a code to {email}. It can take a minute.',\n submit: {\n login: 'Sign in',\n register: 'Create account',\n verify: 'Confirm',\n 'otp-email': 'Email me the code',\n otp: 'Sign in',\n forgot: 'Email me the code',\n reset: 'Save and sign in',\n },\n resend: 'Resend code',\n forgotLink: 'Forgot your password?',\n registerLink: 'Create an account',\n loginLink: 'I already have an account',\n otpLink: 'Sign in with an emailed code',\n backToLogin: 'Back to password sign-in',\n nothingAvailable: 'This store does not support signing in right now.',\n errors: {\n invalid_credentials: 'The email and password do not match.',\n invalid_code: 'The code is not valid or has expired.',\n email_taken: 'An account with this email already exists. Sign in or reset your password.',\n rate_limited: 'Too many attempts. Wait a few minutes and try again.',\n validation: 'Check the details and try again.',\n unsupported: 'This way of signing in is not available in this store.',\n store_misconfigured: 'We could not create your account because of a store configuration problem. You can check out as a guest; we have already told the store.',\n unavailable: 'We could not complete that. Try again in a moment.',\n },\n}\n\n/** Messages for a locale (`es*` default, `en*`), with optional overrides (nested `titles`/`submit`/`errors` merge). */\nexport function accountAuthMessages(locale?: string | null, overrides?: DeepPartial<AccountAuthMessages> | null): AccountAuthMessages {\n const base = (locale ?? 'es-MX').toLowerCase().startsWith('en') ? EN : ES\n if (!overrides) return base\n return {\n ...base,\n ...(overrides as Partial<AccountAuthMessages>),\n titles: { ...base.titles, ...overrides.titles },\n submit: { ...base.submit, ...overrides.submit },\n errors: { ...base.errors, ...overrides.errors },\n }\n}\n\ntype DeepPartial<T> = { [K in keyof T]?: T[K] extends Record<string, string> ? Partial<T[K]> : T[K] }\n\nexport type AccountAuthClassNames = Partial<Record<'root' | 'title' | 'form' | 'notice' | 'error' | 'actions' | 'submit' | 'links' | 'link', string>> & {\n field?: CheckoutFieldClassNames\n}\n\n/** What `<AccountAuth>` passes to its `form` component: the few props a router `Form` and the HTML `<form>` both accept. */\nexport type AccountFormProps = {\n method?: 'post'\n action?: string\n className?: string\n children?: ReactNode\n /** Loose on purpose: a router `Form` types its ref with its own copy of `@types/react`. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ref?: any\n 'data-sf-account-form'?: boolean | string\n}\n\nexport type AccountAuthProps = {\n /** From `loadAuthCapabilities` (the loader). */\n capabilities: CustomerCapabilities\n /** What the action returned (`useActionData()`); drives the next screen and the errors. */\n data?: AuthActionData | null\n /** Where to go after signing in (sent as `next`; the server validates it). */\n next?: string | null\n /** A submit is in flight (`navigation.state !== 'idle'`): disables the buttons. */\n pending?: boolean\n /** First screen. Default `login`, or `otp-email` when the store has no password sign-in. */\n initialView?: AccountAuthView\n /** Form component, e.g. React Router's `Form`, to submit without a reload. It must forward `ref` to the `<form>` (React 19: a prop). Default: the HTML `<form>`. */\n form?: 'form' | ComponentType<AccountFormProps>\n /** `action` of the form (default: the current URL). */\n action?: string\n locale?: string\n messages?: DeepPartial<AccountAuthMessages>\n classNames?: AccountAuthClassNames\n /** Shown above the form (a logo, a welcome text). */\n header?: ReactNode\n}\n\nconst initialOf = (caps: CustomerCapabilities, initialView?: AccountAuthView): AccountAuthView =>\n initialView ?? (caps.password ? 'login' : caps.otp_channels.includes('email') ? 'otp-email' : 'login')\n\n/**\n * The whole account screen. Headless enough to restyle, complete enough to drop in:\n * `export default function Account() { return <AccountAuth capabilities={useLoaderData()} data={useActionData()} form={Form} /> }`.\n */\nexport function AccountAuth({ capabilities, data, next, pending = false, initialView, form: FormTag = 'form', action, locale, messages, classNames: cx = {}, header }: AccountAuthProps) {\n const m = accountAuthMessages(locale, messages)\n const passwordOn = capabilities.password\n const otpOn = capabilities.otp_channels.includes('email')\n const [view, setView] = useState<AccountAuthView>(() => data?.step ?? initialOf(capabilities, initialView))\n const [email, setEmail] = useState(data?.email ?? '')\n const ref = useRef<HTMLFormElement>(null)\n const serverFields = data?.error?.field ? [data.error.field] : null\n const errorText = data?.error ? m.errors[data.error.code] : null\n const v = useFieldErrors(ref, { ...(locale ? { locale } : {}), serverFields, serverMessages: data?.error?.field && errorText ? { [data.error.field]: errorText } : null })\n\n // The action decides the next screen; the email it carries survives it.\n useEffect(() => {\n if (data?.step) setView(data.step)\n if (data?.email) setEmail(data.email)\n }, [data])\n\n const go = (to: AccountAuthView) => {\n v.clear()\n setView(to)\n }\n const fieldProps = { classNames: cx.field, ...(locale ? { locale } : {}) }\n const emailField = (\n <CheckoutField {...fieldProps} name=\"email\" type=\"email\" label={m.email} autoComplete=\"email\" inputMode=\"email\" value={email} onChange={(e) => setEmail(e.currentTarget.value)} error={v.errors.email ?? null} />\n )\n const codeField = (\n <CheckoutField {...fieldProps} name=\"code\" label={m.code} autoComplete=\"one-time-code\" inputMode=\"numeric\" pattern=\"[0-9]*\" error={v.errors.code ?? null} />\n )\n const passwordField = (label: string, autoComplete: string, newPassword: boolean) => (\n <CheckoutField\n {...fieldProps}\n name=\"password\"\n type=\"password\"\n label={label}\n autoComplete={autoComplete}\n error={v.errors.password ?? null}\n {...(newPassword ? { minLength: 10, maxLength: 128, hint: m.passwordHint } : {})}\n />\n )\n const link = (to: AccountAuthView, text: string) => (\n <button type=\"button\" className={cx.link} data-sf-account-link={to} onClick={() => go(to)}>\n {text}\n </button>\n )\n\n let body: ReactNode\n let links: ReactNode = null\n switch (view) {\n case 'register':\n body = (\n <>\n <CheckoutField {...fieldProps} name=\"first_name\" label={m.firstName} autoComplete=\"given-name\" optional />\n <CheckoutField {...fieldProps} name=\"last_name\" label={m.lastName} autoComplete=\"family-name\" optional />\n {emailField}\n {passwordField(m.password, 'new-password', true)}\n </>\n )\n links = link('login', m.loginLink)\n break\n case 'verify':\n case 'otp':\n body = (\n <>\n <p className={cx.notice} data-sf-account-notice>\n {m.codeSentTo.replace('{email}', email)}\n </p>\n <input type=\"hidden\" name=\"email\" value={email} />\n {codeField}\n </>\n )\n links = (\n <>\n {view === 'otp' ? (\n <button type=\"submit\" name=\"intent\" value=\"otp-request\" formNoValidate className={cx.link} data-sf-account-link=\"resend\">\n {m.resend}\n </button>\n ) : null}\n {link('login', m.backToLogin)}\n </>\n )\n break\n case 'otp-email':\n case 'forgot':\n body = emailField\n links = link('login', m.backToLogin)\n break\n case 'reset':\n body = (\n <>\n <p className={cx.notice} data-sf-account-notice>\n {m.codeSentTo.replace('{email}', email)}\n </p>\n <input type=\"hidden\" name=\"email\" value={email} />\n {codeField}\n {passwordField(m.newPassword, 'new-password', true)}\n </>\n )\n links = link('login', m.backToLogin)\n break\n default:\n body = (\n <>\n {emailField}\n {passwordField(m.password, 'current-password', false)}\n </>\n )\n links = (\n <>\n {otpOn ? link('forgot', m.forgotLink) : null}\n {link('register', m.registerLink)}\n {otpOn ? link('otp-email', m.otpLink) : null}\n </>\n )\n }\n\n const intent = { login: 'login', register: 'register', verify: 'verify', 'otp-email': 'otp-request', otp: 'otp-login', forgot: 'forgot', reset: 'reset' }[view]\n // Without password accounts the password views do not exist; only the code sign-in does.\n const available = view === 'login' || view === 'register' || view === 'forgot' || view === 'reset' || view === 'verify' ? passwordOn : otpOn\n const showSummary = !data?.error?.field\n const title = m.titles[view]\n if (!available && !passwordOn && !otpOn) {\n return (\n <section className={cx.root} data-sf-account-auth data-sf-account-view=\"unavailable\">\n <p className={cx.notice} role=\"status\">\n {capabilities.unavailable_reason === 'missing_scope' ? m.errors.store_misconfigured : m.nothingAvailable}\n </p>\n </section>\n )\n }\n return (\n <section className={cx.root} data-sf-account-auth data-sf-account-view={view} aria-labelledby=\"sf-account-title\">\n {header}\n <h1 id=\"sf-account-title\" className={cx.title}>\n {title}\n </h1>\n <FormTag ref={ref as never} method=\"post\" {...(action ? { action } : {})} className={cx.form} data-sf-account-form>\n <ErrorSummary items={v.summary} focusKey={v.summaryKey} {...(locale ? { locale } : {})} />\n {errorText && showSummary ? (\n <p role=\"alert\" className={cx.error} data-sf-account-error={data!.error!.code}>\n {errorText}\n </p>\n ) : null}\n {next ? <input type=\"hidden\" name=\"next\" value={next} /> : null}\n {body}\n <div className={cx.actions}>\n <button type=\"submit\" name=\"intent\" value={intent} disabled={pending} className={cx.submit} data-sf-account-submit>\n {m.submit[view]}\n </button>\n </div>\n <div className={cx.links} data-sf-account-links>\n {links}\n </div>\n </FormTag>\n </section>\n )\n}\n","/**\n * Post-purchase invitation to create an account, for the thank-you page (`/pagar/gracias`). Headless: no styles of its\n * own, `data-sf-ppa-*` hooks and `classNames` slots. It reuses the account action (`createAuthAction`, `./server`):\n * the form posts `register` (or `otp-request` in a store without passwords) with the buyer's email, so the verification,\n * the session cookie and the errors are exactly the ones of `<AccountAuth>`; nothing about addresses or phones is asked.\n *\n * Privacy: the email is the one of the receipt the SERVER read from the buyer's own session (the `email` prop); it is\n * sent as a hidden field and never editable here, so the form cannot be used to probe other addresses. With email\n * verification the action answers the same whether or not the address already has an account (no enumeration); the\n * guest orders of that address show up in the order history once the mailbox is verified (the store's addon scopes by\n * VERIFIED email). Without verification the account is created unverified and its history does not include guest\n * orders: the text then promises nothing about the order.\n *\n * Texts are Spanish by default, English with `locale=\"en\"`, any with `messages`.\n */\nimport { useRef, type ComponentType, type ReactNode } from 'react'\nimport type { CustomerCapabilities } from '@asteby/storefront'\nimport { CheckoutField, ErrorSummary, useFieldErrors, type CheckoutFieldClassNames } from '../checkout/fields.js'\nimport type { AccountFormProps } from './account-auth.js'\nimport type { AuthActionData, AuthErrorCode } from './types.js'\n\nexport type PostPurchaseAccountPromptMessages = {\n title: string\n /** Why, when the email is verified and the guest order will appear in the history. `{email}` is replaced. */\n benefit: string\n /** Why, when it will not (no email verification in the store). */\n benefitBasic: string\n accountFor: string\n password: string\n passwordHint: string\n code: string\n codeSentTo: string\n submit: string\n submitOtp: string\n submitCode: string\n skipNote: string\n loginLink: string\n errors: Record<AuthErrorCode, string>\n}\n\nconst ES: PostPurchaseAccountPromptMessages = {\n title: 'Crea tu cuenta para seguir tu pedido',\n benefit: 'Con {email} verás aquí tu pedido y su envío, y la próxima compra será más rápida. No te pedimos tu dirección ni tu teléfono otra vez.',\n benefitBasic: 'Guarda tus datos para que la próxima compra sea más rápida.',\n accountFor: 'Cuenta para {email}',\n password: 'Contraseña',\n passwordHint: 'Entre 10 y 128 caracteres.',\n code: 'Código',\n codeSentTo: 'Enviamos un código a {email}. Puede tardar un minuto.',\n submit: 'Crear cuenta',\n submitOtp: 'Enviarme un código',\n submitCode: 'Confirmar',\n skipNote: 'Si no quieres cuenta, no pasa nada: te avisaremos por correo de tu pedido.',\n loginLink: 'Ya tengo cuenta',\n errors: {\n invalid_credentials: 'El correo o la contraseña no coinciden.',\n invalid_code: 'El código no es válido o ya venció.',\n email_taken: 'Ya existe una cuenta con este correo. Entra para ver tu pedido.',\n rate_limited: 'Demasiados intentos. Espera unos minutos e inténtalo de nuevo.',\n validation: 'Revisa los datos e inténtalo de nuevo.',\n unsupported: 'Esta tienda no permite crear cuentas por ahora.',\n store_misconfigured: 'No pudimos crear tu cuenta por un problema de configuración de la tienda. Tu pedido sigue en pie.',\n unavailable: 'No pudimos completar la acción. Inténtalo de nuevo en un momento.',\n },\n}\n\nconst EN: PostPurchaseAccountPromptMessages = {\n title: 'Create your account to follow your order',\n benefit: 'With {email} you will see your order and its shipment here, and your next purchase will be faster. We will not ask for your address or phone again.',\n benefitBasic: 'Save your details so your next purchase is faster.',\n accountFor: 'Account for {email}',\n password: 'Password',\n passwordHint: 'Between 10 and 128 characters.',\n code: 'Code',\n codeSentTo: 'We sent a code to {email}. It can take a minute.',\n submit: 'Create account',\n submitOtp: 'Email me a code',\n submitCode: 'Confirm',\n skipNote: 'If you do not want an account, that is fine: we will email you about your order.',\n loginLink: 'I already have an account',\n errors: {\n invalid_credentials: 'The email and password do not match.',\n invalid_code: 'The code is not valid or has expired.',\n email_taken: 'An account with this email already exists. Sign in to see your order.',\n rate_limited: 'Too many attempts. Wait a few minutes and try again.',\n validation: 'Check the details and try again.',\n unsupported: 'This store does not allow creating accounts right now.',\n store_misconfigured: 'We could not create your account because of a store configuration problem. Your order is safe.',\n unavailable: 'We could not complete that. Try again in a moment.',\n },\n}\n\ntype DeepPartial<T> = { [K in keyof T]?: T[K] extends Record<string, string> ? Partial<T[K]> : T[K] }\n\n/** Messages for a locale (`es*` default, `en*`), with optional overrides (`errors` merges). */\nexport function postPurchaseAccountPromptMessages(locale?: string | null, overrides?: DeepPartial<PostPurchaseAccountPromptMessages> | null): PostPurchaseAccountPromptMessages {\n const base = (locale ?? 'es-MX').toLowerCase().startsWith('en') ? EN : ES\n if (!overrides) return base\n return { ...base, ...(overrides as Partial<PostPurchaseAccountPromptMessages>), errors: { ...base.errors, ...overrides.errors } }\n}\n\nexport type PostPurchaseAccountPromptClassNames = Partial<Record<'root' | 'title' | 'text' | 'email' | 'form' | 'notice' | 'error' | 'actions' | 'submit' | 'note' | 'link', string>> & {\n field?: CheckoutFieldClassNames\n}\n\nexport type PostPurchaseAccountPromptProps = {\n /** The buyer's email from the receipt of THIS session (read on the server). Without it nothing renders. */\n email?: string | null\n /** From `loadAuthCapabilities`. Without password nor email codes nothing renders. */\n capabilities: CustomerCapabilities\n /** What the account action returned (`useActionData()`); drives the code step and the errors. */\n data?: AuthActionData | null\n /** Where to go after the account is ready (sent as `next`; the server validates it). E.g. the order history. */\n next?: string | null\n /** A submit is in flight: disables the button. */\n pending?: boolean\n /** Form component, e.g. React Router's `Form`. Default: the HTML `<form>`. */\n form?: 'form' | ComponentType<AccountFormProps>\n /** `action` of the form: the route that mounts `createAuthAction`. Default: the current URL. */\n action?: string\n /** Heading level of the title (default 2). */\n headingLevel?: 2 | 3 | 4\n /** Where \"I already have an account\" goes (e.g. `/cuenta/entrar?next=...`). Omitted: no link. */\n loginHref?: string | null\n locale?: string\n messages?: DeepPartial<PostPurchaseAccountPromptMessages>\n classNames?: PostPurchaseAccountPromptClassNames\n /** Extra content under the form. */\n children?: ReactNode\n}\n\nconst validEmail = (v: string | null | undefined): v is string => typeof v === 'string' && v.length <= 254 && /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(v.trim())\n\n/**\n * `<PostPurchaseAccountPrompt email={receipt.email} capabilities={caps} data={actionData} form={Form} next=\"/cuenta/pedidos\" />`\n */\nexport function PostPurchaseAccountPrompt({\n email,\n capabilities,\n data,\n next,\n pending = false,\n form: FormTag = 'form',\n action,\n headingLevel = 2,\n loginHref,\n locale,\n messages,\n classNames: cx = {},\n children,\n}: PostPurchaseAccountPromptProps) {\n const m = postPurchaseAccountPromptMessages(locale, messages)\n const ref = useRef<HTMLFormElement>(null)\n const passwordOn = capabilities.password\n const otpOn = capabilities.otp_channels.includes('email')\n const errorText = data?.error ? m.errors[data.error.code] : null\n const v = useFieldErrors(ref, { ...(locale ? { locale } : {}), serverFields: data?.error?.field === 'code' || data?.error?.field === 'password' ? [data.error.field] : null, serverMessages: data?.error?.field && errorText ? { [data.error.field]: errorText } : null })\n if (!validEmail(email) || (!passwordOn && !otpOn)) return null\n\n const address = email.trim().toLowerCase()\n const step = data?.step === 'verify' || data?.step === 'otp' ? data.step : null\n const view = step ?? (passwordOn ? 'register' : 'otp-request')\n const intent = step === 'verify' ? 'verify' : step === 'otp' ? 'otp-login' : passwordOn ? 'register' : 'otp-request'\n const label = view === 'verify' || view === 'otp' ? m.submitCode : view === 'otp-request' ? m.submitOtp : m.submit\n const Heading = `h${headingLevel}` as 'h2'\n const fieldProps = { classNames: cx.field, ...(locale ? { locale } : {}) }\n // Only the errors with no field of their own go in the alert; the others are inline.\n const showAlert = errorText && !(data?.error?.field === 'code' || data?.error?.field === 'password')\n // Only a verified mailbox earns the guest order in the history (storefront_customers scopes by verified email).\n const benefit = (capabilities.email_verification ? m.benefit : m.benefitBasic).replace('{email}', address)\n\n return (\n <section className={cx.root} data-sf-ppa data-sf-ppa-view={view} aria-labelledby=\"sf-ppa-title\">\n <Heading id=\"sf-ppa-title\" className={cx.title}>\n {m.title}\n </Heading>\n <p className={cx.text} data-sf-ppa-benefit>\n {benefit}\n </p>\n <FormTag ref={ref as never} method=\"post\" {...(action ? { action } : {})} className={cx.form} data-sf-ppa-form>\n <ErrorSummary items={v.summary} focusKey={v.summaryKey} {...(locale ? { locale } : {})} />\n {showAlert ? (\n <p role=\"alert\" className={cx.error} data-sf-ppa-error={data!.error!.code}>\n {errorText}\n </p>\n ) : null}\n <input type=\"hidden\" name=\"email\" value={address} />\n {next ? <input type=\"hidden\" name=\"next\" value={next} /> : null}\n <p className={cx.email} data-sf-ppa-email>\n {m.accountFor.replace('{email}', address)}\n </p>\n {step ? (\n <>\n <p className={cx.notice} role=\"status\" data-sf-ppa-notice>\n {m.codeSentTo.replace('{email}', address)}\n </p>\n <CheckoutField {...fieldProps} name=\"code\" label={m.code} autoComplete=\"one-time-code\" inputMode=\"numeric\" pattern=\"[0-9]*\" error={v.errors.code ?? null} />\n </>\n ) : passwordOn ? (\n <CheckoutField {...fieldProps} name=\"password\" type=\"password\" label={m.password} autoComplete=\"new-password\" minLength={10} maxLength={128} hint={m.passwordHint} error={v.errors.password ?? null} />\n ) : null}\n <div className={cx.actions}>\n <button type=\"submit\" name=\"intent\" value={intent} disabled={pending} className={cx.submit} data-sf-ppa-submit>\n {label}\n </button>\n </div>\n </FormTag>\n <p className={cx.note} data-sf-ppa-note>\n {m.skipNote}\n {loginHref ? (\n <>\n {' '}\n <a href={loginHref} className={cx.link} data-sf-ppa-login>\n {m.loginLink}\n </a>\n </>\n ) : null}\n </p>\n {children}\n </section>\n )\n}\n"]}
|
package/dist/checkout.cjs
CHANGED
|
@@ -236,6 +236,7 @@ var ES2 = {
|
|
|
236
236
|
address2: "N\xFAmero interior o departamento",
|
|
237
237
|
reference: "Referencias para la entrega",
|
|
238
238
|
provincePlaceholder: "Elige tu estado",
|
|
239
|
+
neighborhoodPlaceholder: "Elige tu colonia",
|
|
239
240
|
address1Hint: "Por ejemplo: Av. Insurgentes Sur 1234",
|
|
240
241
|
referenceHint: "Entre qu\xE9 calles, color de la fachada\u2026",
|
|
241
242
|
emailHint: "Te enviamos aqu\xED la confirmaci\xF3n y el seguimiento.",
|
|
@@ -255,6 +256,7 @@ var EN2 = {
|
|
|
255
256
|
address2: "Apartment, suite",
|
|
256
257
|
reference: "Delivery notes",
|
|
257
258
|
provincePlaceholder: "Choose your state",
|
|
259
|
+
neighborhoodPlaceholder: "Choose your neighborhood",
|
|
258
260
|
address1Hint: "For example: 1234 Main St",
|
|
259
261
|
referenceHint: "Cross streets, building color\u2026",
|
|
260
262
|
emailHint: "We send the confirmation and tracking here.",
|
|
@@ -311,6 +313,9 @@ function AddressFields(props) {
|
|
|
311
313
|
const listId = react.useId();
|
|
312
314
|
const [colonias, setColonias] = react.useState([]);
|
|
313
315
|
const [filled, setFilled] = react.useState(false);
|
|
316
|
+
const [coloniaSelect, setColoniaSelect] = react.useState(false);
|
|
317
|
+
const coloniaSelectRef = react.useRef(false);
|
|
318
|
+
const coloniaCarry = react.useRef(null);
|
|
314
319
|
const lastZip = react.useRef(null);
|
|
315
320
|
const zipRef = react.useRef(null);
|
|
316
321
|
const lookupRef = react.useRef(lookupPostalCode);
|
|
@@ -350,18 +355,18 @@ function AddressFields(props) {
|
|
|
350
355
|
enqueue(() => {
|
|
351
356
|
if (lastZip.current !== zip) return;
|
|
352
357
|
const fill2 = (name, value, lock) => {
|
|
353
|
-
const
|
|
354
|
-
if (!
|
|
355
|
-
if (
|
|
356
|
-
if (
|
|
357
|
-
if (
|
|
358
|
-
if (
|
|
359
|
-
|
|
360
|
-
|
|
358
|
+
const el2 = form?.elements.namedItem(name);
|
|
359
|
+
if (!el2 || !value || "length" in el2 && !(el2 instanceof HTMLSelectElement)) return false;
|
|
360
|
+
if (el2.dataset.sfLocked === "1") return false;
|
|
361
|
+
if (el2.dataset.sfUserEdited === "1" || el2.ownerDocument.activeElement === el2 && el2.value) return false;
|
|
362
|
+
if (el2.value && el2.dataset.sfAutofilled !== "1") return false;
|
|
363
|
+
if (el2 instanceof HTMLSelectElement && ![...el2.options].some((o) => o.value === value)) return false;
|
|
364
|
+
el2.value = value;
|
|
365
|
+
el2.dataset.sfAutofilled = "1";
|
|
361
366
|
const event = new Event("input", { bubbles: true });
|
|
362
367
|
Object.defineProperty(event, ADDRESS_FILL_EVENT_FLAG, { value: true });
|
|
363
|
-
|
|
364
|
-
if (lock) lockField(
|
|
368
|
+
el2.dispatchEvent(event);
|
|
369
|
+
if (lock) lockField(el2);
|
|
365
370
|
return true;
|
|
366
371
|
};
|
|
367
372
|
const a = fill2(n("province"), info.province, lockProvinceOnFill);
|
|
@@ -369,13 +374,42 @@ function AddressFields(props) {
|
|
|
369
374
|
const only = info.neighborhoods?.length === 1 ? info.neighborhoods[0] : null;
|
|
370
375
|
const c = showNeighborhood ? fill2(n("neighborhood"), only) : false;
|
|
371
376
|
setColonias(info.neighborhoods ?? []);
|
|
372
|
-
|
|
377
|
+
const list = info.neighborhoods ?? [];
|
|
378
|
+
const nameEl = form?.elements.namedItem(n("neighborhood"));
|
|
379
|
+
const el = nameEl && !("length" in nameEl && !(nameEl instanceof HTMLSelectElement)) ? nameEl : null;
|
|
380
|
+
const typed = el ? el.value : "";
|
|
381
|
+
const wantSelect = props.neighborhoodList === "select" && showNeighborhood !== false && list.length > 1 && (!typed || list.includes(typed));
|
|
382
|
+
let carried = false;
|
|
383
|
+
if (showNeighborhood && wantSelect !== coloniaSelectRef.current) {
|
|
384
|
+
const userEdited = el?.dataset.sfUserEdited === "1";
|
|
385
|
+
const value = only && !userEdited ? only : wantSelect ? list.includes(typed) ? typed : "" : typed;
|
|
386
|
+
coloniaCarry.current = { value, autofilled: !userEdited && (!!only || el?.dataset.sfAutofilled === "1"), userEdited };
|
|
387
|
+
carried = !!only && !userEdited;
|
|
388
|
+
}
|
|
389
|
+
coloniaSelectRef.current = wantSelect;
|
|
390
|
+
setColoniaSelect(wantSelect);
|
|
391
|
+
setFilled(a || b || c || carried);
|
|
373
392
|
});
|
|
374
393
|
},
|
|
375
394
|
() => {
|
|
376
395
|
}
|
|
377
396
|
);
|
|
378
397
|
};
|
|
398
|
+
react.useEffect(() => {
|
|
399
|
+
const carry = coloniaCarry.current;
|
|
400
|
+
coloniaCarry.current = null;
|
|
401
|
+
if (!carry || !carry.value) return;
|
|
402
|
+
const form = zipRef.current?.closest("form");
|
|
403
|
+
const el = form?.elements.namedItem(n("neighborhood"));
|
|
404
|
+
if (!el || "length" in el && !(el instanceof HTMLSelectElement)) return;
|
|
405
|
+
if (el instanceof HTMLSelectElement && ![...el.options].some((o) => o.value === carry.value)) return;
|
|
406
|
+
el.value = carry.value;
|
|
407
|
+
if (carry.userEdited) el.dataset.sfUserEdited = "1";
|
|
408
|
+
else if (carry.autofilled) el.dataset.sfAutofilled = "1";
|
|
409
|
+
const event = new Event("input", { bubbles: true });
|
|
410
|
+
Object.defineProperty(event, ADDRESS_FILL_EVENT_FLAG, { value: true });
|
|
411
|
+
el.dispatchEvent(event);
|
|
412
|
+
}, [coloniaSelect]);
|
|
379
413
|
react.useEffect(() => {
|
|
380
414
|
const zip = defaults?.zip;
|
|
381
415
|
if (zip) runLookup(zip);
|
|
@@ -409,7 +443,24 @@ function AddressFields(props) {
|
|
|
409
443
|
provinces.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p.name, children: p.name }, p.code ?? p.name))
|
|
410
444
|
] }) : /* @__PURE__ */ jsxRuntime.jsx(CheckoutField, { ...common, name: n("province"), label: m.province, autoComplete: "address-level1", defaultValue: defaults?.province ?? "", error: errors[n("province")] ?? null, classNames: field(cx, "half") }),
|
|
411
445
|
/* @__PURE__ */ jsxRuntime.jsx(CheckoutField, { ...common, name: n("city"), label: m.city, autoComplete: "address-level2", defaultValue: defaults?.city ?? "", error: errors[n("city")] ?? null, classNames: field(cx, "half") }),
|
|
412
|
-
showNeighborhood ? /* @__PURE__ */ jsxRuntime.
|
|
446
|
+
showNeighborhood && coloniaSelect ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
447
|
+
CheckoutField,
|
|
448
|
+
{
|
|
449
|
+
...common,
|
|
450
|
+
as: "select",
|
|
451
|
+
name: n("neighborhood"),
|
|
452
|
+
label: m.neighborhood,
|
|
453
|
+
autoComplete: "address-level3",
|
|
454
|
+
optional: showNeighborhood !== "required",
|
|
455
|
+
defaultValue: colonias.includes(defaults?.neighborhood ?? "") ? defaults?.neighborhood ?? "" : "",
|
|
456
|
+
error: errors[n("neighborhood")] ?? null,
|
|
457
|
+
classNames: field(cx, "half"),
|
|
458
|
+
children: [
|
|
459
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: showNeighborhood === "required", children: m.neighborhoodPlaceholder }),
|
|
460
|
+
colonias.map((c) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: c, children: c }, c))
|
|
461
|
+
]
|
|
462
|
+
}
|
|
463
|
+
) : showNeighborhood ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
413
464
|
CheckoutField,
|
|
414
465
|
{
|
|
415
466
|
...common,
|
|
@@ -420,10 +471,10 @@ function AddressFields(props) {
|
|
|
420
471
|
defaultValue: defaults?.neighborhood ?? "",
|
|
421
472
|
error: errors[n("neighborhood")] ?? null,
|
|
422
473
|
classNames: field(cx, "half"),
|
|
423
|
-
...colonias.length ? { list: listId } : {}
|
|
474
|
+
...colonias.length && !coloniaSelect ? { list: listId } : {}
|
|
424
475
|
}
|
|
425
476
|
) : null,
|
|
426
|
-
colonias.length ? /* @__PURE__ */ jsxRuntime.jsx("datalist", { id: listId, children: colonias.map((c) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: c }, c)) }) : null,
|
|
477
|
+
colonias.length && !coloniaSelect ? /* @__PURE__ */ jsxRuntime.jsx("datalist", { id: listId, children: colonias.map((c) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: c }, c)) }) : null,
|
|
427
478
|
/* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", "aria-live": "polite", "data-sf-zip-status": true, style: filled ? void 0 : { position: "absolute", width: 1, height: 1, overflow: "hidden", clip: "rect(0 0 0 0)", whiteSpace: "nowrap" }, className: filled ? join(cx.hint, cx.wide) : void 0, children: filled ? m.lookupFilled : "" }),
|
|
428
479
|
/* @__PURE__ */ jsxRuntime.jsx(CheckoutField, { ...common, name: n("address1"), label: m.address1, autoComplete: "address-line1", defaultValue: defaults?.address1 ?? "", error: errors[n("address1")] ?? null, hint: m.address1Hint, classNames: field(cx, "wide") }),
|
|
429
480
|
/* @__PURE__ */ jsxRuntime.jsx(CheckoutField, { ...common, name: n("address2"), label: m.address2, autoComplete: "address-line2", optional: true, defaultValue: defaults?.address2 ?? "", error: errors[n("address2")] ?? null, classNames: field(cx, "half") }),
|