@ecomiq/storefront 2.1.4 → 3.0.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/LICENSE +21 -0
- package/README.md +150 -103
- package/dist/account-Dx4e3syi.js +258 -0
- package/dist/account-forms-AVk71ko7.js +39 -0
- package/dist/account-forms.d.ts +13 -0
- package/dist/account.d.ts +240 -0
- package/dist/address-defaults-BqjRhS82.js +14 -0
- package/dist/address-defaults.d.ts +11 -0
- package/dist/analytics/analytics-CG1Qagwl.js +148 -0
- package/dist/analytics/analytics.d.ts +1 -0
- package/dist/analytics/config-DJr-GRhs.js +62 -0
- package/dist/analytics/config.d.ts +22 -0
- package/dist/analytics/consent-B13rBpBs.js +57 -0
- package/dist/analytics/consent-banner-9QvRRy8v.js +239 -0
- package/dist/analytics/consent-banner.d.ts +20 -0
- package/dist/analytics/cookies-pLozllyB.js +100 -0
- package/dist/analytics/cookies.d.ts +6 -0
- package/dist/analytics/destinations-iECrlLIr.js +144 -0
- package/dist/analytics/events-Dt81tIp1.js +102 -0
- package/dist/analytics/events.d.ts +51 -0
- package/dist/analytics/tracker-p4yaoOyk.js +51 -0
- package/dist/api-cache-DsuIn5hX.js +159 -0
- package/dist/bank-accounts-DlEczQQ5.js +81 -0
- package/dist/bank-accounts.d.ts +4 -0
- package/dist/captcha-DAqaIx8m.js +117 -0
- package/dist/captcha.d.ts +34 -0
- package/dist/cart-D7DxZ2lD.js +30 -0
- package/dist/cart-actions-Bsub_FFG.js +116 -0
- package/dist/cart-actions.d.ts +15 -0
- package/dist/cart-drawer-B7PPsR69.js +22 -0
- package/dist/cart-drawer.d.ts +9 -0
- package/dist/cart-form-y9P1r_EX.js +81 -0
- package/dist/cart-form.d.ts +24 -0
- package/dist/cart-summary-ur2VWKr-.js +89 -0
- package/dist/cart-summary.d.ts +31 -0
- package/dist/cart.d.ts +4 -0
- package/dist/catalog-7gJ-l5hW.js +67 -0
- package/dist/catalog-hooks-B7ZP4wYY.js +312 -0
- package/dist/catalog-hooks.d.ts +111 -0
- package/dist/catalog.d.ts +5 -0
- package/dist/checkout-DVWSXANi.js +474 -0
- package/dist/checkout-form-CbOIdENC.js +131 -0
- package/dist/checkout-form.d.ts +20 -0
- package/dist/checkout.d.ts +86 -0
- package/dist/complaint-book-BvwLvfx0.js +117 -0
- package/dist/complaint-book.d.ts +62 -0
- package/dist/culqi-authentication-BGr20vAJ.js +204 -0
- package/dist/culqi-authentication.d.ts +15 -0
- package/dist/culqi-checkout-CTXpKgp_.js +55 -0
- package/dist/culqi-three-ds-HP3mfrvV.js +33 -0
- package/dist/culqi-three-ds.d.ts +29 -0
- package/dist/customer-avatar-CJXSDroK.js +12 -0
- package/dist/customer-avatar.d.ts +5 -0
- package/dist/customer-cookies-DHOgFAMV.js +45 -0
- package/dist/customer-csrf-C1oDX-Py.js +17 -0
- package/dist/customer-csrf.d.ts +3 -0
- package/dist/customer-document-fields-C1K-_DAD.js +70 -0
- package/dist/customer-document-fields.d.ts +9 -0
- package/dist/customer-login-form-C7AC6vXd.js +144 -0
- package/dist/customer-login-form.d.ts +17 -0
- package/dist/customer-registration-form-BEm_NEfP.js +93 -0
- package/dist/customer-registration-form.d.ts +8 -0
- package/dist/document-url-CGsAl5Tf.js +9 -0
- package/dist/documents-T1mzc_j8.js +38 -0
- package/dist/documents.d.ts +16 -0
- package/dist/entries/account.d.ts +11 -0
- package/dist/entries/account.js +10 -0
- package/dist/entries/analytics.d.ts +6 -0
- package/dist/entries/analytics.js +5 -0
- package/dist/entries/cart.d.ts +8 -0
- package/dist/entries/cart.js +7 -0
- package/dist/entries/checkout.d.ts +12 -0
- package/dist/entries/checkout.js +11 -0
- package/dist/entries/order.d.ts +11 -0
- package/dist/entries/order.js +11 -0
- package/dist/favicon-YpyhVJ9H.js +28 -0
- package/dist/favicon.d.ts +4 -0
- package/dist/form-BtQcbXlJ.js +18 -0
- package/dist/form-contracts-BNpHaTGJ.js +166 -0
- package/dist/form-contracts.d.ts +42 -0
- package/dist/form.d.ts +3 -0
- package/dist/hidden-CCWtOWKR.js +3 -0
- package/dist/hidden.d.ts +4 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +50 -0
- package/dist/invoice-fields-BG0HjL6T.js +103 -0
- package/dist/invoice-fields.d.ts +39 -0
- package/dist/links-kFxBZfdb.js +96 -0
- package/dist/links.d.ts +21 -0
- package/dist/mercadopago-checkout-DC7RXa8k.js +27 -0
- package/dist/mercadopago-dialog-UTQev0MG.js +180 -0
- package/dist/mercadopago-dialog.d.ts +21 -0
- package/dist/money-DtGOtDri.js +32 -0
- package/dist/money.d.ts +1 -0
- package/dist/optimistic-cart-BveVOHuh.js +53 -0
- package/dist/optimistic-cart.d.ts +16 -0
- package/dist/order-display-DTt5WBbc.js +112 -0
- package/dist/order-display.d.ts +20 -0
- package/dist/order-draft-DxV1Uhm3.js +38 -0
- package/dist/order-draft.d.ts +16 -0
- package/dist/order-pages-Dm6l5m0m.js +38 -0
- package/dist/order-pages.d.ts +12 -0
- package/dist/order-payment-continuation-D_d5PGA4.js +212 -0
- package/dist/order-payment-continuation.d.ts +10 -0
- package/dist/order-payment-in-review-x4gdLFHZ.js +65 -0
- package/dist/order-payment-in-review.d.ts +5 -0
- package/dist/order-status-BJXLJwxq.js +162 -0
- package/dist/order-status.d.ts +89 -0
- package/dist/order-view-9IlBg5AF.js +62 -0
- package/dist/order-view.d.ts +12 -0
- package/dist/page-action-Ctkf4xC6.js +7 -0
- package/dist/page-seo-a5FJl8x5.js +262 -0
- package/dist/page-seo.d.ts +34 -0
- package/dist/pages-Ca_Gt6mq.js +150 -0
- package/dist/pages.d.ts +45 -0
- package/dist/payment-dialog-frame-B-Q_xQ94.js +57 -0
- package/dist/payment-logo-BoPaGJc_.js +46 -0
- package/dist/payment-logo-svgs-By9lDTLK.js +20 -0
- package/dist/payment-logo.d.ts +11 -0
- package/dist/payment-logos-BYvdwYyJ.js +23 -0
- package/dist/payment-methods-B8ocTgFZ.js +73 -0
- package/dist/payment-methods.d.ts +58 -0
- package/dist/payment-return-5cjypwIw.js +7 -0
- package/dist/place-CmW4hBWY.js +13 -0
- package/dist/place.d.ts +4 -0
- package/dist/preview-BiIBif3C.js +427 -0
- package/dist/preview-address-Cf0sJ-9p.js +21 -0
- package/dist/preview-cart-Dg2CVktS.js +376 -0
- package/dist/product-preview-BspMAecJ.js +51 -0
- package/dist/product-preview.d.ts +5 -0
- package/dist/product-variants-BNDHvs1y.js +46 -0
- package/dist/product-variants.d.ts +12 -0
- package/dist/public-pages-XtwlaLwt.js +194 -0
- package/dist/public-pages.d.ts +67 -0
- package/dist/registration-CpDcv8ql.js +91 -0
- package/dist/registration.d.ts +12 -0
- package/dist/request-security-CRsRMgwj.js +76 -0
- package/dist/rich-text-M-Ju8RL4.js +9 -0
- package/dist/rich-text.d.ts +5 -0
- package/dist/route-text-DcJw2SsK.js +9 -0
- package/dist/route-text.d.ts +4 -0
- package/dist/section-preview-CmsMl3yu.js +83 -0
- package/dist/section-preview.d.ts +12 -0
- package/dist/sections/account-addresses.d.ts +18 -0
- package/dist/sections/account-addresses.js +375 -0
- package/dist/sections/account-order.d.ts +12 -0
- package/dist/sections/account-order.js +592 -0
- package/dist/sections/account-orders.d.ts +8 -0
- package/dist/sections/account-orders.js +359 -0
- package/dist/sections/account-profile.d.ts +16 -0
- package/dist/sections/account-profile.js +123 -0
- package/dist/sections/checkout.d.ts +24 -0
- package/dist/sections/checkout.js +963 -0
- package/dist/sections/complaint-book.d.ts +8 -0
- package/dist/sections/complaint-book.js +538 -0
- package/dist/sections/design-system.d.ts +1 -0
- package/dist/sections/design-system.js +310 -0
- package/dist/sections/draft-invoice.d.ts +20 -0
- package/dist/sections/draft-invoice.js +158 -0
- package/dist/sections/order-tracking.d.ts +19 -0
- package/dist/sections/order-tracking.js +141 -0
- package/dist/sections-CNUMWTF_.js +77 -0
- package/dist/sections.d.ts +19 -0
- package/dist/seo-GpDRhAAA.js +78 -0
- package/dist/session-CKvmFJyg.js +379 -0
- package/dist/session.d.ts +24 -0
- package/dist/settings-B0NO2A6Y.js +78 -0
- package/dist/settings.d.ts +51 -0
- package/dist/source-marker-DhqSkW7n.js +4 -0
- package/dist/sources-B-3JFJfb.js +46 -0
- package/dist/sources.d.ts +7 -0
- package/dist/store-8Q-_LFrQ.js +152 -0
- package/dist/store-contact--hY6CoFb.js +19 -0
- package/dist/store-contact.d.ts +6 -0
- package/dist/store.d.ts +17 -0
- package/dist/storefront-language-DrMjVbmk.js +29 -0
- package/dist/storefront-language.d.ts +14 -0
- package/dist/storefront-text-D25ae1qf.js +11 -0
- package/dist/storefront-text-en-ljjjSS4q.js +1030 -0
- package/dist/storefront-text-pt-BtHaJLcp.js +1030 -0
- package/dist/storefront-text.d.ts +4 -0
- package/dist/stripe-dialog-Ev9s3Z62.js +396 -0
- package/dist/stripe-dialog.d.ts +30 -0
- package/dist/telemetry-HuZXWBPi.js +114 -0
- package/dist/telemetry.d.ts +10 -0
- package/dist/templates-CAqoNyTW.js +40 -0
- package/dist/templates.d.ts +15 -0
- package/dist/urls-CpGQPxvf.js +71 -0
- package/dist/urls.d.ts +18 -0
- package/dist/use-checkout-CZcxXJXi.js +42 -0
- package/dist/use-checkout-payment-9R-zacrJ.js +80 -0
- package/dist/use-checkout-payment.d.ts +18 -0
- package/dist/use-checkout.d.ts +36 -0
- package/dist/use-culqi-checkout-CrjLAipU.js +109 -0
- package/dist/use-order-payment-BKIz_IO0.js +45 -0
- package/dist/use-order-payment.d.ts +18 -0
- package/dist/use-payment-token-CErx-tN-.js +105 -0
- package/dist/vite-payment-logos-kziu7wKb.js +27 -0
- package/dist/vite-payment-logos.d.ts +24 -0
- package/dist/vite-public-assets-DW2fgtVb.js +209 -0
- package/dist/vite-public-assets.d.ts +29 -0
- package/dist/vite-sections-DTBr0-Kg.js +464 -0
- package/dist/vite-sections.d.ts +21 -0
- package/dist/vite-theme-ui-BMO-CDi3.js +41 -0
- package/dist/vite-theme-ui.d.ts +10 -0
- package/dist/vite.d.ts +36 -0
- package/dist/vite.js +127 -0
- package/dist/voucher-payment-CVFDZ1L8.js +66 -0
- package/dist/worker-CNi-gzCu.js +86 -0
- package/dist/worker.d.ts +27 -0
- package/package.json +100 -76
- package/src/sections/account-addresses.tsx +215 -0
- package/src/sections/account-order.tsx +424 -0
- package/src/sections/account-orders.tsx +259 -0
- package/src/sections/account-profile.tsx +70 -0
- package/src/sections/checkout.tsx +586 -0
- package/src/sections/complaint-book.tsx +325 -0
- package/src/sections/design-system.tsx +146 -0
- package/src/sections/draft-invoice.tsx +105 -0
- package/src/sections/order-tracking.tsx +81 -0
- package/src/vite-client.d.ts +4 -0
- package/bin/ecomiq.mjs +0 -179
- package/public/design-bridge.js +0 -318
- package/src/api-proxy.ts +0 -194
- package/src/auth/create-storefront-auth.ts +0 -94
- package/src/auth/ecomiq-oauth-password-client.ts +0 -26
- package/src/auth/ecomiq-oauth-password-constants.ts +0 -24
- package/src/auth/ecomiq-oauth-password-plugin.ts +0 -294
- package/src/auth/ecomiq-oauth-password-types.ts +0 -24
- package/src/auth/ecomiq-storefront-sign-in.ts +0 -44
- package/src/auth/env.ts +0 -7
- package/src/auth/secure-cookies.ts +0 -23
- package/src/auth/storefront-auth-base-url.ts +0 -117
- package/src/auth/storefront-auth.ts +0 -7
- package/src/cart-session.ts +0 -239
- package/src/client.ts +0 -48
- package/src/codegen.mjs +0 -801
- package/src/components/account/customer-addresses-panel.tsx +0 -678
- package/src/components/account/customer-order-detail-panel.tsx +0 -285
- package/src/components/account/customer-orders-panel.tsx +0 -192
- package/src/components/account/customer-profile-panel.tsx +0 -379
- package/src/components/checkout/cart-sync.ts +0 -143
- package/src/components/checkout/checkout-contact-section.tsx +0 -76
- package/src/components/checkout/checkout-external-update-banner.tsx +0 -15
- package/src/components/checkout/checkout-form-controls.tsx +0 -139
- package/src/components/checkout/checkout-line-items.tsx +0 -43
- package/src/components/checkout/checkout-order-summary.tsx +0 -165
- package/src/components/checkout/checkout-payment-section.tsx +0 -212
- package/src/components/checkout/checkout-session-view.tsx +0 -564
- package/src/components/checkout/checkout-shipping-address-section.tsx +0 -400
- package/src/components/checkout/checkout-shipping-section.tsx +0 -98
- package/src/components/checkout/checkout-states.tsx +0 -73
- package/src/components/checkout/checkout-step-card.tsx +0 -101
- package/src/components/checkout/checkout-steps.ts +0 -111
- package/src/components/checkout/form-schema.ts +0 -281
- package/src/components/checkout/format.ts +0 -15
- package/src/components/checkout/index.ts +0 -5
- package/src/components/checkout/map-customer-to-checkout.ts +0 -188
- package/src/components/checkout/types.ts +0 -41
- package/src/components/checkout/use-checkout-customer-prefill.ts +0 -409
- package/src/components/checkout/use-checkout-geo.ts +0 -50
- package/src/components/checkout/use-checkout-session.ts +0 -640
- package/src/components/hero.tsx +0 -291
- package/src/config.d.ts +0 -94
- package/src/config.mjs +0 -146
- package/src/format-money.ts +0 -31
- package/src/health.ts +0 -90
- package/src/hooks/index.ts +0 -9
- package/src/hooks/recently-viewed.ts +0 -125
- package/src/index.ts +0 -349
- package/src/link.tsx +0 -2
- package/src/pages/account/account-page-skeleton.tsx +0 -69
- package/src/pages/account/account-page-view.tsx +0 -270
- package/src/pages/account/account-shell.tsx +0 -101
- package/src/pages/account/parse-account-route.ts +0 -36
- package/src/pages/account.tsx +0 -16
- package/src/pages/api.$.ts +0 -20
- package/src/pages/api.auth.$.ts +0 -16
- package/src/pages/checkout.$checkoutId.tsx +0 -60
- package/src/pages/checkout.tsx +0 -31
- package/src/pages/pages.$pageSlug.tsx +0 -74
- package/src/pages/thank-you.tsx +0 -53
- package/src/providers/auth.tsx +0 -96
- package/src/providers/cart.tsx +0 -275
- package/src/providers/ecomiq.ts +0 -137
- package/src/providers/index.ts +0 -26
- package/src/proxy-api.ts +0 -20
- package/src/public-config.ts +0 -24
- package/src/review-submission.ts +0 -89
- package/src/runtime/context.ts +0 -2
- package/src/runtime/default-layout.tsx +0 -64
- package/src/runtime/head.ts +0 -149
- package/src/runtime/page.tsx +0 -143
- package/src/runtime/postcss-browser-stub.mjs +0 -5
- package/src/server-config-store.ts +0 -35
- package/src/server.ts +0 -286
- package/src/styles.css +0 -76
- package/src/ui/badge.tsx +0 -32
- package/src/ui/button.tsx +0 -31
- package/src/ui/card.tsx +0 -31
- package/src/ui/carousel.tsx +0 -218
- package/src/ui/cn.ts +0 -6
- package/src/ui/index.ts +0 -8
- package/src/ui/separator.tsx +0 -6
- package/src/ui/skeleton.tsx +0 -6
- package/src/ui/storefront-error.tsx +0 -49
- package/src/utils.ts +0 -36
- package/src/vite-inline.mjs +0 -263
- package/templates/__root.tsx +0 -83
- package/templates/router.tsx +0 -19
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import type { HTMLAttributes } from 'react'
|
|
2
|
-
import { cn } from '../../ui'
|
|
3
|
-
|
|
4
|
-
export function fieldClass(error?: string) {
|
|
5
|
-
return cn(
|
|
6
|
-
'mt-1.5 flex h-11 w-full rounded-md border border-border bg-background px-3 text-sm outline-none placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-ring',
|
|
7
|
-
error && 'border-destructive',
|
|
8
|
-
)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function FieldError({ message }: { message?: string }) {
|
|
12
|
-
if (!message) return null
|
|
13
|
-
return <p className="mt-1 text-xs text-destructive">{message}</p>
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function CheckoutTextField({
|
|
17
|
-
id,
|
|
18
|
-
label,
|
|
19
|
-
value,
|
|
20
|
-
onChange,
|
|
21
|
-
error,
|
|
22
|
-
type = 'text',
|
|
23
|
-
autoComplete,
|
|
24
|
-
inputMode,
|
|
25
|
-
placeholder,
|
|
26
|
-
}: {
|
|
27
|
-
id: string
|
|
28
|
-
label: string
|
|
29
|
-
value: string
|
|
30
|
-
onChange: (value: string) => void
|
|
31
|
-
error?: string
|
|
32
|
-
type?: string
|
|
33
|
-
autoComplete?: string
|
|
34
|
-
inputMode?: HTMLAttributes<HTMLInputElement>['inputMode']
|
|
35
|
-
placeholder?: string
|
|
36
|
-
}) {
|
|
37
|
-
return (
|
|
38
|
-
<div className="min-w-0">
|
|
39
|
-
<label htmlFor={id} className="text-sm font-medium text-foreground">
|
|
40
|
-
{label}
|
|
41
|
-
</label>
|
|
42
|
-
<input
|
|
43
|
-
id={id}
|
|
44
|
-
type={type}
|
|
45
|
-
className={fieldClass(error)}
|
|
46
|
-
value={value}
|
|
47
|
-
onChange={(e) => onChange(e.target.value)}
|
|
48
|
-
autoComplete={autoComplete}
|
|
49
|
-
inputMode={inputMode}
|
|
50
|
-
placeholder={placeholder}
|
|
51
|
-
/>
|
|
52
|
-
<FieldError message={error} />
|
|
53
|
-
</div>
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function CheckoutSelectField({
|
|
58
|
-
id,
|
|
59
|
-
label,
|
|
60
|
-
value,
|
|
61
|
-
options,
|
|
62
|
-
onChange,
|
|
63
|
-
error,
|
|
64
|
-
placeholder = 'Seleccionar…',
|
|
65
|
-
}: {
|
|
66
|
-
id: string
|
|
67
|
-
label: string
|
|
68
|
-
value: string
|
|
69
|
-
options: { value: string; label: string }[]
|
|
70
|
-
onChange: (value: string) => void
|
|
71
|
-
error?: string
|
|
72
|
-
placeholder?: string
|
|
73
|
-
}) {
|
|
74
|
-
return (
|
|
75
|
-
<div className="min-w-0">
|
|
76
|
-
<label htmlFor={id} className="text-sm font-medium text-foreground">
|
|
77
|
-
{label}
|
|
78
|
-
</label>
|
|
79
|
-
<select
|
|
80
|
-
id={id}
|
|
81
|
-
className={fieldClass(error)}
|
|
82
|
-
value={value}
|
|
83
|
-
onChange={(e) => onChange(e.target.value)}
|
|
84
|
-
>
|
|
85
|
-
<option value="">{placeholder}</option>
|
|
86
|
-
{options.map((o) => (
|
|
87
|
-
<option key={o.value} value={o.value}>
|
|
88
|
-
{o.label}
|
|
89
|
-
</option>
|
|
90
|
-
))}
|
|
91
|
-
</select>
|
|
92
|
-
<FieldError message={error} />
|
|
93
|
-
</div>
|
|
94
|
-
)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function CheckoutPhoneField({
|
|
98
|
-
id,
|
|
99
|
-
label,
|
|
100
|
-
value,
|
|
101
|
-
dialCode,
|
|
102
|
-
error,
|
|
103
|
-
onChange,
|
|
104
|
-
}: {
|
|
105
|
-
id: string
|
|
106
|
-
label: string
|
|
107
|
-
value: string
|
|
108
|
-
dialCode: string
|
|
109
|
-
error?: string
|
|
110
|
-
onChange: (value: string) => void
|
|
111
|
-
}) {
|
|
112
|
-
return (
|
|
113
|
-
<div className="min-w-0">
|
|
114
|
-
<label htmlFor={id} className="text-sm font-medium text-foreground">
|
|
115
|
-
{label}
|
|
116
|
-
</label>
|
|
117
|
-
<div
|
|
118
|
-
className={cn(
|
|
119
|
-
'mt-1.5 flex h-11 overflow-hidden rounded-md border bg-background focus-within:ring-2 focus-within:ring-ring',
|
|
120
|
-
error ? 'border-destructive' : 'border-border',
|
|
121
|
-
)}
|
|
122
|
-
>
|
|
123
|
-
<span className="flex shrink-0 items-center border-r bg-muted/40 px-3 text-sm text-muted-foreground">
|
|
124
|
-
{dialCode}
|
|
125
|
-
</span>
|
|
126
|
-
<input
|
|
127
|
-
id={id}
|
|
128
|
-
type="tel"
|
|
129
|
-
inputMode="numeric"
|
|
130
|
-
autoComplete="tel-national"
|
|
131
|
-
className="min-w-0 flex-1 bg-transparent px-3 text-sm outline-none"
|
|
132
|
-
value={value}
|
|
133
|
-
onChange={(e) => onChange(e.target.value.replace(/\D/g, ''))}
|
|
134
|
-
/>
|
|
135
|
-
</div>
|
|
136
|
-
<FieldError message={error} />
|
|
137
|
-
</div>
|
|
138
|
-
)
|
|
139
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { StorefrontOrderBump } from '@ecomiq/core'
|
|
2
|
-
import { Button } from '../../ui'
|
|
3
|
-
|
|
4
|
-
export function CheckoutOrderBumps({
|
|
5
|
-
bumps,
|
|
6
|
-
money,
|
|
7
|
-
busy,
|
|
8
|
-
onAdd,
|
|
9
|
-
}: {
|
|
10
|
-
bumps: StorefrontOrderBump[]
|
|
11
|
-
money: (n: number) => string
|
|
12
|
-
busy: boolean
|
|
13
|
-
onAdd: (bump: StorefrontOrderBump) => void
|
|
14
|
-
}) {
|
|
15
|
-
if (bumps.length === 0) return null
|
|
16
|
-
return (
|
|
17
|
-
<section className="space-y-3 rounded-xl border bg-card p-5">
|
|
18
|
-
<h2 className="text-lg font-semibold">Agregar al pedido</h2>
|
|
19
|
-
{bumps.map((bump) => (
|
|
20
|
-
<div key={bump.id} className="flex items-center gap-3">
|
|
21
|
-
<div className="size-14 overflow-hidden rounded-md bg-muted">
|
|
22
|
-
{bump.imageUrl ? (
|
|
23
|
-
<img src={bump.imageUrl} alt="" className="size-full object-cover" />
|
|
24
|
-
) : null}
|
|
25
|
-
</div>
|
|
26
|
-
<div className="min-w-0 flex-1">
|
|
27
|
-
<p className="text-sm font-medium">{bump.productName}</p>
|
|
28
|
-
<p className="text-xs text-muted-foreground">{money(bump.offerPrice)}</p>
|
|
29
|
-
</div>
|
|
30
|
-
<Button
|
|
31
|
-
type="button"
|
|
32
|
-
size="sm"
|
|
33
|
-
variant="outline"
|
|
34
|
-
disabled={busy}
|
|
35
|
-
onClick={() => onAdd(bump)}
|
|
36
|
-
>
|
|
37
|
-
{bump.callToAction || 'Agregar'}
|
|
38
|
-
</Button>
|
|
39
|
-
</div>
|
|
40
|
-
))}
|
|
41
|
-
</section>
|
|
42
|
-
)
|
|
43
|
-
}
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import { Package, Tag } from 'lucide-react'
|
|
2
|
-
import type { StorefrontCartItem } from '@ecomiq/core'
|
|
3
|
-
import { Button } from '../../ui'
|
|
4
|
-
import { fieldClass } from './checkout-form-controls'
|
|
5
|
-
|
|
6
|
-
export function CheckoutOrderSummary({
|
|
7
|
-
items,
|
|
8
|
-
money,
|
|
9
|
-
subtotal,
|
|
10
|
-
discount,
|
|
11
|
-
shipping,
|
|
12
|
-
tax,
|
|
13
|
-
total,
|
|
14
|
-
hasShippingOptions,
|
|
15
|
-
couponCode,
|
|
16
|
-
couponError,
|
|
17
|
-
promotionCodes,
|
|
18
|
-
formError,
|
|
19
|
-
isSaving,
|
|
20
|
-
canSubmit = true,
|
|
21
|
-
submitLabel = 'Pagar',
|
|
22
|
-
onCouponCodeChange,
|
|
23
|
-
onApplyCoupon,
|
|
24
|
-
onRemoveCoupon,
|
|
25
|
-
}: {
|
|
26
|
-
items: StorefrontCartItem[]
|
|
27
|
-
money: (value: number) => string
|
|
28
|
-
subtotal: number
|
|
29
|
-
discount: number
|
|
30
|
-
shipping: number
|
|
31
|
-
tax: number
|
|
32
|
-
total: number
|
|
33
|
-
hasShippingOptions: boolean
|
|
34
|
-
couponCode: string
|
|
35
|
-
couponError: string | null
|
|
36
|
-
promotionCodes: string[]
|
|
37
|
-
formError: string | null
|
|
38
|
-
isSaving: boolean
|
|
39
|
-
canSubmit?: boolean
|
|
40
|
-
submitLabel?: string
|
|
41
|
-
onCouponCodeChange: (value: string) => void
|
|
42
|
-
onApplyCoupon: () => void
|
|
43
|
-
onRemoveCoupon: (code: string) => void
|
|
44
|
-
}) {
|
|
45
|
-
return (
|
|
46
|
-
<aside className="rounded-xl border bg-card p-5 shadow-sm lg:sticky lg:top-6">
|
|
47
|
-
<h2 className="text-lg font-semibold">Resumen</h2>
|
|
48
|
-
|
|
49
|
-
<ul className="mt-4 divide-y border-y" aria-label="Productos">
|
|
50
|
-
{items.map((item) => (
|
|
51
|
-
<SummaryLineItem key={item.id} item={item} money={money} />
|
|
52
|
-
))}
|
|
53
|
-
</ul>
|
|
54
|
-
|
|
55
|
-
<div className="mt-4 flex gap-2">
|
|
56
|
-
<input
|
|
57
|
-
className={fieldClass()}
|
|
58
|
-
placeholder="Cupón"
|
|
59
|
-
value={couponCode}
|
|
60
|
-
onChange={(e) => onCouponCodeChange(e.target.value)}
|
|
61
|
-
/>
|
|
62
|
-
<Button type="button" variant="outline" onClick={onApplyCoupon}>
|
|
63
|
-
Aplicar
|
|
64
|
-
</Button>
|
|
65
|
-
</div>
|
|
66
|
-
{couponError ? (
|
|
67
|
-
<p className="mt-2 text-xs text-destructive">{couponError}</p>
|
|
68
|
-
) : null}
|
|
69
|
-
{promotionCodes.length > 0 ? (
|
|
70
|
-
<div className="mt-3 flex flex-wrap gap-2">
|
|
71
|
-
{promotionCodes.map((code) => (
|
|
72
|
-
<button
|
|
73
|
-
key={code}
|
|
74
|
-
type="button"
|
|
75
|
-
className="inline-flex items-center gap-1.5 rounded-md bg-muted px-2 py-1 text-xs font-medium"
|
|
76
|
-
onClick={() => onRemoveCoupon(code)}
|
|
77
|
-
>
|
|
78
|
-
<Tag className="size-3" aria-hidden="true" />
|
|
79
|
-
{code} ×
|
|
80
|
-
</button>
|
|
81
|
-
))}
|
|
82
|
-
</div>
|
|
83
|
-
) : null}
|
|
84
|
-
|
|
85
|
-
<dl className="mt-5 space-y-3 text-sm">
|
|
86
|
-
<div className="flex justify-between gap-4">
|
|
87
|
-
<dt className="text-muted-foreground">Subtotal</dt>
|
|
88
|
-
<dd className="tabular-nums">{money(subtotal)}</dd>
|
|
89
|
-
</div>
|
|
90
|
-
{discount !== 0 ? (
|
|
91
|
-
<div className="flex justify-between gap-4 text-primary">
|
|
92
|
-
<dt>Descuentos</dt>
|
|
93
|
-
<dd className="tabular-nums">-{money(Math.abs(discount))}</dd>
|
|
94
|
-
</div>
|
|
95
|
-
) : null}
|
|
96
|
-
<div className="flex justify-between gap-4">
|
|
97
|
-
<dt className="text-muted-foreground">Envío</dt>
|
|
98
|
-
<dd className="tabular-nums">
|
|
99
|
-
{hasShippingOptions ? money(shipping) : 'Por calcular'}
|
|
100
|
-
</dd>
|
|
101
|
-
</div>
|
|
102
|
-
{tax !== 0 ? (
|
|
103
|
-
<div className="flex justify-between gap-4">
|
|
104
|
-
<dt className="text-muted-foreground">Impuestos</dt>
|
|
105
|
-
<dd className="tabular-nums">{money(tax)}</dd>
|
|
106
|
-
</div>
|
|
107
|
-
) : null}
|
|
108
|
-
<div className="flex items-baseline justify-between gap-4 border-t pt-4">
|
|
109
|
-
<dt className="font-semibold">Total</dt>
|
|
110
|
-
<dd className="text-xl font-semibold tabular-nums">{money(total)}</dd>
|
|
111
|
-
</div>
|
|
112
|
-
</dl>
|
|
113
|
-
|
|
114
|
-
{formError ? (
|
|
115
|
-
<p className="mt-4 text-sm text-destructive" role="alert">
|
|
116
|
-
{formError}
|
|
117
|
-
</p>
|
|
118
|
-
) : null}
|
|
119
|
-
|
|
120
|
-
<Button
|
|
121
|
-
type="submit"
|
|
122
|
-
className="mt-6 w-full"
|
|
123
|
-
size="lg"
|
|
124
|
-
disabled={isSaving || !canSubmit}
|
|
125
|
-
>
|
|
126
|
-
{isSaving ? 'Procesando…' : submitLabel}
|
|
127
|
-
</Button>
|
|
128
|
-
</aside>
|
|
129
|
-
)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function SummaryLineItem({
|
|
133
|
-
item,
|
|
134
|
-
money,
|
|
135
|
-
}: {
|
|
136
|
-
item: StorefrontCartItem
|
|
137
|
-
money: (value: number) => string
|
|
138
|
-
}) {
|
|
139
|
-
const lineTotal = item.unitPrice * item.quantity
|
|
140
|
-
return (
|
|
141
|
-
<li className="flex gap-3 py-3">
|
|
142
|
-
<div className="flex size-14 shrink-0 items-center justify-center overflow-hidden rounded-md bg-muted">
|
|
143
|
-
{item.thumbnail ? (
|
|
144
|
-
<img
|
|
145
|
-
src={item.thumbnail}
|
|
146
|
-
alt=""
|
|
147
|
-
width={56}
|
|
148
|
-
height={56}
|
|
149
|
-
className="size-full object-cover"
|
|
150
|
-
/>
|
|
151
|
-
) : (
|
|
152
|
-
<Package className="size-4 text-muted-foreground" aria-hidden="true" />
|
|
153
|
-
)}
|
|
154
|
-
</div>
|
|
155
|
-
<div className="min-w-0 flex-1">
|
|
156
|
-
<p className="text-sm font-medium leading-snug">{item.title}</p>
|
|
157
|
-
<div className="mt-0.5 flex flex-wrap gap-x-2 text-xs text-muted-foreground">
|
|
158
|
-
<span>Cant. {item.quantity}</span>
|
|
159
|
-
{item.variantLabel ? <span>{item.variantLabel}</span> : null}
|
|
160
|
-
</div>
|
|
161
|
-
</div>
|
|
162
|
-
<p className="shrink-0 text-sm font-semibold tabular-nums">{money(lineTotal)}</p>
|
|
163
|
-
</li>
|
|
164
|
-
)
|
|
165
|
-
}
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Banknote,
|
|
3
|
-
CreditCard,
|
|
4
|
-
Landmark,
|
|
5
|
-
Wallet,
|
|
6
|
-
} from 'lucide-react'
|
|
7
|
-
import type { CartCheckoutResponse, CartPaymentMethod } from '@ecomiq/core'
|
|
8
|
-
import { Button, cn } from '../../ui'
|
|
9
|
-
import { methodUsesProviderCheckoutUi } from './cart-sync'
|
|
10
|
-
import type { CheckoutFieldId } from './form-schema'
|
|
11
|
-
import { FieldError } from './checkout-form-controls'
|
|
12
|
-
import { paymentRedirectUrl } from './format'
|
|
13
|
-
|
|
14
|
-
function paymentIcon(method: CartPaymentMethod) {
|
|
15
|
-
const key = `${method.kind} ${method.code} ${method.providerMethodCode ?? ''}`.toLowerCase()
|
|
16
|
-
if (key.includes('paypal')) return Wallet
|
|
17
|
-
if (key.includes('stripe') || key.includes('card') || key.includes('credit')) return CreditCard
|
|
18
|
-
if (key.includes('mercado')) return Wallet
|
|
19
|
-
if (method.isManual || key.includes('transfer') || key.includes('cash')) return Landmark
|
|
20
|
-
return Banknote
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function CheckoutPaymentSection({
|
|
24
|
-
methods,
|
|
25
|
-
selectedCode,
|
|
26
|
-
fieldError,
|
|
27
|
-
checkoutPaymentLoading,
|
|
28
|
-
checkoutPaymentError,
|
|
29
|
-
checkoutPaymentResponse,
|
|
30
|
-
checkoutPaymentMethodCode,
|
|
31
|
-
providerPaymentCompleted,
|
|
32
|
-
receiptUrl,
|
|
33
|
-
receiptError,
|
|
34
|
-
onSelect,
|
|
35
|
-
onClearError,
|
|
36
|
-
onMarkProviderCompleted,
|
|
37
|
-
onReceiptFileChange,
|
|
38
|
-
}: {
|
|
39
|
-
methods: CartPaymentMethod[]
|
|
40
|
-
selectedCode: string | null
|
|
41
|
-
fieldError?: string
|
|
42
|
-
checkoutPaymentLoading: boolean
|
|
43
|
-
checkoutPaymentError: string | null
|
|
44
|
-
checkoutPaymentResponse: CartCheckoutResponse | null
|
|
45
|
-
checkoutPaymentMethodCode: string | null
|
|
46
|
-
providerPaymentCompleted: boolean
|
|
47
|
-
receiptUrl: string | null
|
|
48
|
-
receiptError: string | null
|
|
49
|
-
onSelect: (code: string) => void
|
|
50
|
-
onClearError: (id: CheckoutFieldId) => void
|
|
51
|
-
onMarkProviderCompleted: () => void
|
|
52
|
-
onReceiptFileChange: (file: File | null) => void
|
|
53
|
-
}) {
|
|
54
|
-
return (
|
|
55
|
-
<div className="space-y-4">
|
|
56
|
-
<div className="space-y-3">
|
|
57
|
-
{methods.map((method) => {
|
|
58
|
-
const selected = selectedCode === method.code
|
|
59
|
-
const Icon = paymentIcon(method)
|
|
60
|
-
const usesProviderUi = methodUsesProviderCheckoutUi(method)
|
|
61
|
-
const showExpanded = selected
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<div
|
|
65
|
-
key={method.code}
|
|
66
|
-
className={cn(
|
|
67
|
-
'overflow-hidden rounded-lg border transition-colors',
|
|
68
|
-
selected ? 'border-border bg-muted/40' : 'border-border bg-background',
|
|
69
|
-
)}
|
|
70
|
-
>
|
|
71
|
-
<label className="flex cursor-pointer items-center gap-3 px-4 py-3.5">
|
|
72
|
-
<input
|
|
73
|
-
type="radio"
|
|
74
|
-
name="payment"
|
|
75
|
-
className="size-4 accent-blue-600"
|
|
76
|
-
checked={selected}
|
|
77
|
-
onChange={() => {
|
|
78
|
-
onClearError('checkout-payment-method')
|
|
79
|
-
onSelect(method.code)
|
|
80
|
-
}}
|
|
81
|
-
/>
|
|
82
|
-
<span className="min-w-0 flex-1">
|
|
83
|
-
<span className="block text-sm font-medium">{method.name}</span>
|
|
84
|
-
{method.description ? (
|
|
85
|
-
<span className="mt-0.5 block text-xs text-muted-foreground">
|
|
86
|
-
{method.description}
|
|
87
|
-
</span>
|
|
88
|
-
) : null}
|
|
89
|
-
</span>
|
|
90
|
-
<Icon className="size-5 shrink-0 text-muted-foreground" aria-hidden="true" />
|
|
91
|
-
</label>
|
|
92
|
-
|
|
93
|
-
{showExpanded ? (
|
|
94
|
-
<div className="space-y-3 border-t px-4 py-4">
|
|
95
|
-
{usesProviderUi ? (
|
|
96
|
-
<ProviderPaymentPanel
|
|
97
|
-
loading={
|
|
98
|
-
checkoutPaymentMethodCode === method.code && checkoutPaymentLoading
|
|
99
|
-
}
|
|
100
|
-
error={
|
|
101
|
-
checkoutPaymentMethodCode === method.code
|
|
102
|
-
? checkoutPaymentError
|
|
103
|
-
: null
|
|
104
|
-
}
|
|
105
|
-
response={
|
|
106
|
-
checkoutPaymentMethodCode === method.code
|
|
107
|
-
? checkoutPaymentResponse
|
|
108
|
-
: null
|
|
109
|
-
}
|
|
110
|
-
completed={providerPaymentCompleted}
|
|
111
|
-
onMarkCompleted={onMarkProviderCompleted}
|
|
112
|
-
/>
|
|
113
|
-
) : null}
|
|
114
|
-
|
|
115
|
-
{method.isManual ? (
|
|
116
|
-
<div className="space-y-2">
|
|
117
|
-
<p className="text-sm font-medium">Comprobante de pago</p>
|
|
118
|
-
<input
|
|
119
|
-
type="file"
|
|
120
|
-
accept="image/*,application/pdf"
|
|
121
|
-
className="block w-full text-sm"
|
|
122
|
-
onChange={(e) =>
|
|
123
|
-
onReceiptFileChange(e.target.files?.[0] ?? null)
|
|
124
|
-
}
|
|
125
|
-
/>
|
|
126
|
-
{receiptError ? (
|
|
127
|
-
<p className="text-xs text-destructive">{receiptError}</p>
|
|
128
|
-
) : null}
|
|
129
|
-
{receiptUrl ? (
|
|
130
|
-
<p className="text-xs text-muted-foreground">Comprobante listo</p>
|
|
131
|
-
) : null}
|
|
132
|
-
</div>
|
|
133
|
-
) : null}
|
|
134
|
-
|
|
135
|
-
{!usesProviderUi && !method.isManual ? (
|
|
136
|
-
<p className="text-xs text-muted-foreground">
|
|
137
|
-
Continúa con Pagar para confirmar este método de pago.
|
|
138
|
-
</p>
|
|
139
|
-
) : null}
|
|
140
|
-
</div>
|
|
141
|
-
) : null}
|
|
142
|
-
</div>
|
|
143
|
-
)
|
|
144
|
-
})}
|
|
145
|
-
</div>
|
|
146
|
-
<FieldError message={fieldError} />
|
|
147
|
-
</div>
|
|
148
|
-
)
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function ProviderPaymentPanel({
|
|
152
|
-
loading,
|
|
153
|
-
error,
|
|
154
|
-
response,
|
|
155
|
-
completed,
|
|
156
|
-
onMarkCompleted,
|
|
157
|
-
}: {
|
|
158
|
-
loading: boolean
|
|
159
|
-
error: string | null
|
|
160
|
-
response: CartCheckoutResponse | null
|
|
161
|
-
completed: boolean
|
|
162
|
-
onMarkCompleted: () => void
|
|
163
|
-
}) {
|
|
164
|
-
if (loading) {
|
|
165
|
-
return <p className="text-sm text-muted-foreground">Preparando pasarela de pago…</p>
|
|
166
|
-
}
|
|
167
|
-
if (error) {
|
|
168
|
-
return <p className="text-sm text-destructive">{error}</p>
|
|
169
|
-
}
|
|
170
|
-
if (!response) {
|
|
171
|
-
return (
|
|
172
|
-
<p className="text-xs text-muted-foreground">
|
|
173
|
-
Completa el pago de forma segura con el proveedor seleccionado.
|
|
174
|
-
</p>
|
|
175
|
-
)
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const url = paymentRedirectUrl(response)
|
|
179
|
-
const clientSecret =
|
|
180
|
-
response.clientSecret ??
|
|
181
|
-
response.intentClientSecret ??
|
|
182
|
-
response.payment?.action?.clientSecret
|
|
183
|
-
|
|
184
|
-
return (
|
|
185
|
-
<div className="space-y-3 text-sm">
|
|
186
|
-
{url ? (
|
|
187
|
-
<a
|
|
188
|
-
href={url}
|
|
189
|
-
target="_blank"
|
|
190
|
-
rel="noreferrer"
|
|
191
|
-
className="font-medium text-primary underline-offset-4 hover:underline"
|
|
192
|
-
>
|
|
193
|
-
Abrir pasarela de pago
|
|
194
|
-
</a>
|
|
195
|
-
) : null}
|
|
196
|
-
{clientSecret && !url ? (
|
|
197
|
-
<p className="text-muted-foreground">
|
|
198
|
-
Sesión de pago lista. Completa el cobro en la pasarela cuando esté disponible.
|
|
199
|
-
</p>
|
|
200
|
-
) : null}
|
|
201
|
-
{completed ? (
|
|
202
|
-
<p className="text-xs text-muted-foreground">
|
|
203
|
-
Pago confirmado. Pulsa Pagar para finalizar tu pedido.
|
|
204
|
-
</p>
|
|
205
|
-
) : (
|
|
206
|
-
<Button type="button" size="sm" variant="outline" onClick={onMarkCompleted}>
|
|
207
|
-
Ya completé el pago en la pasarela
|
|
208
|
-
</Button>
|
|
209
|
-
)}
|
|
210
|
-
</div>
|
|
211
|
-
)
|
|
212
|
-
}
|