@fayz-ai/storefront 0.45.0 → 0.47.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/dist/{chunk-NH55KVUY.js → chunk-DK3KK373.js} +1219 -412
- package/dist/chunk-DK3KK373.js.map +1 -0
- package/dist/components/cart/CartDrawer.d.ts.map +1 -1
- package/dist/components/checkout/AddressForm.d.ts +39 -0
- package/dist/components/checkout/AddressForm.d.ts.map +1 -0
- package/dist/components/checkout/CheckoutField.d.ts +16 -0
- package/dist/components/checkout/CheckoutField.d.ts.map +1 -0
- package/dist/components/checkout/CheckoutSteps.d.ts.map +1 -1
- package/dist/components/checkout/DeliveryEstimator.d.ts.map +1 -1
- package/dist/components/delivery/DeliverToPicker.d.ts +19 -0
- package/dist/components/delivery/DeliverToPicker.d.ts.map +1 -0
- package/dist/components/layout/SearchOverlay.d.ts.map +1 -1
- package/dist/components/marketing/CollectionSections.d.ts.map +1 -1
- package/dist/components/product/ProductCard.d.ts +1 -1
- package/dist/components/product/ProductCard.d.ts.map +1 -1
- package/dist/document/config.d.ts +27 -1
- package/dist/document/config.d.ts.map +1 -1
- package/dist/document/store-policy.d.ts +12 -1
- package/dist/document/store-policy.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/use-buyer-country.d.ts +21 -0
- package/dist/hooks/use-buyer-country.d.ts.map +1 -0
- package/dist/hooks/use-market-product.d.ts +9 -0
- package/dist/hooks/use-market-product.d.ts.map +1 -0
- package/dist/hooks/use-payment-methods.d.ts.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/checkout-address.d.ts +21 -0
- package/dist/lib/checkout-address.d.ts.map +1 -0
- package/dist/locales/index.d.ts +10 -0
- package/dist/locales/index.d.ts.map +1 -0
- package/dist/locales/messages.d.ts +140 -0
- package/dist/locales/messages.d.ts.map +1 -0
- package/dist/render.js +1 -1
- package/dist/stores/buyer.store.d.ts +18 -0
- package/dist/stores/buyer.store.d.ts.map +1 -0
- package/dist/stores/cart.store.d.ts +6 -0
- package/dist/stores/cart.store.d.ts.map +1 -1
- package/dist/stores/delivery.store.d.ts +13 -2
- package/dist/stores/delivery.store.d.ts.map +1 -1
- package/dist/stores/market.store.d.ts +27 -0
- package/dist/stores/market.store.d.ts.map +1 -0
- package/dist/views/CheckoutPage.d.ts.map +1 -1
- package/dist/views/ProductDetailPage.d.ts.map +1 -1
- package/dist/workflows/checkout.d.ts.map +1 -1
- package/package.json +7 -7
- package/dist/chunk-NH55KVUY.js.map +0 -1
|
@@ -3,11 +3,11 @@ import { persist } from 'zustand/middleware';
|
|
|
3
3
|
import { createAuthRuntime, createMockAuthAdapter } from '@fayz-ai/plugin-auth';
|
|
4
4
|
import { getShopProvider, setShopProvider } from '@fayz-ai/shop/runtime';
|
|
5
5
|
import { setShopCarrierQuotesResolver, setShopAccessTokenResolver, setShopShippingItemsResolver } from '@fayz-ai/sdk/shop';
|
|
6
|
-
import { normalizePostalCode, lookupPostalCode, defaultRouterAdapter, defineLoader, staticRouterAdapter, isLoaderParamRef, isLoaderPropRef, resolveLoader, errorMessage, dataNeedKey, getBlockMeta, defaultPropsFromSettings, getBlockErrorVisibility, isBlockEnabledOn, checkBlockConstraints, checkBlockContext, repairBlockTree, renderBlocks, clearExtensionPoints, defineExtensionPoint, runExtensionPoint, runEscapeValve, breadcrumbJsonLd, hasEntityDeclaration, resolveEntityDeclaration, defineBlock, formatPostalCode, defineEntity, listEntityDeclarations, resolveHandle, seoOrigin, describeError, RESERVED_ENTITY_FIELDS, ENTITY_FIELD_TYPES, handleNameFor, registerHandle, hasHandle, listHandles, blockRegistry, loaderRegistry, listLoaders } from '@fayz-ai/core';
|
|
7
|
-
import
|
|
6
|
+
import { normalizePostalCode, getCountrySchema, lookupPostalCode, defaultRouterAdapter, defineLoader, staticRouterAdapter, isLoaderParamRef, isLoaderPropRef, resolveLoader, errorMessage, dataNeedKey, getBlockMeta, defaultPropsFromSettings, getBlockErrorVisibility, isBlockEnabledOn, checkBlockConstraints, checkBlockContext, repairBlockTree, renderBlocks, clearExtensionPoints, defineExtensionPoint, runExtensionPoint, runEscapeValve, breadcrumbJsonLd, hasEntityDeclaration, resolveEntityDeclaration, defineBlock, formatPostalCode, countryName, defineEntity, listEntityDeclarations, resolveHandle, seoOrigin, describeError, RESERVED_ENTITY_FIELDS, ENTITY_FIELD_TYPES, handleNameFor, registerHandle, validateAddress, hasHandle, listHandles, blockRegistry, loaderRegistry, listLoaders } from '@fayz-ai/core';
|
|
7
|
+
import React38, { createContext, useContext, useEffect, useRef, useState, useSyncExternalStore, useMemo, useCallback } from 'react';
|
|
8
8
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
9
|
-
import { isStorageImageUrl, imageVariantUrl, imageSrcSet, IMAGE_SRCSET_WIDTHS, validateDiscount, documentDigits, isChargeableProvider, supportsCard, formatDocument,
|
|
10
|
-
import { ChevronLeft, ChevronRight, ShoppingBag, X, Minus, Plus, Send, MessageCircle, Mail, Truck, RefreshCcw, ShieldCheck, ChevronDown, Check, Search, Menu, Trash2, Lock, CreditCard, Store, Bike, Clock,
|
|
9
|
+
import { isStorageImageUrl, imageVariantUrl, imageSrcSet, IMAGE_SRCSET_WIDTHS, validateDiscount, documentDigits, isChargeableProvider, supportsCard, formatDocument, gatewayLabel, isValidDocument } from '@fayz-ai/shop';
|
|
10
|
+
import { ChevronLeft, ChevronRight, ShoppingBag, X, Minus, Plus, Send, MessageCircle, Mail, Truck, RefreshCcw, ShieldCheck, ChevronDown, Check, Search, Menu, Trash2, MapPin, Lock, CreditCard, Store, Bike, Clock, Star, Phone, User, UserCircle, Package, LogOut, QrCode, Copy, XCircle, RotateCcw, PackageCheck, Info, AlertCircle } from 'lucide-react';
|
|
11
11
|
import { getLucideIcon } from '@fayz-ai/ui/icons';
|
|
12
12
|
import { storefrontDiscountToPromotion, previewCouponPercent, discountToPromotion, PROMOTION_TYPES, PROMOTION_STATUSES, APPLICATION_METHOD_TYPES, APPLICATION_METHOD_TARGET_TYPES, APPLICATION_METHOD_ALLOCATIONS, hasRuleAttribute, listRuleAttributeKeys, RULE_OPERATORS, resolveRuleAttribute } from '@fayz-ai/shop/rules';
|
|
13
13
|
import { createMockShopProvider } from '@fayz-ai/shop/mock';
|
|
@@ -155,6 +155,46 @@ async function signOutCustomer() {
|
|
|
155
155
|
useSessionStore.getState().signOut();
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
|
+
var useMarketStore = create()((set) => ({
|
|
159
|
+
markets: [],
|
|
160
|
+
active: null,
|
|
161
|
+
prices: {},
|
|
162
|
+
setMarkets: (markets) => set({ markets }),
|
|
163
|
+
setActive: (active2) => set({ active: active2 }),
|
|
164
|
+
setPrices: (code, list) => set((state) => ({
|
|
165
|
+
prices: {
|
|
166
|
+
...state.prices,
|
|
167
|
+
[code]: Object.fromEntries(list.map((p) => [`${p.productId}:${p.variantId ?? ""}`, p.price]))
|
|
168
|
+
}
|
|
169
|
+
}))
|
|
170
|
+
}));
|
|
171
|
+
function marketForCountry(markets, country) {
|
|
172
|
+
const iso2 = country.toUpperCase();
|
|
173
|
+
return markets.find((m) => m.countries.includes(iso2)) ?? markets.find((m) => m.isDefault) ?? null;
|
|
174
|
+
}
|
|
175
|
+
function marketUnitPrice(state, productId, variantId, fallback) {
|
|
176
|
+
const market = state.active;
|
|
177
|
+
if (!market) return fallback;
|
|
178
|
+
const list = state.prices[market.code];
|
|
179
|
+
const hit = list?.[`${productId}:${variantId ?? ""}`] ?? list?.[`${productId}:`];
|
|
180
|
+
if (hit != null) return hit;
|
|
181
|
+
return market.isDefault ? fallback : null;
|
|
182
|
+
}
|
|
183
|
+
function withMarketPrice(product, state = useMarketStore.getState()) {
|
|
184
|
+
const market = state.active;
|
|
185
|
+
if (!market || market.isDefault) return product;
|
|
186
|
+
const price = marketUnitPrice(state, product.id, null, product.price);
|
|
187
|
+
if (price == null) {
|
|
188
|
+
return { ...product, compareAtPrice: null, currency: market.currency, inventoryCount: 0, metadata: { ...product.metadata, unavailableInMarket: market.code } };
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
...product,
|
|
192
|
+
price,
|
|
193
|
+
compareAtPrice: null,
|
|
194
|
+
currency: market.currency,
|
|
195
|
+
variants: product.variants?.map((v) => ({ ...v, price: marketUnitPrice(state, product.id, v.id, v.price ?? product.price), compareAtPrice: null }))
|
|
196
|
+
};
|
|
197
|
+
}
|
|
158
198
|
|
|
159
199
|
// src/lib/format.ts
|
|
160
200
|
function formatMoney(value, currency = "BRL", locale = "pt-BR") {
|
|
@@ -240,11 +280,14 @@ function newAddressId() {
|
|
|
240
280
|
}
|
|
241
281
|
var EMPTY = {
|
|
242
282
|
postalCode: "",
|
|
283
|
+
country: "BR",
|
|
243
284
|
address: null,
|
|
244
285
|
options: [],
|
|
245
286
|
selectedZoneId: null,
|
|
246
287
|
status: "idle",
|
|
247
288
|
error: null,
|
|
289
|
+
errorKey: null,
|
|
290
|
+
errorVars: null,
|
|
248
291
|
refusedZone: null,
|
|
249
292
|
reviewZone: null
|
|
250
293
|
};
|
|
@@ -263,13 +306,33 @@ var useDeliveryStore = create()(
|
|
|
263
306
|
setScheduledFor(startsAt) {
|
|
264
307
|
set({ scheduledFor: startsAt });
|
|
265
308
|
},
|
|
266
|
-
async resolve(postalCode, subtotal) {
|
|
309
|
+
async resolve(postalCode, subtotal, country = "BR") {
|
|
310
|
+
const iso2 = country.toUpperCase();
|
|
311
|
+
if (iso2 !== "BR") {
|
|
312
|
+
const schema = getCountrySchema(iso2);
|
|
313
|
+
const code2 = schema.postal.normalize(postalCode);
|
|
314
|
+
if (!schema.postal.pattern.test(code2)) {
|
|
315
|
+
set({
|
|
316
|
+
...EMPTY,
|
|
317
|
+
postalCode,
|
|
318
|
+
country: iso2,
|
|
319
|
+
status: "error",
|
|
320
|
+
error: `Confira o c\xF3digo postal (ex.: ${schema.postal.example}).`,
|
|
321
|
+
errorKey: "delivery.error.postal",
|
|
322
|
+
errorVars: { example: schema.postal.example }
|
|
323
|
+
});
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
const address2 = await lookupPostalCode(code2, iso2).catch(() => null);
|
|
327
|
+
set({ ...EMPTY, postalCode: code2, country: iso2, address: address2, status: "idle" });
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
267
330
|
const code = normalizePostalCode(postalCode);
|
|
268
331
|
if (code.length !== 8) {
|
|
269
|
-
set({ ...EMPTY, postalCode, status: "error", error: "Digite os 8 d\xEDgitos do CEP." });
|
|
332
|
+
set({ ...EMPTY, postalCode, status: "error", error: "Digite os 8 d\xEDgitos do CEP.", errorKey: "delivery.error.digits" });
|
|
270
333
|
return;
|
|
271
334
|
}
|
|
272
|
-
set({ postalCode: code, status: "loading", error: null });
|
|
335
|
+
set({ postalCode: code, country: "BR", status: "loading", error: null, errorKey: null, errorVars: null });
|
|
273
336
|
const shop = getShopProvider();
|
|
274
337
|
const addressPromise = lookupPostalCode(code).catch(() => null);
|
|
275
338
|
const hint = await Promise.race([
|
|
@@ -287,7 +350,8 @@ var useDeliveryStore = create()(
|
|
|
287
350
|
...EMPTY,
|
|
288
351
|
postalCode: code,
|
|
289
352
|
status: "error",
|
|
290
|
-
error: "N\xE3o foi poss\xEDvel calcular o frete agora. Tente de novo."
|
|
353
|
+
error: "N\xE3o foi poss\xEDvel calcular o frete agora. Tente de novo.",
|
|
354
|
+
errorKey: "delivery.error.quote"
|
|
291
355
|
});
|
|
292
356
|
return;
|
|
293
357
|
}
|
|
@@ -310,7 +374,9 @@ var useDeliveryStore = create()(
|
|
|
310
374
|
status: options.length > 0 ? "served" : "unserved",
|
|
311
375
|
// Reported alongside the price, not instead of it: the CEP may be
|
|
312
376
|
// mistyped even though its range is covered.
|
|
313
|
-
error: notFound ? "CEP n\xE3o encontrado. Confira os n\xFAmeros." : null
|
|
377
|
+
error: notFound ? "CEP n\xE3o encontrado. Confira os n\xFAmeros." : null,
|
|
378
|
+
errorKey: notFound ? "delivery.error.notFound" : null,
|
|
379
|
+
errorVars: null
|
|
314
380
|
});
|
|
315
381
|
},
|
|
316
382
|
selectZone(zoneId) {
|
|
@@ -366,6 +432,7 @@ var useDeliveryStore = create()(
|
|
|
366
432
|
// comprador ao checkout com uma janela que o servidor vai recusar.
|
|
367
433
|
partialize: (state) => ({
|
|
368
434
|
postalCode: state.postalCode,
|
|
435
|
+
country: state.country,
|
|
369
436
|
address: state.address,
|
|
370
437
|
fulfillmentType: state.fulfillmentType,
|
|
371
438
|
// O caderno é o ponto: número e complemento são o que o comprador
|
|
@@ -376,6 +443,7 @@ var useDeliveryStore = create()(
|
|
|
376
443
|
}),
|
|
377
444
|
onRehydrateStorage: () => (state) => {
|
|
378
445
|
if (state?.address) state.status = "idle";
|
|
446
|
+
if (state && !state.country) state.country = "BR";
|
|
379
447
|
}
|
|
380
448
|
}
|
|
381
449
|
)
|
|
@@ -407,7 +475,9 @@ var useCartStore = create()(
|
|
|
407
475
|
const baseId = optionKey ? `${product.id}:${optionKey}` : product.id;
|
|
408
476
|
const lineId = cleanNotes ? `${baseId}#${cleanNotes}` : baseId;
|
|
409
477
|
const variant = resolveVariantForSelection(product, normalizedOptions);
|
|
410
|
-
const
|
|
478
|
+
const basePrice = variant?.price ?? product.price;
|
|
479
|
+
const unitPrice = marketUnitPrice(useMarketStore.getState(), product.id, variant?.id, basePrice);
|
|
480
|
+
if (unitPrice == null) return state;
|
|
411
481
|
const stock = variant ? variant.inventoryCount : product.inventoryCount;
|
|
412
482
|
const existing = state.lines.find((l) => (l.lineId ?? l.productId) === lineId);
|
|
413
483
|
if (existing) {
|
|
@@ -433,6 +503,7 @@ var useCartStore = create()(
|
|
|
433
503
|
options: normalizedOptions,
|
|
434
504
|
optionsLabel: formatProductOptionSelection(normalizedOptions),
|
|
435
505
|
unitPrice,
|
|
506
|
+
basePrice,
|
|
436
507
|
quantity: Math.min(qty, stock || Infinity),
|
|
437
508
|
imageUrl: image?.url ?? null,
|
|
438
509
|
maxQuantity: stock,
|
|
@@ -467,6 +538,20 @@ var useCartStore = create()(
|
|
|
467
538
|
}),
|
|
468
539
|
clearDiscount: () => set({ discountCode: null, discountPercent: 0, discountFreeShipping: false }),
|
|
469
540
|
clear: () => set({ lines: [], discountCode: null, discountPercent: 0, discountFreeShipping: false }),
|
|
541
|
+
repriceForMarket: () => set((state) => {
|
|
542
|
+
const market = useMarketStore.getState();
|
|
543
|
+
let changed = false;
|
|
544
|
+
const lines = state.lines.flatMap((line) => {
|
|
545
|
+
const price = marketUnitPrice(market, line.productId, line.variantId, line.basePrice ?? line.unitPrice);
|
|
546
|
+
if (price == null) {
|
|
547
|
+
changed = true;
|
|
548
|
+
return [];
|
|
549
|
+
}
|
|
550
|
+
if (price !== line.unitPrice) changed = true;
|
|
551
|
+
return [{ ...line, unitPrice: price }];
|
|
552
|
+
});
|
|
553
|
+
return changed ? { lines } : state;
|
|
554
|
+
}),
|
|
470
555
|
openDrawer: () => set({ isOpen: true }),
|
|
471
556
|
closeDrawer: () => set({ isOpen: false, justAddedLineId: null }),
|
|
472
557
|
reconcile: async (resolve) => {
|
|
@@ -808,6 +893,423 @@ function productPlaceholder(label, w = PLACEHOLDER_ASPECTS.product[0], h = PLACE
|
|
|
808
893
|
function escapeXml(text) {
|
|
809
894
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
810
895
|
}
|
|
896
|
+
|
|
897
|
+
// src/locales/messages.ts
|
|
898
|
+
var ptBR = {
|
|
899
|
+
// Checkout shell
|
|
900
|
+
"checkout.title": "Checkout \u2014 {{store}}",
|
|
901
|
+
"checkout.backToStore": "Voltar \xE0 loja",
|
|
902
|
+
"checkout.secure": "Checkout seguro",
|
|
903
|
+
"checkout.help": "Ajuda",
|
|
904
|
+
"checkout.steps.label": "Etapas do checkout",
|
|
905
|
+
"checkout.steps.1": "Dados",
|
|
906
|
+
"checkout.steps.2": "Entrega",
|
|
907
|
+
"checkout.steps.3": "Pagamento",
|
|
908
|
+
"checkout.steps.4": "Pronto",
|
|
909
|
+
// Step 1 — contact
|
|
910
|
+
"checkout.contact.title": "Informa\xE7\xF5es de contato",
|
|
911
|
+
"checkout.contact.signedInAs": "Conectado como {{email}}",
|
|
912
|
+
"checkout.contact.haveAccount": "J\xE1 tem conta? Entrar",
|
|
913
|
+
"checkout.contact.email": "E-mail",
|
|
914
|
+
"checkout.contact.name": "Nome completo",
|
|
915
|
+
"checkout.contact.phone": "Telefone",
|
|
916
|
+
"checkout.contact.phoneOptional": "Telefone (opcional)",
|
|
917
|
+
"checkout.contact.document": "CPF ou CNPJ",
|
|
918
|
+
"checkout.contact.documentOptional": "CPF ou CNPJ (opcional)",
|
|
919
|
+
"checkout.contact.requiresAccount": "Esta loja pede uma conta para finalizar a compra.",
|
|
920
|
+
"checkout.contact.signInOrCreate": "Entrar ou criar conta",
|
|
921
|
+
// Step 2 — address
|
|
922
|
+
"checkout.address.title": "Endere\xE7o de entrega",
|
|
923
|
+
"checkout.address.loadingSaved": "Buscando seus endere\xE7os salvos",
|
|
924
|
+
"checkout.address.selected": "Selecionado",
|
|
925
|
+
"checkout.address.addNew": "+ Adicionar novo endere\xE7o",
|
|
926
|
+
"checkout.address.enter": "Informe o endere\xE7o de entrega",
|
|
927
|
+
"checkout.address.enterHint": "Preencher outro endere\xE7o para esta compra",
|
|
928
|
+
"checkout.address.lookingUp": "Buscando o endere\xE7o deste CEP",
|
|
929
|
+
"checkout.address.notFound": "CEP n\xE3o encontrado \u2014 preencha o endere\xE7o \xE0 m\xE3o.",
|
|
930
|
+
"checkout.address.filled": "Preenchemos o endere\xE7o para voc\xEA.",
|
|
931
|
+
"checkout.address.regionFromPostal": "Prov\xEDncia preenchida pelo c\xF3digo postal.",
|
|
932
|
+
"checkout.address.optional": "{{label}} (opcional)",
|
|
933
|
+
"checkout.address.choose": "Selecione",
|
|
934
|
+
"checkout.address.shipTo": "Enviar para",
|
|
935
|
+
// Step 3 — payment
|
|
936
|
+
"checkout.confirming.title": "Confirmando seu pedido",
|
|
937
|
+
"checkout.confirming.label": "Criando seu pedido",
|
|
938
|
+
"checkout.confirming.keepOpen": "N\xE3o feche esta p\xE1gina \u2014 estamos registrando seu pedido na loja.",
|
|
939
|
+
"checkout.payment.title": "Pagamento",
|
|
940
|
+
"checkout.payment.label": "Forma de pagamento",
|
|
941
|
+
"checkout.payment.cardOnline": "Voc\xEA paga na p\xE1gina segura do provedor e volta para a loja",
|
|
942
|
+
"checkout.payment.placeOrder": "Fazer pedido - {{total}}",
|
|
943
|
+
"checkout.payment.pendingNote": "O pedido fica aguardando pagamento at\xE9 a loja confirmar.",
|
|
944
|
+
"checkout.payment.unavailableCountry": "Esta forma de pagamento n\xE3o est\xE1 dispon\xEDvel para {{country}}.",
|
|
945
|
+
"payment.pix.label": "Pix",
|
|
946
|
+
"payment.pix.hint": "Voc\xEA recebe a chave para pagar ap\xF3s confirmar o pedido",
|
|
947
|
+
"payment.credit_card.label": "Cart\xE3o de cr\xE9dito",
|
|
948
|
+
"payment.credit_card.hint": "Maquininha na entrega",
|
|
949
|
+
"payment.debit_card.label": "Cart\xE3o de d\xE9bito",
|
|
950
|
+
"payment.debit_card.hint": "Maquininha na entrega",
|
|
951
|
+
"payment.boleto.label": "Boleto",
|
|
952
|
+
"payment.boleto.hint": "Enviado por e-mail ap\xF3s a confirma\xE7\xE3o",
|
|
953
|
+
"payment.cash.label": "Dinheiro",
|
|
954
|
+
"payment.cash.hint": "Pagamento na entrega",
|
|
955
|
+
"payment.other.label": "Combinar com a loja",
|
|
956
|
+
"payment.other.hint": "A loja entra em contato para acertar o pagamento",
|
|
957
|
+
// Step 4
|
|
958
|
+
"checkout.done.title": "Pagamento confirmado!",
|
|
959
|
+
"checkout.done.text": "Seu pedido foi criado e a loja j\xE1 foi avisada.",
|
|
960
|
+
"checkout.done.viewOrder": "Ver meu pedido",
|
|
961
|
+
// Navigation
|
|
962
|
+
"checkout.continueToDelivery": "Continuar para a entrega",
|
|
963
|
+
"checkout.goToPayment": "Ir para o pagamento - {{total}}",
|
|
964
|
+
"checkout.backToContact": "Voltar aos dados",
|
|
965
|
+
"checkout.backToCart": "Voltar ao carrinho",
|
|
966
|
+
// Summary
|
|
967
|
+
"summary.title": "Resumo do pedido",
|
|
968
|
+
"summary.subtotal": "Subtotal",
|
|
969
|
+
"summary.discount": "Desconto",
|
|
970
|
+
"summary.delivery": "Entrega",
|
|
971
|
+
"summary.pickup": "Retirada na loja",
|
|
972
|
+
"summary.noFee": "Sem taxa",
|
|
973
|
+
"summary.free": "Gr\xE1tis",
|
|
974
|
+
"summary.total": "Total",
|
|
975
|
+
"summary.protected": "Compra protegida e dados criptografados.",
|
|
976
|
+
"summary.shipping": "Frete",
|
|
977
|
+
// Discount
|
|
978
|
+
"discount.placeholder": "Cupom de desconto",
|
|
979
|
+
"discount.apply": "Aplicar",
|
|
980
|
+
"discount.freeShipping": "frete gr\xE1tis",
|
|
981
|
+
"discount.percentOff": "{{percent}}% de desconto",
|
|
982
|
+
"discount.applied": "{{code}} aplicado: {{effect}}.",
|
|
983
|
+
"discount.appliedToast": "Cupom aplicado!",
|
|
984
|
+
"discount.invalid": "Cupom inv\xE1lido.",
|
|
985
|
+
"discount.invalidToast": "Cupom inv\xE1lido",
|
|
986
|
+
"discount.checkCode": "Verifique o c\xF3digo e tente novamente.",
|
|
987
|
+
"discount.cannotValidate": "N\xE3o conseguimos validar esse cupom agora.",
|
|
988
|
+
"discount.cannotValidateToast": "N\xE3o conseguimos validar o cupom",
|
|
989
|
+
"discount.tryLater": "Tente de novo em alguns instantes.",
|
|
990
|
+
// Legal
|
|
991
|
+
"legal.privacy": "Privacidade",
|
|
992
|
+
"legal.terms": "Termos",
|
|
993
|
+
"legal.refunds": "Trocas e devolu\xE7\xF5es",
|
|
994
|
+
// Validation
|
|
995
|
+
"error.requiresAccount": "Esta loja pede uma conta para finalizar a compra. Entre ou crie a sua.",
|
|
996
|
+
"error.email": "Informe um e-mail v\xE1lido.",
|
|
997
|
+
"error.name": "Informe seu nome completo.",
|
|
998
|
+
"error.phone": "Informe um telefone de contato.",
|
|
999
|
+
"error.documentInvalid": "CPF ou CNPJ inv\xE1lido \u2014 confira os n\xFAmeros.",
|
|
1000
|
+
"error.documentMissing": "Informe o CPF ou CNPJ do comprador.",
|
|
1001
|
+
"error.taxIdInvalid": "NIF/NIE inv\xE1lido \u2014 confira o n\xFAmero.",
|
|
1002
|
+
"error.address": "Preencha ou selecione o endere\xE7o de entrega.",
|
|
1003
|
+
"error.number": "Falta o n\xFAmero do endere\xE7o.",
|
|
1004
|
+
"error.complement": "Informe o complemento (apto, bloco).",
|
|
1005
|
+
"error.state": "Informe a UF com duas letras (ex.: RJ).",
|
|
1006
|
+
"error.postalInvalid": "Confira o c\xF3digo postal (ex.: {{example}}).",
|
|
1007
|
+
"error.region": "Selecione a {{label}}.",
|
|
1008
|
+
"error.refusedZone": "Esta loja n\xE3o entrega nesse endere\xE7o. Tente outro.",
|
|
1009
|
+
"error.unserved": "Ainda n\xE3o entregamos nesse CEP. Tente outro endere\xE7o.",
|
|
1010
|
+
"error.sessionMismatch": "Sua sess\xE3o ficou presa a outro cadastro. Recarregue a p\xE1gina e tente de novo.",
|
|
1011
|
+
"error.outOfStock": "Um item do carrinho ficou sem estoque. Revise o carrinho e tente de novo.",
|
|
1012
|
+
"error.placeOrder": "N\xE3o foi poss\xEDvel concluir o pedido.",
|
|
1013
|
+
// Delivery estimator
|
|
1014
|
+
"delivery.title": "Calcular entrega",
|
|
1015
|
+
"delivery.calculate": "Calcular",
|
|
1016
|
+
"delivery.postalLabel": "CEP",
|
|
1017
|
+
"delivery.change": "Trocar CEP",
|
|
1018
|
+
"delivery.unserved": "Ainda n\xE3o entregamos nesse CEP.",
|
|
1019
|
+
"delivery.refused": "Esta loja n\xE3o entrega nesse endere\xE7o.",
|
|
1020
|
+
"delivery.review": "Entregamos nessa regi\xE3o, mas confirmamos com voc\xEA antes de sair.",
|
|
1021
|
+
"delivery.etaSoon": "hoje ou amanh\xE3",
|
|
1022
|
+
"delivery.etaRange": "{{min}} a {{max}} dias \xFAteis",
|
|
1023
|
+
"delivery.etaDays": "{{days}} dia(s) \xFAtil(eis)",
|
|
1024
|
+
"delivery.flatRate": "O frete \xE9 calculado no checkout.",
|
|
1025
|
+
"delivery.error.digits": "Digite os 8 d\xEDgitos do CEP.",
|
|
1026
|
+
"delivery.error.postal": "Confira o c\xF3digo postal (ex.: {{example}}).",
|
|
1027
|
+
"delivery.error.quote": "N\xE3o foi poss\xEDvel calcular o frete agora. Tente de novo.",
|
|
1028
|
+
"delivery.error.notFound": "CEP n\xE3o encontrado. Confira os n\xFAmeros.",
|
|
1029
|
+
// Cart
|
|
1030
|
+
"cart.title": "Carrinho",
|
|
1031
|
+
"cart.close": "Fechar carrinho",
|
|
1032
|
+
"cart.empty": "Seu carrinho est\xE1 vazio.",
|
|
1033
|
+
"cart.remove": "Remover {{name}}",
|
|
1034
|
+
"cart.checkout": "Finalizar compra",
|
|
1035
|
+
"cart.missingForFree": "Faltam {{amount}} para frete gr\xE1tis",
|
|
1036
|
+
"cart.wonFree": "Voc\xEA ganhou frete gr\xE1tis!",
|
|
1037
|
+
// Deliver to
|
|
1038
|
+
"country.deliverTo": "Enviar para",
|
|
1039
|
+
"country.change": "Trocar pa\xEDs",
|
|
1040
|
+
"country.label": "Pa\xEDs de entrega"
|
|
1041
|
+
};
|
|
1042
|
+
var en = {
|
|
1043
|
+
"checkout.backToStore": "Back to store",
|
|
1044
|
+
"checkout.secure": "Secure checkout",
|
|
1045
|
+
"checkout.help": "Help",
|
|
1046
|
+
"checkout.steps.label": "Checkout steps",
|
|
1047
|
+
"checkout.steps.1": "Details",
|
|
1048
|
+
"checkout.steps.2": "Delivery",
|
|
1049
|
+
"checkout.steps.3": "Payment",
|
|
1050
|
+
"checkout.steps.4": "Done",
|
|
1051
|
+
"checkout.contact.title": "Contact information",
|
|
1052
|
+
"checkout.contact.signedInAs": "Signed in as {{email}}",
|
|
1053
|
+
"checkout.contact.haveAccount": "Have an account? Sign in",
|
|
1054
|
+
"checkout.contact.email": "Email",
|
|
1055
|
+
"checkout.contact.name": "Full name",
|
|
1056
|
+
"checkout.contact.phone": "Phone",
|
|
1057
|
+
"checkout.contact.phoneOptional": "Phone (optional)",
|
|
1058
|
+
"checkout.contact.document": "Tax ID",
|
|
1059
|
+
"checkout.contact.documentOptional": "Tax ID (optional)",
|
|
1060
|
+
"checkout.contact.requiresAccount": "This store needs an account to complete the purchase.",
|
|
1061
|
+
"checkout.contact.signInOrCreate": "Sign in or create an account",
|
|
1062
|
+
"checkout.address.title": "Delivery address",
|
|
1063
|
+
"checkout.address.loadingSaved": "Loading your saved addresses",
|
|
1064
|
+
"checkout.address.selected": "Selected",
|
|
1065
|
+
"checkout.address.addNew": "+ Add a new address",
|
|
1066
|
+
"checkout.address.enter": "Enter the delivery address",
|
|
1067
|
+
"checkout.address.enterHint": "Use a different address for this order",
|
|
1068
|
+
"checkout.address.lookingUp": "Looking up this postal code",
|
|
1069
|
+
"checkout.address.notFound": "Postal code not found \u2014 fill in the address by hand.",
|
|
1070
|
+
"checkout.address.filled": "We filled in the address for you.",
|
|
1071
|
+
"checkout.address.regionFromPostal": "Province filled in from the postcode.",
|
|
1072
|
+
"checkout.address.optional": "{{label}} (optional)",
|
|
1073
|
+
"checkout.address.choose": "Select",
|
|
1074
|
+
"checkout.address.shipTo": "Ship to",
|
|
1075
|
+
"checkout.confirming.title": "Confirming your order",
|
|
1076
|
+
"checkout.confirming.label": "Creating your order",
|
|
1077
|
+
"checkout.confirming.keepOpen": "Don\u2019t close this page \u2014 we\u2019re registering your order with the store.",
|
|
1078
|
+
"checkout.payment.title": "Payment",
|
|
1079
|
+
"checkout.payment.label": "Payment method",
|
|
1080
|
+
"checkout.payment.cardOnline": "You pay on the provider\u2019s secure page and come back to the store",
|
|
1081
|
+
"checkout.payment.placeOrder": "Place order - {{total}}",
|
|
1082
|
+
"checkout.payment.pendingNote": "The order awaits payment until the store confirms it.",
|
|
1083
|
+
"checkout.payment.unavailableCountry": "This payment method isn\u2019t available for {{country}}.",
|
|
1084
|
+
"payment.pix.hint": "You get the key to pay after confirming the order",
|
|
1085
|
+
"payment.credit_card.label": "Credit card",
|
|
1086
|
+
"payment.credit_card.hint": "Card machine on delivery",
|
|
1087
|
+
"payment.debit_card.label": "Debit card",
|
|
1088
|
+
"payment.debit_card.hint": "Card machine on delivery",
|
|
1089
|
+
"payment.boleto.hint": "Sent by email after confirmation",
|
|
1090
|
+
"payment.cash.label": "Cash",
|
|
1091
|
+
"payment.cash.hint": "Pay on delivery",
|
|
1092
|
+
"payment.other.label": "Arrange with the store",
|
|
1093
|
+
"payment.other.hint": "The store will contact you to arrange payment",
|
|
1094
|
+
"checkout.done.title": "Payment confirmed!",
|
|
1095
|
+
"checkout.done.text": "Your order was created and the store has been notified.",
|
|
1096
|
+
"checkout.done.viewOrder": "View my order",
|
|
1097
|
+
"checkout.continueToDelivery": "Continue to delivery",
|
|
1098
|
+
"checkout.goToPayment": "Go to payment - {{total}}",
|
|
1099
|
+
"checkout.backToContact": "Back to details",
|
|
1100
|
+
"checkout.backToCart": "Back to cart",
|
|
1101
|
+
"summary.title": "Order summary",
|
|
1102
|
+
"summary.discount": "Discount",
|
|
1103
|
+
"summary.delivery": "Delivery",
|
|
1104
|
+
"summary.pickup": "Store pickup",
|
|
1105
|
+
"summary.noFee": "No fee",
|
|
1106
|
+
"summary.free": "Free",
|
|
1107
|
+
"summary.protected": "Protected purchase, encrypted data.",
|
|
1108
|
+
"summary.shipping": "Shipping",
|
|
1109
|
+
"discount.placeholder": "Discount code",
|
|
1110
|
+
"discount.apply": "Apply",
|
|
1111
|
+
"discount.freeShipping": "free shipping",
|
|
1112
|
+
"discount.percentOff": "{{percent}}% off",
|
|
1113
|
+
"discount.applied": "{{code}} applied: {{effect}}.",
|
|
1114
|
+
"discount.appliedToast": "Code applied!",
|
|
1115
|
+
"discount.invalid": "Invalid code.",
|
|
1116
|
+
"discount.invalidToast": "Invalid code",
|
|
1117
|
+
"discount.checkCode": "Check the code and try again.",
|
|
1118
|
+
"discount.cannotValidate": "We couldn\u2019t check this code right now.",
|
|
1119
|
+
"discount.cannotValidateToast": "We couldn\u2019t check the code",
|
|
1120
|
+
"discount.tryLater": "Try again in a moment.",
|
|
1121
|
+
"legal.privacy": "Privacy",
|
|
1122
|
+
"legal.terms": "Terms",
|
|
1123
|
+
"legal.refunds": "Returns",
|
|
1124
|
+
"error.requiresAccount": "This store needs an account to complete the purchase. Sign in or create one.",
|
|
1125
|
+
"error.email": "Enter a valid email.",
|
|
1126
|
+
"error.name": "Enter your full name.",
|
|
1127
|
+
"error.phone": "Enter a contact phone number.",
|
|
1128
|
+
"error.documentInvalid": "Invalid tax ID \u2014 check the numbers.",
|
|
1129
|
+
"error.documentMissing": "Enter the buyer\u2019s tax ID.",
|
|
1130
|
+
"error.taxIdInvalid": "Invalid NIF/NIE \u2014 check the number.",
|
|
1131
|
+
"error.address": "Fill in or select the delivery address.",
|
|
1132
|
+
"error.number": "The street number is missing.",
|
|
1133
|
+
"error.complement": "Enter the apartment or unit.",
|
|
1134
|
+
"error.state": "Enter the two-letter state code (e.g. RJ).",
|
|
1135
|
+
"error.postalInvalid": "Check the postal code (e.g. {{example}}).",
|
|
1136
|
+
"error.region": "Select the {{label}}.",
|
|
1137
|
+
"error.refusedZone": "This store doesn\u2019t deliver to this address. Try another.",
|
|
1138
|
+
"error.unserved": "We don\u2019t deliver to this postal code yet. Try another address.",
|
|
1139
|
+
"error.sessionMismatch": "Your session got attached to another account. Reload the page and try again.",
|
|
1140
|
+
"error.outOfStock": "An item in your cart is out of stock. Review the cart and try again.",
|
|
1141
|
+
"error.placeOrder": "We couldn\u2019t complete the order.",
|
|
1142
|
+
"delivery.title": "Estimate delivery",
|
|
1143
|
+
"delivery.calculate": "Estimate",
|
|
1144
|
+
"delivery.postalLabel": "Postal code",
|
|
1145
|
+
"delivery.change": "Change postal code",
|
|
1146
|
+
"delivery.unserved": "We don\u2019t deliver to this postal code yet.",
|
|
1147
|
+
"delivery.refused": "This store doesn\u2019t deliver to this address.",
|
|
1148
|
+
"delivery.review": "We deliver to this area, but we\u2019ll confirm with you before shipping.",
|
|
1149
|
+
"delivery.etaSoon": "today or tomorrow",
|
|
1150
|
+
"delivery.etaRange": "{{min}} to {{max}} business days",
|
|
1151
|
+
"delivery.etaDays": "{{days}} business day(s)",
|
|
1152
|
+
"delivery.flatRate": "Shipping is calculated at checkout.",
|
|
1153
|
+
"delivery.error.digits": "Enter all 8 digits of the CEP.",
|
|
1154
|
+
"delivery.error.postal": "Check the postal code (e.g. {{example}}).",
|
|
1155
|
+
"delivery.error.quote": "We couldn\u2019t calculate shipping right now. Try again.",
|
|
1156
|
+
"delivery.error.notFound": "Postal code not found. Check the numbers.",
|
|
1157
|
+
"cart.title": "Cart",
|
|
1158
|
+
"cart.close": "Close cart",
|
|
1159
|
+
"cart.empty": "Your cart is empty.",
|
|
1160
|
+
"cart.remove": "Remove {{name}}",
|
|
1161
|
+
"cart.checkout": "Checkout",
|
|
1162
|
+
"cart.missingForFree": "{{amount}} away from free shipping",
|
|
1163
|
+
"cart.wonFree": "You got free shipping!",
|
|
1164
|
+
"country.deliverTo": "Deliver to",
|
|
1165
|
+
"country.change": "Change country",
|
|
1166
|
+
"country.label": "Delivery country"
|
|
1167
|
+
};
|
|
1168
|
+
var es = {
|
|
1169
|
+
"checkout.backToStore": "Volver a la tienda",
|
|
1170
|
+
"checkout.secure": "Pago seguro",
|
|
1171
|
+
"checkout.help": "Ayuda",
|
|
1172
|
+
"checkout.steps.label": "Pasos del pago",
|
|
1173
|
+
"checkout.steps.1": "Datos",
|
|
1174
|
+
"checkout.steps.2": "Env\xEDo",
|
|
1175
|
+
"checkout.steps.3": "Pago",
|
|
1176
|
+
"checkout.steps.4": "Listo",
|
|
1177
|
+
"checkout.contact.title": "Datos de contacto",
|
|
1178
|
+
"checkout.contact.signedInAs": "Has iniciado sesi\xF3n como {{email}}",
|
|
1179
|
+
"checkout.contact.haveAccount": "\xBFYa tienes cuenta? Entrar",
|
|
1180
|
+
"checkout.contact.email": "Email",
|
|
1181
|
+
"checkout.contact.name": "Nombre completo",
|
|
1182
|
+
"checkout.contact.phone": "Tel\xE9fono",
|
|
1183
|
+
"checkout.contact.phoneOptional": "Tel\xE9fono (opcional)",
|
|
1184
|
+
"checkout.contact.document": "NIF/NIE",
|
|
1185
|
+
"checkout.contact.documentOptional": "NIF/NIE (opcional)",
|
|
1186
|
+
"checkout.contact.requiresAccount": "Esta tienda pide una cuenta para finalizar la compra.",
|
|
1187
|
+
"checkout.contact.signInOrCreate": "Entrar o crear cuenta",
|
|
1188
|
+
"checkout.address.title": "Direcci\xF3n de env\xEDo",
|
|
1189
|
+
"checkout.address.loadingSaved": "Buscando tus direcciones guardadas",
|
|
1190
|
+
"checkout.address.selected": "Seleccionada",
|
|
1191
|
+
"checkout.address.addNew": "+ A\xF1adir una direcci\xF3n nueva",
|
|
1192
|
+
"checkout.address.enter": "Indica la direcci\xF3n de env\xEDo",
|
|
1193
|
+
"checkout.address.enterHint": "Usar otra direcci\xF3n para este pedido",
|
|
1194
|
+
"checkout.address.lookingUp": "Buscando este c\xF3digo postal",
|
|
1195
|
+
"checkout.address.notFound": "C\xF3digo postal no encontrado: rellena la direcci\xF3n a mano.",
|
|
1196
|
+
"checkout.address.filled": "Hemos rellenado la direcci\xF3n por ti.",
|
|
1197
|
+
"checkout.address.regionFromPostal": "Provincia rellenada a partir del c\xF3digo postal.",
|
|
1198
|
+
"checkout.address.optional": "{{label}} (opcional)",
|
|
1199
|
+
"checkout.address.choose": "Selecciona",
|
|
1200
|
+
"checkout.address.shipTo": "Enviar a",
|
|
1201
|
+
"checkout.confirming.title": "Confirmando tu pedido",
|
|
1202
|
+
"checkout.confirming.label": "Creando tu pedido",
|
|
1203
|
+
"checkout.confirming.keepOpen": "No cierres esta p\xE1gina: estamos registrando tu pedido en la tienda.",
|
|
1204
|
+
"checkout.payment.title": "Pago",
|
|
1205
|
+
"checkout.payment.label": "Forma de pago",
|
|
1206
|
+
"checkout.payment.cardOnline": "Pagas en la p\xE1gina segura del proveedor y vuelves a la tienda",
|
|
1207
|
+
"checkout.payment.placeOrder": "Hacer pedido - {{total}}",
|
|
1208
|
+
"checkout.payment.pendingNote": "El pedido queda pendiente de pago hasta que la tienda lo confirme.",
|
|
1209
|
+
"checkout.payment.unavailableCountry": "Esta forma de pago no est\xE1 disponible para {{country}}.",
|
|
1210
|
+
"payment.pix.hint": "Recibes la clave para pagar al confirmar el pedido",
|
|
1211
|
+
"payment.credit_card.label": "Tarjeta de cr\xE9dito",
|
|
1212
|
+
"payment.credit_card.hint": "Dat\xE1fono en la entrega",
|
|
1213
|
+
"payment.debit_card.label": "Tarjeta de d\xE9bito",
|
|
1214
|
+
"payment.debit_card.hint": "Dat\xE1fono en la entrega",
|
|
1215
|
+
"payment.boleto.hint": "Enviado por email tras la confirmaci\xF3n",
|
|
1216
|
+
"payment.cash.label": "Efectivo",
|
|
1217
|
+
"payment.cash.hint": "Pago en la entrega",
|
|
1218
|
+
"payment.other.label": "Acordar con la tienda",
|
|
1219
|
+
"payment.other.hint": "La tienda te contactar\xE1 para acordar el pago",
|
|
1220
|
+
"checkout.done.title": "\xA1Pago confirmado!",
|
|
1221
|
+
"checkout.done.text": "Tu pedido se ha creado y la tienda ya ha sido avisada.",
|
|
1222
|
+
"checkout.done.viewOrder": "Ver mi pedido",
|
|
1223
|
+
"checkout.continueToDelivery": "Continuar al env\xEDo",
|
|
1224
|
+
"checkout.goToPayment": "Ir al pago - {{total}}",
|
|
1225
|
+
"checkout.backToContact": "Volver a los datos",
|
|
1226
|
+
"checkout.backToCart": "Volver al carrito",
|
|
1227
|
+
"summary.title": "Resumen del pedido",
|
|
1228
|
+
"summary.discount": "Descuento",
|
|
1229
|
+
"summary.delivery": "Env\xEDo",
|
|
1230
|
+
"summary.pickup": "Recogida en tienda",
|
|
1231
|
+
"summary.noFee": "Sin coste",
|
|
1232
|
+
"summary.free": "Gratis",
|
|
1233
|
+
"summary.protected": "Compra protegida y datos cifrados.",
|
|
1234
|
+
"summary.shipping": "Env\xEDo",
|
|
1235
|
+
"discount.placeholder": "C\xF3digo de descuento",
|
|
1236
|
+
"discount.apply": "Aplicar",
|
|
1237
|
+
"discount.freeShipping": "env\xEDo gratis",
|
|
1238
|
+
"discount.percentOff": "{{percent}}% de descuento",
|
|
1239
|
+
"discount.applied": "{{code}} aplicado: {{effect}}.",
|
|
1240
|
+
"discount.appliedToast": "\xA1C\xF3digo aplicado!",
|
|
1241
|
+
"discount.invalid": "C\xF3digo no v\xE1lido.",
|
|
1242
|
+
"discount.invalidToast": "C\xF3digo no v\xE1lido",
|
|
1243
|
+
"discount.checkCode": "Revisa el c\xF3digo e int\xE9ntalo de nuevo.",
|
|
1244
|
+
"discount.cannotValidate": "No hemos podido validar este c\xF3digo ahora.",
|
|
1245
|
+
"discount.cannotValidateToast": "No hemos podido validar el c\xF3digo",
|
|
1246
|
+
"discount.tryLater": "Int\xE9ntalo de nuevo en unos instantes.",
|
|
1247
|
+
"legal.privacy": "Privacidad",
|
|
1248
|
+
"legal.terms": "T\xE9rminos",
|
|
1249
|
+
"legal.refunds": "Devoluciones",
|
|
1250
|
+
"error.requiresAccount": "Esta tienda pide una cuenta para finalizar la compra. Entra o crea la tuya.",
|
|
1251
|
+
"error.email": "Indica un email v\xE1lido.",
|
|
1252
|
+
"error.name": "Indica tu nombre completo.",
|
|
1253
|
+
"error.phone": "Indica un tel\xE9fono de contacto.",
|
|
1254
|
+
"error.documentInvalid": "Documento no v\xE1lido: revisa los n\xFAmeros.",
|
|
1255
|
+
"error.documentMissing": "Indica el documento del comprador.",
|
|
1256
|
+
"error.taxIdInvalid": "NIF/NIE no v\xE1lido: revisa el n\xFAmero.",
|
|
1257
|
+
"error.address": "Rellena o selecciona la direcci\xF3n de env\xEDo.",
|
|
1258
|
+
"error.number": "Falta el n\xFAmero de la direcci\xF3n.",
|
|
1259
|
+
"error.complement": "Indica el piso o la puerta.",
|
|
1260
|
+
"error.state": "Indica el estado con dos letras (ej.: RJ).",
|
|
1261
|
+
"error.postalInvalid": "Revisa el c\xF3digo postal (ej.: {{example}}).",
|
|
1262
|
+
"error.region": "Selecciona la {{label}}.",
|
|
1263
|
+
"error.refusedZone": "Esta tienda no env\xEDa a esta direcci\xF3n. Prueba con otra.",
|
|
1264
|
+
"error.unserved": "Todav\xEDa no enviamos a este c\xF3digo postal. Prueba con otra direcci\xF3n.",
|
|
1265
|
+
"error.sessionMismatch": "Tu sesi\xF3n qued\xF3 vinculada a otra cuenta. Recarga la p\xE1gina e int\xE9ntalo de nuevo.",
|
|
1266
|
+
"error.outOfStock": "Un producto del carrito se ha agotado. Revisa el carrito e int\xE9ntalo de nuevo.",
|
|
1267
|
+
"error.placeOrder": "No se ha podido completar el pedido.",
|
|
1268
|
+
"delivery.title": "Calcular env\xEDo",
|
|
1269
|
+
"delivery.calculate": "Calcular",
|
|
1270
|
+
"delivery.postalLabel": "C\xF3digo postal",
|
|
1271
|
+
"delivery.change": "Cambiar c\xF3digo postal",
|
|
1272
|
+
"delivery.unserved": "Todav\xEDa no enviamos a este c\xF3digo postal.",
|
|
1273
|
+
"delivery.refused": "Esta tienda no env\xEDa a esta direcci\xF3n.",
|
|
1274
|
+
"delivery.review": "Enviamos a esta zona, pero lo confirmamos contigo antes de salir.",
|
|
1275
|
+
"delivery.etaSoon": "hoy o ma\xF1ana",
|
|
1276
|
+
"delivery.etaRange": "de {{min}} a {{max}} d\xEDas laborables",
|
|
1277
|
+
"delivery.etaDays": "{{days}} d\xEDa(s) laborable(s)",
|
|
1278
|
+
"delivery.flatRate": "El env\xEDo se calcula en el pago.",
|
|
1279
|
+
"delivery.error.digits": "Escribe los 8 d\xEDgitos del CEP.",
|
|
1280
|
+
"delivery.error.postal": "Revisa el c\xF3digo postal (ej.: {{example}}).",
|
|
1281
|
+
"delivery.error.quote": "No hemos podido calcular el env\xEDo ahora. Int\xE9ntalo de nuevo.",
|
|
1282
|
+
"delivery.error.notFound": "C\xF3digo postal no encontrado. Revisa los n\xFAmeros.",
|
|
1283
|
+
"cart.title": "Carrito",
|
|
1284
|
+
"cart.close": "Cerrar carrito",
|
|
1285
|
+
"cart.empty": "Tu carrito est\xE1 vac\xEDo.",
|
|
1286
|
+
"cart.remove": "Quitar {{name}}",
|
|
1287
|
+
"cart.checkout": "Finalizar compra",
|
|
1288
|
+
"cart.missingForFree": "Te faltan {{amount}} para el env\xEDo gratis",
|
|
1289
|
+
"cart.wonFree": "\xA1Tienes env\xEDo gratis!",
|
|
1290
|
+
"country.deliverTo": "Enviar a",
|
|
1291
|
+
"country.change": "Cambiar pa\xEDs",
|
|
1292
|
+
"country.label": "Pa\xEDs de env\xEDo"
|
|
1293
|
+
};
|
|
1294
|
+
var MESSAGES = { "pt-BR": ptBR, en, es };
|
|
1295
|
+
function normalizeLanguage(value) {
|
|
1296
|
+
const base = (value || "").toLowerCase().split(/[-_]/)[0];
|
|
1297
|
+
if (base === "pt") return "pt-BR";
|
|
1298
|
+
if (base === "en") return "en";
|
|
1299
|
+
if (base === "es") return "es";
|
|
1300
|
+
return null;
|
|
1301
|
+
}
|
|
1302
|
+
function translate(language, key, vars, overrides) {
|
|
1303
|
+
let text = overrides?.[language]?.[key] ?? MESSAGES[language]?.[key] ?? overrides?.["pt-BR"]?.[key] ?? ptBR[key];
|
|
1304
|
+
if (vars) for (const [name, value] of Object.entries(vars)) text = text.split(`{{${name}}}`).join(String(value));
|
|
1305
|
+
return text;
|
|
1306
|
+
}
|
|
1307
|
+
function resolveCountries(config) {
|
|
1308
|
+
const countries = [...new Set((config.countries ?? []).map((c) => c.trim().toUpperCase()).filter(Boolean))];
|
|
1309
|
+
if (countries.length === 0) countries.push("BR");
|
|
1310
|
+
const wanted = config.defaultCountry?.trim().toUpperCase();
|
|
1311
|
+
return { countries, defaultCountry: wanted && countries.includes(wanted) ? wanted : countries[0] };
|
|
1312
|
+
}
|
|
811
1313
|
function resolveConfig(config) {
|
|
812
1314
|
const homePage = config.pages?.home ?? (config.home ? { blocks: config.home.sections } : void 0);
|
|
813
1315
|
const catalogPath = homePage ? "/catalog" : "/";
|
|
@@ -818,6 +1320,8 @@ function resolveConfig(config) {
|
|
|
818
1320
|
pages: { ...config.pages, ...homePage ? { home: homePage } : {} },
|
|
819
1321
|
currency: config.currency ?? "BRL",
|
|
820
1322
|
locale: config.locale ?? "pt-BR",
|
|
1323
|
+
language: normalizeLanguage(config.language) ?? "pt-BR",
|
|
1324
|
+
...resolveCountries(config),
|
|
821
1325
|
shipping: { flatRate: config.shipping?.flatRate ?? 0, freeAbove: config.shipping?.freeAbove },
|
|
822
1326
|
payments: {
|
|
823
1327
|
mode: config.payments?.mode ?? "mock",
|
|
@@ -1065,7 +1569,7 @@ function Link({ to, children, onClick, target, ...rest }) {
|
|
|
1065
1569
|
event.preventDefault();
|
|
1066
1570
|
adapter.navigate(to);
|
|
1067
1571
|
};
|
|
1068
|
-
return
|
|
1572
|
+
return React38.createElement(
|
|
1069
1573
|
"a",
|
|
1070
1574
|
{ href: adapter.href(to), onClick: handleClick, target, ...rest },
|
|
1071
1575
|
children
|
|
@@ -1305,9 +1809,9 @@ function SmoothImage({
|
|
|
1305
1809
|
const easing = resolved.easing ?? "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
1306
1810
|
const blur = resolved.blur ?? true;
|
|
1307
1811
|
const transform = resolved.transform ?? "none";
|
|
1308
|
-
const ref =
|
|
1309
|
-
const [loaded, setLoaded] =
|
|
1310
|
-
const delivered =
|
|
1812
|
+
const ref = React38.useRef(null);
|
|
1813
|
+
const [loaded, setLoaded] = React38.useState(() => mode === "none" || !clientMounted);
|
|
1814
|
+
const delivered = React38.useMemo(() => {
|
|
1311
1815
|
if (transform !== "supabase" || !src || srcSet || !isStorageImageUrl(src)) return { src, srcSet, sizes };
|
|
1312
1816
|
if (variant?.width) {
|
|
1313
1817
|
const w = variant.width;
|
|
@@ -1325,10 +1829,10 @@ function SmoothImage({
|
|
|
1325
1829
|
sizes: variant?.sizes ?? sizes ?? "100vw"
|
|
1326
1830
|
};
|
|
1327
1831
|
}, [transform, src, srcSet, sizes, variant?.width, variant?.sizes, variant?.widths, variant?.quality]);
|
|
1328
|
-
|
|
1832
|
+
React38.useEffect(() => {
|
|
1329
1833
|
clientMounted = true;
|
|
1330
1834
|
}, []);
|
|
1331
|
-
|
|
1835
|
+
React38.useEffect(() => {
|
|
1332
1836
|
if (mode === "none") {
|
|
1333
1837
|
setLoaded(true);
|
|
1334
1838
|
return;
|
|
@@ -1935,6 +2439,14 @@ function useStorefrontActions() {
|
|
|
1935
2439
|
createProductEnquiry
|
|
1936
2440
|
};
|
|
1937
2441
|
}
|
|
2442
|
+
function useMarketProduct(product) {
|
|
2443
|
+
const active2 = useMarketStore((s2) => s2.active);
|
|
2444
|
+
const prices = useMarketStore((s2) => s2.prices);
|
|
2445
|
+
return useMemo(
|
|
2446
|
+
() => product ? withMarketPrice(product, { active: active2, prices }) : product,
|
|
2447
|
+
[product, active2, prices]
|
|
2448
|
+
);
|
|
2449
|
+
}
|
|
1938
2450
|
function Price({ value, compareAt, testId, compareTestId, className }) {
|
|
1939
2451
|
const { currency, locale } = useStorefrontConfig();
|
|
1940
2452
|
return /* @__PURE__ */ jsxs("span", { className: `inline-flex items-baseline gap-2 ${className ?? ""}`, children: [
|
|
@@ -2596,8 +3108,8 @@ var BADGE_TONE_CLASSES = {
|
|
|
2596
3108
|
warning: "bg-amber-500 text-white"
|
|
2597
3109
|
};
|
|
2598
3110
|
function useExtensionBadges(product) {
|
|
2599
|
-
const [badges, setBadges] =
|
|
2600
|
-
|
|
3111
|
+
const [badges, setBadges] = React38.useState([]);
|
|
3112
|
+
React38.useEffect(() => {
|
|
2601
3113
|
let cancelled = false;
|
|
2602
3114
|
getProductCardBadges(product).then((next) => {
|
|
2603
3115
|
if (!cancelled && next.length > 0) setBadges(next);
|
|
@@ -2617,7 +3129,8 @@ function pickProductCardImage(images, order = "primary") {
|
|
|
2617
3129
|
}
|
|
2618
3130
|
return images.find((i) => i.isPrimary) ?? images[0];
|
|
2619
3131
|
}
|
|
2620
|
-
function ProductCard({ product, config: providedConfig, actions: providedActions, imageOrder = "primary" }) {
|
|
3132
|
+
function ProductCard({ product: catalogProduct, config: providedConfig, actions: providedActions, imageOrder = "primary" }) {
|
|
3133
|
+
const product = useMarketProduct(catalogProduct);
|
|
2621
3134
|
const runtimeConfig = useStorefrontConfig();
|
|
2622
3135
|
const runtimeActions = useStorefrontActions();
|
|
2623
3136
|
const config = providedConfig ?? runtimeConfig;
|
|
@@ -3793,7 +4306,7 @@ function scalarToString(value) {
|
|
|
3793
4306
|
}
|
|
3794
4307
|
function ProductSpecs({ product }) {
|
|
3795
4308
|
const config = useStorefrontConfig();
|
|
3796
|
-
const extraExcluded =
|
|
4309
|
+
const extraExcluded = React38.useMemo(
|
|
3797
4310
|
() => new Set(config.productSpecs?.exclude ?? []),
|
|
3798
4311
|
[config.productSpecs?.exclude]
|
|
3799
4312
|
);
|
|
@@ -4213,6 +4726,65 @@ function GalleryArrow({ side, onClick, canHover }) {
|
|
|
4213
4726
|
}
|
|
4214
4727
|
);
|
|
4215
4728
|
}
|
|
4729
|
+
var BUYER_COUNTRY_COOKIE = "fayz_country";
|
|
4730
|
+
var useBuyerStore = create()(
|
|
4731
|
+
persist(
|
|
4732
|
+
(set) => ({
|
|
4733
|
+
picked: null,
|
|
4734
|
+
pick(country) {
|
|
4735
|
+
const iso2 = country.trim().toUpperCase();
|
|
4736
|
+
set({ picked: iso2 });
|
|
4737
|
+
try {
|
|
4738
|
+
document.cookie = `${BUYER_COUNTRY_COOKIE}=${iso2}; path=/; max-age=31536000; samesite=lax`;
|
|
4739
|
+
} catch {
|
|
4740
|
+
}
|
|
4741
|
+
}
|
|
4742
|
+
}),
|
|
4743
|
+
{ name: "fayz.storefront.buyer.v1" }
|
|
4744
|
+
)
|
|
4745
|
+
);
|
|
4746
|
+
function navigatorRegion() {
|
|
4747
|
+
try {
|
|
4748
|
+
for (const tag of navigator.languages ?? [navigator.language]) {
|
|
4749
|
+
const region = tag?.split(/[-_]/)[1];
|
|
4750
|
+
if (region && /^[A-Za-z]{2}$/.test(region)) return region.toUpperCase();
|
|
4751
|
+
}
|
|
4752
|
+
} catch {
|
|
4753
|
+
}
|
|
4754
|
+
return void 0;
|
|
4755
|
+
}
|
|
4756
|
+
function useBuyerCountry() {
|
|
4757
|
+
const config = useStorefrontConfig();
|
|
4758
|
+
const allowed = config.countries;
|
|
4759
|
+
const picked = useBuyerStore((s2) => s2.picked);
|
|
4760
|
+
const pick = useBuyerStore((s2) => s2.pick);
|
|
4761
|
+
const [mounted, setMounted] = useState(false);
|
|
4762
|
+
useEffect(() => setMounted(true), []);
|
|
4763
|
+
const ok = (c) => !!c && allowed.includes(c);
|
|
4764
|
+
let country = ok(config.countryHint) ? config.countryHint : config.defaultCountry;
|
|
4765
|
+
if (allowed.length > 1 && mounted) {
|
|
4766
|
+
const region = navigatorRegion();
|
|
4767
|
+
if (ok(picked)) country = picked;
|
|
4768
|
+
else if (!ok(config.countryHint) && ok(region)) country = region;
|
|
4769
|
+
}
|
|
4770
|
+
return {
|
|
4771
|
+
country,
|
|
4772
|
+
allowed,
|
|
4773
|
+
schema: getCountrySchema(country),
|
|
4774
|
+
setCountry(next) {
|
|
4775
|
+
const iso2 = next.toUpperCase();
|
|
4776
|
+
if (!allowed.includes(iso2) || iso2 === country) return;
|
|
4777
|
+
pick(iso2);
|
|
4778
|
+
useDeliveryStore.getState().clear();
|
|
4779
|
+
}
|
|
4780
|
+
};
|
|
4781
|
+
}
|
|
4782
|
+
function useT() {
|
|
4783
|
+
const config = useStorefrontConfig();
|
|
4784
|
+
const language = config.language;
|
|
4785
|
+
const overrides = config.messages;
|
|
4786
|
+
return useCallback((key, vars) => translate(language, key, vars, overrides), [language, overrides]);
|
|
4787
|
+
}
|
|
4216
4788
|
function RelatedProducts({ product }) {
|
|
4217
4789
|
const config = useStorefrontConfig();
|
|
4218
4790
|
const actions = useStorefrontActions();
|
|
@@ -4241,21 +4813,24 @@ function DeliveryEstimator({ compact: compact2 = false }) {
|
|
|
4241
4813
|
const config = useStorefrontConfig();
|
|
4242
4814
|
const cart = useCartStore();
|
|
4243
4815
|
const delivery = useDeliveryStore();
|
|
4244
|
-
const
|
|
4816
|
+
const t = useT();
|
|
4817
|
+
const { country, schema } = useBuyerCountry();
|
|
4818
|
+
const isBrazil = country === "BR";
|
|
4819
|
+
const [draft, setDraft] = useState(() => delivery.country === country ? formatPostalCode(delivery.postalCode, country) : "");
|
|
4245
4820
|
const subtotal = selectSubtotal(cart);
|
|
4246
4821
|
const money = (value) => formatMoney(value, config.currency, config.locale);
|
|
4247
4822
|
const loading = delivery.status === "loading";
|
|
4248
4823
|
const resolved = delivery.status === "served";
|
|
4249
4824
|
async function submit(event) {
|
|
4250
4825
|
event.preventDefault();
|
|
4251
|
-
await delivery.resolve(draft, subtotal);
|
|
4826
|
+
await delivery.resolve(draft, subtotal, country);
|
|
4252
4827
|
}
|
|
4253
4828
|
function eta(option) {
|
|
4254
4829
|
const { etaMinDays: min, etaMaxDays: max } = option;
|
|
4255
4830
|
if (min == null && max == null) return null;
|
|
4256
|
-
if (min === 0 && (max === 0 || max === 1)) return "
|
|
4257
|
-
if (min != null && max != null && min !== max) return
|
|
4258
|
-
return
|
|
4831
|
+
if (min === 0 && (max === 0 || max === 1)) return t("delivery.etaSoon");
|
|
4832
|
+
if (min != null && max != null && min !== max) return t("delivery.etaRange", { min, max });
|
|
4833
|
+
return t("delivery.etaDays", { days: String(max ?? min) });
|
|
4259
4834
|
}
|
|
4260
4835
|
return /* @__PURE__ */ jsxs(
|
|
4261
4836
|
"section",
|
|
@@ -4266,19 +4841,19 @@ function DeliveryEstimator({ compact: compact2 = false }) {
|
|
|
4266
4841
|
!resolved && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4267
4842
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm font-semibold", children: [
|
|
4268
4843
|
/* @__PURE__ */ jsx(Truck, { className: "h-4 w-4 text-primary" }),
|
|
4269
|
-
"
|
|
4844
|
+
t("delivery.title")
|
|
4270
4845
|
] }),
|
|
4271
4846
|
/* @__PURE__ */ jsxs("form", { onSubmit: submit, className: "mt-3 flex gap-2", children: [
|
|
4272
4847
|
/* @__PURE__ */ jsx(
|
|
4273
4848
|
"input",
|
|
4274
4849
|
{
|
|
4275
4850
|
"data-testid": TID.deliveryCepInput,
|
|
4276
|
-
"aria-label": "CEP",
|
|
4277
|
-
inputMode:
|
|
4851
|
+
"aria-label": isBrazil ? "CEP" : t("delivery.postalLabel"),
|
|
4852
|
+
inputMode: schema.postal.inputMode,
|
|
4278
4853
|
autoComplete: "postal-code",
|
|
4279
|
-
placeholder: "00000-000",
|
|
4854
|
+
placeholder: isBrazil ? "00000-000" : schema.postal.example,
|
|
4280
4855
|
value: draft,
|
|
4281
|
-
onChange: (event) => setDraft(formatPostalCode(event.target.value)),
|
|
4856
|
+
onChange: (event) => setDraft(formatPostalCode(event.target.value, country)),
|
|
4282
4857
|
className: "min-w-0 flex-1 rounded-lg border bg-background px-3 py-2 text-sm outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/10"
|
|
4283
4858
|
}
|
|
4284
4859
|
),
|
|
@@ -4289,22 +4864,21 @@ function DeliveryEstimator({ compact: compact2 = false }) {
|
|
|
4289
4864
|
"data-testid": TID.deliveryCepSubmit,
|
|
4290
4865
|
disabled: loading,
|
|
4291
4866
|
className: "shrink-0 rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground transition hover:opacity-90 disabled:opacity-50",
|
|
4292
|
-
children: loading ? "..." : "
|
|
4867
|
+
children: loading ? "..." : t("delivery.calculate")
|
|
4293
4868
|
}
|
|
4294
4869
|
)
|
|
4295
4870
|
] })
|
|
4296
4871
|
] }),
|
|
4297
|
-
delivery.error && /* @__PURE__ */ jsx("p", { "data-testid": TID.deliveryError, className: "mt-3 text-sm text-destructive", children: delivery.error }),
|
|
4872
|
+
delivery.error && /* @__PURE__ */ jsx("p", { "data-testid": TID.deliveryError, className: "mt-3 text-sm text-destructive", children: delivery.errorKey ? t(delivery.errorKey, delivery.errorVars ?? void 0) : delivery.error }),
|
|
4298
4873
|
delivery.address && /* @__PURE__ */ jsxs("p", { "data-testid": TID.deliveryAddress, className: "mt-3 flex items-start gap-1.5 text-xs text-muted-foreground", children: [
|
|
4299
4874
|
/* @__PURE__ */ jsx(MapPin, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }),
|
|
4300
4875
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
4301
4876
|
[delivery.address.street, delivery.address.district].filter(Boolean).join(", "),
|
|
4302
4877
|
delivery.address.street || delivery.address.district ? " \u2014 " : "",
|
|
4303
|
-
delivery.address.city,
|
|
4304
|
-
"/",
|
|
4305
|
-
delivery.address.state
|
|
4878
|
+
[delivery.address.city, delivery.address.state].filter(Boolean).join("/")
|
|
4306
4879
|
] })
|
|
4307
4880
|
] }),
|
|
4881
|
+
!isBrazil && delivery.country === country && delivery.postalCode && delivery.status === "idle" && /* @__PURE__ */ jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: t("delivery.flatRate") }),
|
|
4308
4882
|
delivery.status === "served" && /* @__PURE__ */ jsx("ul", { className: "mt-3 space-y-2", children: delivery.options.map((option) => {
|
|
4309
4883
|
const selected = delivery.selectedZoneId === option.zoneId;
|
|
4310
4884
|
const label = eta(option);
|
|
@@ -4324,13 +4898,13 @@ function DeliveryEstimator({ compact: compact2 = false }) {
|
|
|
4324
4898
|
/* @__PURE__ */ jsx("span", { className: "block truncate font-medium", children: option.carrier ? `${option.carrier} \xB7 ${option.name}` : option.name }),
|
|
4325
4899
|
label && /* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground", children: label })
|
|
4326
4900
|
] }),
|
|
4327
|
-
/* @__PURE__ */ jsx("span", { className: "shrink-0 font-semibold", children: rate === 0 ? "
|
|
4901
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 font-semibold", children: rate === 0 ? t("summary.free") : money(rate) })
|
|
4328
4902
|
]
|
|
4329
4903
|
}
|
|
4330
4904
|
) }, option.zoneId);
|
|
4331
4905
|
}) }),
|
|
4332
|
-
delivery.status === "unserved" && /* @__PURE__ */ jsx("p", { "data-testid": TID.deliveryUnserved, className: "mt-3 text-sm text-destructive", children: delivery.refusedZone ? "
|
|
4333
|
-
delivery.reviewZone && delivery.status === "served" && /* @__PURE__ */ jsx("p", { className: "mt-3 text-sm text-amber-600 dark:text-amber-500", children: "
|
|
4906
|
+
delivery.status === "unserved" && /* @__PURE__ */ jsx("p", { "data-testid": TID.deliveryUnserved, className: "mt-3 text-sm text-destructive", children: delivery.refusedZone ? t("delivery.refused") : t("delivery.unserved") }),
|
|
4907
|
+
delivery.reviewZone && delivery.status === "served" && /* @__PURE__ */ jsx("p", { className: "mt-3 text-sm text-amber-600 dark:text-amber-500", children: t("delivery.review") }),
|
|
4334
4908
|
delivery.postalCode && /* @__PURE__ */ jsx(
|
|
4335
4909
|
"button",
|
|
4336
4910
|
{
|
|
@@ -4341,7 +4915,7 @@ function DeliveryEstimator({ compact: compact2 = false }) {
|
|
|
4341
4915
|
setDraft("");
|
|
4342
4916
|
},
|
|
4343
4917
|
className: "mt-3 py-1 text-xs text-muted-foreground underline-offset-2 hover:underline",
|
|
4344
|
-
children: "
|
|
4918
|
+
children: t("delivery.change")
|
|
4345
4919
|
}
|
|
4346
4920
|
)
|
|
4347
4921
|
]
|
|
@@ -4351,7 +4925,8 @@ function DeliveryEstimator({ compact: compact2 = false }) {
|
|
|
4351
4925
|
function ProductDetailPage({ slug }) {
|
|
4352
4926
|
const config = useStorefrontConfig();
|
|
4353
4927
|
const actions = useStorefrontActions();
|
|
4354
|
-
const { product, loading } = useProduct(slug);
|
|
4928
|
+
const { product: catalogProduct, loading } = useProduct(slug);
|
|
4929
|
+
const product = useMarketProduct(catalogProduct);
|
|
4355
4930
|
const addItem = useCartStore((s2) => s2.addItem);
|
|
4356
4931
|
const [qty, setQty] = useState(1);
|
|
4357
4932
|
const [selectedOptions, setSelectedOptions] = useState({});
|
|
@@ -4590,7 +5165,7 @@ function buildEnquiryFromForm(fields, values, subject, sourceUrl) {
|
|
|
4590
5165
|
const phoneField = fields.find((f2) => f2.type === "phone");
|
|
4591
5166
|
const nameField = fields.find((f2) => f2.id === "name") ?? fields.find((f2) => (f2.type ?? "text") === "text" && f2 !== emailField && f2 !== phoneField);
|
|
4592
5167
|
const identity = /* @__PURE__ */ new Set([emailField?.id, phoneField?.id, nameField?.id]);
|
|
4593
|
-
const lines = fields.filter((f2) => !identity.has(f2.id)).map((f2) => ({ field: f2, value: (values[f2.id] ?? "").trim() })).filter((entry) => entry.value).map(({ field
|
|
5168
|
+
const lines = fields.filter((f2) => !identity.has(f2.id)).map((f2) => ({ field: f2, value: (values[f2.id] ?? "").trim() })).filter((entry) => entry.value).map(({ field, value }) => field.type === "textarea" ? value : `${field.label}: ${value}`);
|
|
4594
5169
|
return {
|
|
4595
5170
|
productName: subject,
|
|
4596
5171
|
customerName: nameField && values[nameField.id]?.trim() || "Visitante",
|
|
@@ -4604,31 +5179,31 @@ function buildEnquiryFromForm(fields, values, subject, sourceUrl) {
|
|
|
4604
5179
|
}
|
|
4605
5180
|
var INPUT_CLASS = "w-full border bg-background px-3 py-2 text-sm outline-none focus:border-primary";
|
|
4606
5181
|
function Field({
|
|
4607
|
-
field
|
|
5182
|
+
field,
|
|
4608
5183
|
value,
|
|
4609
5184
|
onChange
|
|
4610
5185
|
}) {
|
|
4611
5186
|
const common = {
|
|
4612
|
-
"data-testid": TID.formBlockField(
|
|
4613
|
-
required:
|
|
5187
|
+
"data-testid": TID.formBlockField(field.id),
|
|
5188
|
+
required: field.required,
|
|
4614
5189
|
value,
|
|
4615
|
-
placeholder:
|
|
5190
|
+
placeholder: field.placeholder,
|
|
4616
5191
|
className: INPUT_CLASS,
|
|
4617
5192
|
style: { borderRadius: "var(--sf-radius-input)" }
|
|
4618
5193
|
};
|
|
4619
|
-
return /* @__PURE__ */ jsxs("label", { className: `space-y-1.5 text-sm font-medium ${
|
|
5194
|
+
return /* @__PURE__ */ jsxs("label", { className: `space-y-1.5 text-sm font-medium ${field.type === "textarea" ? "block" : ""}`, children: [
|
|
4620
5195
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
4621
|
-
|
|
4622
|
-
|
|
5196
|
+
field.label,
|
|
5197
|
+
field.required ? "" : " (opcional)"
|
|
4623
5198
|
] }),
|
|
4624
|
-
|
|
5199
|
+
field.type === "textarea" ? /* @__PURE__ */ jsx("textarea", { ...common, rows: 5, onChange: (e) => onChange(e.target.value), className: `${INPUT_CLASS} resize-none` }) : field.type === "select" ? /* @__PURE__ */ jsxs("select", { ...common, onChange: (e) => onChange(e.target.value), children: [
|
|
4625
5200
|
/* @__PURE__ */ jsx("option", { value: "", children: "\u2014" }),
|
|
4626
|
-
(
|
|
5201
|
+
(field.options ?? []).map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
|
|
4627
5202
|
] }) : /* @__PURE__ */ jsx(
|
|
4628
5203
|
"input",
|
|
4629
5204
|
{
|
|
4630
5205
|
...common,
|
|
4631
|
-
type:
|
|
5206
|
+
type: field.type === "email" ? "email" : field.type === "phone" ? "tel" : "text",
|
|
4632
5207
|
onChange: (e) => onChange(e.target.value)
|
|
4633
5208
|
}
|
|
4634
5209
|
)
|
|
@@ -4675,14 +5250,14 @@ function FormBlock({
|
|
|
4675
5250
|
subtitle && /* @__PURE__ */ jsx("p", { className: "mt-2 text-muted-foreground", children: subtitle })
|
|
4676
5251
|
] }),
|
|
4677
5252
|
status === "success" ? /* @__PURE__ */ jsx("p", { "data-testid": TID.formBlockSuccess, className: "text-center font-medium text-emerald-600", children: successMessage }) : /* @__PURE__ */ jsxs("form", { onSubmit: submit, className: "space-y-4", children: [
|
|
4678
|
-
fields.map((
|
|
5253
|
+
fields.map((field) => /* @__PURE__ */ jsx(
|
|
4679
5254
|
Field,
|
|
4680
5255
|
{
|
|
4681
|
-
field
|
|
4682
|
-
value: values[
|
|
4683
|
-
onChange: (value) => setValues((prev) => ({ ...prev, [
|
|
5256
|
+
field,
|
|
5257
|
+
value: values[field.id] ?? "",
|
|
5258
|
+
onChange: (value) => setValues((prev) => ({ ...prev, [field.id]: value }))
|
|
4684
5259
|
},
|
|
4685
|
-
|
|
5260
|
+
field.id
|
|
4686
5261
|
)),
|
|
4687
5262
|
/* @__PURE__ */ jsx(
|
|
4688
5263
|
"button",
|
|
@@ -4776,9 +5351,9 @@ var formBlockMeta = {
|
|
|
4776
5351
|
// A form is a destination, not merchandising — editorial pages and the home.
|
|
4777
5352
|
enabledOn: ["home", "catalog", "collection", "content"]
|
|
4778
5353
|
};
|
|
4779
|
-
function fieldValue(
|
|
5354
|
+
function fieldValue(field, value) {
|
|
4780
5355
|
if (value === null || value === void 0 || value === "") return null;
|
|
4781
|
-
switch (
|
|
5356
|
+
switch (field.type) {
|
|
4782
5357
|
case "image":
|
|
4783
5358
|
return /* @__PURE__ */ jsx(
|
|
4784
5359
|
"img",
|
|
@@ -4817,12 +5392,12 @@ function EntityCard({ declaration, record, fields }) {
|
|
|
4817
5392
|
children: [
|
|
4818
5393
|
typeof title === "string" && title && /* @__PURE__ */ jsx("h3", { className: "sf-heading mb-2 text-lg font-semibold", children: title }),
|
|
4819
5394
|
/* @__PURE__ */ jsx("dl", { className: "space-y-1.5", children: detailFields.map((name) => {
|
|
4820
|
-
const
|
|
4821
|
-
if (!
|
|
4822
|
-
const rendered = fieldValue(
|
|
5395
|
+
const field = declaration.fields[name];
|
|
5396
|
+
if (!field) return null;
|
|
5397
|
+
const rendered = fieldValue(field, record.data[name]);
|
|
4823
5398
|
if (rendered === null) return null;
|
|
4824
5399
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
4825
|
-
/* @__PURE__ */ jsx("dt", { className: "text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children:
|
|
5400
|
+
/* @__PURE__ */ jsx("dt", { className: "text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: field.label ?? name }),
|
|
4826
5401
|
/* @__PURE__ */ jsx("dd", { className: "text-sm text-foreground/90", children: rendered })
|
|
4827
5402
|
] }, name);
|
|
4828
5403
|
}) })
|
|
@@ -5445,7 +6020,7 @@ function CollectionHero({
|
|
|
5445
6020
|
{
|
|
5446
6021
|
className: `absolute inset-0 flex flex-col justify-center p-6 text-white sm:p-12 ${OVERLAY_CLASS[overlay]} ${centered ? "items-center text-center" : "items-start text-left"}`,
|
|
5447
6022
|
children: /* @__PURE__ */ jsxs(Reveal, { className: centered ? "max-w-3xl" : "max-w-2xl", children: [
|
|
5448
|
-
logos && logos.length > 0 && /* @__PURE__ */ jsx("div", { className: `mb-6 flex items-center gap-5 ${centered ? "justify-center" : ""}`, children: logos.map((logo, i) => /* @__PURE__ */ jsxs(
|
|
6023
|
+
logos && logos.length > 0 && /* @__PURE__ */ jsx("div", { className: `mb-6 flex items-center gap-5 ${centered ? "justify-center" : ""}`, children: logos.map((logo, i) => /* @__PURE__ */ jsxs(React38.Fragment, { children: [
|
|
5449
6024
|
i > 0 && /* @__PURE__ */ jsx("span", { className: "text-2xl font-light opacity-60", "aria-hidden": true, children: "\xD7" }),
|
|
5450
6025
|
/* @__PURE__ */ jsx("img", { src: logo.src, alt: logo.alt, className: "h-10 w-auto object-contain sm:h-14" })
|
|
5451
6026
|
] }, logo.src)) }),
|
|
@@ -5569,7 +6144,7 @@ function ProductSpotlight({
|
|
|
5569
6144
|
loader: "products.bySlug",
|
|
5570
6145
|
params: { slug: productSlug }
|
|
5571
6146
|
});
|
|
5572
|
-
const product = productSlug ? data ?? null : null;
|
|
6147
|
+
const product = useMarketProduct(productSlug ? data ?? null : null);
|
|
5573
6148
|
const target = product ? `/product/${product.slug}` : href;
|
|
5574
6149
|
const art = image ?? product?.images?.[0]?.url ?? bannerPlaceholder(title, hue, hue + 45, 1200, 1200);
|
|
5575
6150
|
const label = cta ?? (productSlug ? "Comprar" : void 0);
|
|
@@ -6198,12 +6773,21 @@ function applyStoreSettings(config, settings) {
|
|
|
6198
6773
|
}
|
|
6199
6774
|
return next;
|
|
6200
6775
|
}
|
|
6776
|
+
function applyBuyer(config, buyer) {
|
|
6777
|
+
if (!buyer) return config;
|
|
6778
|
+
const language = normalizeLanguage(buyer.language) ?? config.language;
|
|
6779
|
+
const hint = buyer.country?.trim().toUpperCase();
|
|
6780
|
+
const countryHint = hint && config.countries.includes(hint) ? hint : config.countryHint;
|
|
6781
|
+
if (language === config.language && countryHint === config.countryHint) return config;
|
|
6782
|
+
return { ...config, language, countryHint };
|
|
6783
|
+
}
|
|
6201
6784
|
function StorefrontConfigHost({
|
|
6202
6785
|
config,
|
|
6786
|
+
buyer,
|
|
6203
6787
|
children
|
|
6204
6788
|
}) {
|
|
6205
|
-
const [policy, setPolicy] =
|
|
6206
|
-
|
|
6789
|
+
const [policy, setPolicy] = React38.useState(null);
|
|
6790
|
+
React38.useEffect(() => {
|
|
6207
6791
|
let cancelled = false;
|
|
6208
6792
|
let provider;
|
|
6209
6793
|
try {
|
|
@@ -6218,12 +6802,56 @@ function StorefrontConfigHost({
|
|
|
6218
6802
|
setShopCarrierQuotesResolver(() => settings?.carrierQuotes);
|
|
6219
6803
|
}).catch(() => {
|
|
6220
6804
|
});
|
|
6805
|
+
if (typeof provider.listMarkets === "function") {
|
|
6806
|
+
void provider.listMarkets().then((markets) => {
|
|
6807
|
+
if (!cancelled) useMarketStore.getState().setMarkets(markets);
|
|
6808
|
+
}).catch(() => {
|
|
6809
|
+
});
|
|
6810
|
+
}
|
|
6221
6811
|
return () => {
|
|
6222
6812
|
cancelled = true;
|
|
6223
6813
|
};
|
|
6224
6814
|
}, [config]);
|
|
6225
|
-
const resolved =
|
|
6226
|
-
|
|
6815
|
+
const resolved = React38.useMemo(
|
|
6816
|
+
() => applyBuyer(applyStoreSettings(config, policy), buyer),
|
|
6817
|
+
[config, policy, buyer?.language, buyer?.country]
|
|
6818
|
+
);
|
|
6819
|
+
return /* @__PURE__ */ jsx(StorefrontConfigProvider, { value: resolved, children: /* @__PURE__ */ jsx(MarketScope, { children }) });
|
|
6820
|
+
}
|
|
6821
|
+
function MarketScope({ children }) {
|
|
6822
|
+
const base = useStorefrontConfig();
|
|
6823
|
+
const { country } = useBuyerCountry();
|
|
6824
|
+
const markets = useMarketStore((s2) => s2.markets);
|
|
6825
|
+
const market = markets.length ? marketForCountry(markets, country) : null;
|
|
6826
|
+
const prices = useMarketStore((s2) => market ? s2.prices[market.code] : void 0);
|
|
6827
|
+
React38.useEffect(() => {
|
|
6828
|
+
useMarketStore.getState().setActive(market);
|
|
6829
|
+
if (!market || market.isDefault || prices) return;
|
|
6830
|
+
let provider;
|
|
6831
|
+
try {
|
|
6832
|
+
provider = base.provider ?? getShopProvider();
|
|
6833
|
+
} catch {
|
|
6834
|
+
return;
|
|
6835
|
+
}
|
|
6836
|
+
void provider.getMarketPrices?.(market.code).then((list) => useMarketStore.getState().setPrices(market.code, list)).catch(() => {
|
|
6837
|
+
});
|
|
6838
|
+
}, [market?.code, prices]);
|
|
6839
|
+
React38.useEffect(() => {
|
|
6840
|
+
if (!market || !market.isDefault && !prices) return;
|
|
6841
|
+
useCartStore.getState().repriceForMarket();
|
|
6842
|
+
}, [market?.code, prices]);
|
|
6843
|
+
const value = React38.useMemo(() => {
|
|
6844
|
+
if (!market) return base;
|
|
6845
|
+
return {
|
|
6846
|
+
...base,
|
|
6847
|
+
market,
|
|
6848
|
+
currency: market.currency,
|
|
6849
|
+
locale: market.locale || base.locale,
|
|
6850
|
+
shipping: market.isDefault ? base.shipping : { flatRate: market.shippingFlatRate, freeAbove: market.shippingFreeAbove ?? void 0 },
|
|
6851
|
+
policy: market.paymentProvider ? { ...base.policy, paymentProvider: market.paymentProvider } : base.policy
|
|
6852
|
+
};
|
|
6853
|
+
}, [base, market]);
|
|
6854
|
+
return /* @__PURE__ */ jsx(StorefrontConfigProvider, { value, children });
|
|
6227
6855
|
}
|
|
6228
6856
|
var RADIUS_MAP = {
|
|
6229
6857
|
none: { button: "0px", card: "0px", input: "0px" },
|
|
@@ -6276,8 +6904,8 @@ function themeToCss(theme, options = {}) {
|
|
|
6276
6904
|
if (theme.font.display) lines.push(`--sf-font-display: '${theme.font.display}', ${fallback};`);
|
|
6277
6905
|
if (theme.font.serif) lines.push(`--sf-font-serif: '${theme.font.serif}', serif;`);
|
|
6278
6906
|
}
|
|
6279
|
-
for (const [
|
|
6280
|
-
for (const [key, value] of Object.entries(theme[
|
|
6907
|
+
for (const [field, prefix] of Object.entries(THEME_SCALE_VAR_PREFIX)) {
|
|
6908
|
+
for (const [key, value] of Object.entries(theme[field] ?? {})) {
|
|
6281
6909
|
lines.push(`${prefix}-${key}: ${value};`);
|
|
6282
6910
|
}
|
|
6283
6911
|
}
|
|
@@ -6342,7 +6970,7 @@ function StorefrontThemeStyle({
|
|
|
6342
6970
|
document.getElementById(linkId)?.remove();
|
|
6343
6971
|
};
|
|
6344
6972
|
}, [fontsHref, linkId, selector]);
|
|
6345
|
-
return
|
|
6973
|
+
return React38.createElement(
|
|
6346
6974
|
"style",
|
|
6347
6975
|
{ "data-sf-theme": theme.name },
|
|
6348
6976
|
themeToCss(theme, { selector })
|
|
@@ -6441,7 +7069,7 @@ function SearchOverlay({ onClose }) {
|
|
|
6441
7069
|
"\u201D."
|
|
6442
7070
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6443
7071
|
/* @__PURE__ */ jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-4", children: suggestions.map(
|
|
6444
|
-
(product) => searchConfig.renderSuggestion ? /* @__PURE__ */ jsx(
|
|
7072
|
+
(product) => searchConfig.renderSuggestion ? /* @__PURE__ */ jsx(React38.Fragment, { children: searchConfig.renderSuggestion(product) }, product.id) : /* @__PURE__ */ jsx(SuggestionCard, { product, onNavigate: onClose }, product.id)
|
|
6445
7073
|
) }),
|
|
6446
7074
|
/* @__PURE__ */ jsx(
|
|
6447
7075
|
"button",
|
|
@@ -6459,7 +7087,8 @@ function SearchOverlay({ onClose }) {
|
|
|
6459
7087
|
}
|
|
6460
7088
|
);
|
|
6461
7089
|
}
|
|
6462
|
-
function SuggestionCard({ product, onNavigate }) {
|
|
7090
|
+
function SuggestionCard({ product: catalogProduct, onNavigate }) {
|
|
7091
|
+
const product = useMarketProduct(catalogProduct);
|
|
6463
7092
|
const image = product.images.find((i) => i.isPrimary) ?? product.images[0];
|
|
6464
7093
|
return /* @__PURE__ */ jsxs(
|
|
6465
7094
|
"button",
|
|
@@ -6647,11 +7276,11 @@ function HeaderActions({ onMenuClick }) {
|
|
|
6647
7276
|
const openDrawer = useCartStore((s2) => s2.openDrawer);
|
|
6648
7277
|
const session = useSessionStore();
|
|
6649
7278
|
const [accountOpen, setAccountOpen] = useState(false);
|
|
6650
|
-
const accountRef =
|
|
7279
|
+
const accountRef = React38.useRef(null);
|
|
6651
7280
|
const pop = usePopOnChange(count);
|
|
6652
7281
|
const firstName = session.name?.split(/\s+/)[0];
|
|
6653
7282
|
const initial2 = (firstName ?? session.email ?? "C").slice(0, 1).toUpperCase();
|
|
6654
|
-
|
|
7283
|
+
React38.useEffect(() => {
|
|
6655
7284
|
if (!accountOpen) return;
|
|
6656
7285
|
const onPointerDown = (event) => {
|
|
6657
7286
|
if (!accountRef.current?.contains(event.target)) setAccountOpen(false);
|
|
@@ -6818,7 +7447,7 @@ function MobileMenuDrawer({ open, onClose }) {
|
|
|
6818
7447
|
navigateTo(config.catalogPath);
|
|
6819
7448
|
onClose();
|
|
6820
7449
|
};
|
|
6821
|
-
|
|
7450
|
+
React38.useEffect(() => {
|
|
6822
7451
|
if (!open) return;
|
|
6823
7452
|
const onKey = (e) => {
|
|
6824
7453
|
if (e.key === "Escape") onClose();
|
|
@@ -7178,6 +7807,7 @@ function CartDrawer() {
|
|
|
7178
7807
|
const FooterExtra = overrideComponent(components.CartDrawerFooterExtra);
|
|
7179
7808
|
const footerExtraProps = overrideProps(components.CartDrawerFooterExtra);
|
|
7180
7809
|
const validate = useDiscountValidator();
|
|
7810
|
+
const t = useT();
|
|
7181
7811
|
const [code, setCode] = useState("");
|
|
7182
7812
|
const [discountError, setDiscountError] = useState(null);
|
|
7183
7813
|
const [applying, setApplying] = useState(false);
|
|
@@ -7205,15 +7835,15 @@ function CartDrawer() {
|
|
|
7205
7835
|
const applied = code.trim().toUpperCase();
|
|
7206
7836
|
cart.applyDiscount(applied, result.percent, { freeShipping: result.freeShipping });
|
|
7207
7837
|
setCode("");
|
|
7208
|
-
const effect = result.freeShipping ? "
|
|
7209
|
-
toast.success("
|
|
7838
|
+
const effect = result.freeShipping ? t("discount.freeShipping") : t("discount.percentOff", { percent: result.percent });
|
|
7839
|
+
toast.success(t("discount.appliedToast"), `${applied} \u2022 ${effect}`);
|
|
7210
7840
|
} else {
|
|
7211
|
-
setDiscountError(result.message ?? "
|
|
7212
|
-
toast.error("
|
|
7841
|
+
setDiscountError(result.message ?? t("discount.invalid"));
|
|
7842
|
+
toast.error(t("discount.invalidToast"), result.message ?? t("discount.checkCode"));
|
|
7213
7843
|
}
|
|
7214
7844
|
} catch (err) {
|
|
7215
|
-
setDiscountError("
|
|
7216
|
-
toast.error("
|
|
7845
|
+
setDiscountError(t("discount.cannotValidate"));
|
|
7846
|
+
toast.error(t("discount.cannotValidateToast"), t("discount.tryLater"));
|
|
7217
7847
|
console.warn("[cart] falha ao validar cupom", err);
|
|
7218
7848
|
} finally {
|
|
7219
7849
|
setApplying(false);
|
|
@@ -7237,25 +7867,25 @@ function CartDrawer() {
|
|
|
7237
7867
|
{
|
|
7238
7868
|
"data-testid": TID.cartDrawer,
|
|
7239
7869
|
role: "dialog",
|
|
7240
|
-
"aria-label": "
|
|
7870
|
+
"aria-label": t("cart.title"),
|
|
7241
7871
|
className: "absolute right-0 top-0 flex h-full w-full max-w-md animate-slide-in-from-right flex-col bg-background shadow-2xl",
|
|
7242
7872
|
children: [
|
|
7243
7873
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b px-5 py-4", children: [
|
|
7244
|
-
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "
|
|
7874
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: t("cart.title") }),
|
|
7245
7875
|
/* @__PURE__ */ jsx(
|
|
7246
7876
|
"button",
|
|
7247
7877
|
{
|
|
7248
7878
|
type: "button",
|
|
7249
|
-
"aria-label": "
|
|
7879
|
+
"aria-label": t("cart.close"),
|
|
7250
7880
|
onClick: cart.closeDrawer,
|
|
7251
7881
|
className: "grid min-h-11 min-w-11 place-items-center rounded-full p-1.5 hover:bg-muted sm:min-h-0 sm:min-w-0",
|
|
7252
7882
|
children: /* @__PURE__ */ jsx(X, { className: "h-5 w-5" })
|
|
7253
7883
|
}
|
|
7254
7884
|
)
|
|
7255
7885
|
] }),
|
|
7256
|
-
cart.lines.length === 0 ? /* @__PURE__ */ jsx("div", { "data-testid": TID.cartEmpty, className: "flex flex-1 items-center justify-center p-8 text-center text-muted-foreground", children: "
|
|
7886
|
+
cart.lines.length === 0 ? /* @__PURE__ */ jsx("div", { "data-testid": TID.cartEmpty, className: "flex flex-1 items-center justify-center p-8 text-center text-muted-foreground", children: t("cart.empty") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7257
7887
|
freeAbove != null && /* @__PURE__ */ jsxs("div", { "data-testid": TID.shippingProgress, className: "border-b bg-muted/40 px-5 py-3", children: [
|
|
7258
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium", children: missingForFree > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7888
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium", children: config.language === "pt-BR" ? missingForFree > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7259
7889
|
"Faltam ",
|
|
7260
7890
|
/* @__PURE__ */ jsx("strong", { children: money(missingForFree) }),
|
|
7261
7891
|
" para frete gr\xE1tis \u{1F69A}"
|
|
@@ -7263,7 +7893,14 @@ function CartDrawer() {
|
|
|
7263
7893
|
"\u{1F389} Voc\xEA ganhou ",
|
|
7264
7894
|
/* @__PURE__ */ jsx("strong", { children: "frete gr\xE1tis" }),
|
|
7265
7895
|
"!"
|
|
7266
|
-
] })
|
|
7896
|
+
] }) : missingForFree > 0 ? (() => {
|
|
7897
|
+
const [before, after] = t("cart.missingForFree").split("{{amount}}");
|
|
7898
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7899
|
+
before,
|
|
7900
|
+
/* @__PURE__ */ jsx("strong", { children: money(missingForFree) }),
|
|
7901
|
+
after
|
|
7902
|
+
] });
|
|
7903
|
+
})() : /* @__PURE__ */ jsx("strong", { children: t("cart.wonFree") }) }),
|
|
7267
7904
|
/* @__PURE__ */ jsx("div", { className: "mt-2 h-1.5 overflow-hidden rounded-full bg-border", children: /* @__PURE__ */ jsx(
|
|
7268
7905
|
"div",
|
|
7269
7906
|
{
|
|
@@ -7297,7 +7934,7 @@ function CartDrawer() {
|
|
|
7297
7934
|
{
|
|
7298
7935
|
type: "button",
|
|
7299
7936
|
"data-testid": TID.lineRemove,
|
|
7300
|
-
"aria-label":
|
|
7937
|
+
"aria-label": t("cart.remove", { name: line.name }),
|
|
7301
7938
|
onClick: () => cart.removeItem(line.lineId ?? line.productId),
|
|
7302
7939
|
className: "-m-1.5 grid min-h-11 min-w-11 place-items-center p-1.5 text-muted-foreground hover:text-destructive sm:min-h-0 sm:min-w-0",
|
|
7303
7940
|
children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
|
|
@@ -7354,7 +7991,7 @@ function CartDrawer() {
|
|
|
7354
7991
|
{
|
|
7355
7992
|
"data-testid": TID.discountInput,
|
|
7356
7993
|
type: "text",
|
|
7357
|
-
placeholder: "
|
|
7994
|
+
placeholder: t("discount.placeholder"),
|
|
7358
7995
|
value: code,
|
|
7359
7996
|
onChange: (e) => setCode(e.target.value),
|
|
7360
7997
|
className: "flex-1 rounded-lg border bg-background px-3 py-2 text-sm uppercase"
|
|
@@ -7368,7 +8005,7 @@ function CartDrawer() {
|
|
|
7368
8005
|
onClick: applyCode,
|
|
7369
8006
|
disabled: applying || !code.trim(),
|
|
7370
8007
|
className: "rounded-lg border px-3 py-2 text-sm font-medium hover:bg-muted disabled:opacity-50",
|
|
7371
|
-
children: "
|
|
8008
|
+
children: t("discount.apply")
|
|
7372
8009
|
}
|
|
7373
8010
|
)
|
|
7374
8011
|
] }),
|
|
@@ -7378,12 +8015,12 @@ function CartDrawer() {
|
|
|
7378
8015
|
selectRequiresShipping(cart) && /* @__PURE__ */ jsx("div", { className: "mb-3", children: /* @__PURE__ */ jsx(DeliveryEstimator, { compact: true }) }),
|
|
7379
8016
|
/* @__PURE__ */ jsxs("dl", { className: "space-y-1.5 text-sm", children: [
|
|
7380
8017
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
7381
|
-
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: "
|
|
8018
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: t("summary.subtotal") }),
|
|
7382
8019
|
/* @__PURE__ */ jsx("dd", { "data-testid": TID.cartSubtotal, "data-price": subtotal.toFixed(2), children: money(subtotal) })
|
|
7383
8020
|
] }),
|
|
7384
8021
|
discountTotal > 0 && /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-emerald-700", "data-testid": TID.discountRow, children: [
|
|
7385
8022
|
/* @__PURE__ */ jsxs("dt", { children: [
|
|
7386
|
-
"
|
|
8023
|
+
t("summary.discount"),
|
|
7387
8024
|
" ",
|
|
7388
8025
|
/* @__PURE__ */ jsxs(
|
|
7389
8026
|
"button",
|
|
@@ -7406,10 +8043,10 @@ function CartDrawer() {
|
|
|
7406
8043
|
] }),
|
|
7407
8044
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
7408
8045
|
/* @__PURE__ */ jsxs("dt", { className: cart.discountFreeShipping ? "text-emerald-700" : "text-muted-foreground", children: [
|
|
7409
|
-
"
|
|
8046
|
+
t("summary.shipping"),
|
|
7410
8047
|
delivery.status === "served" && delivery.postalCode && /* @__PURE__ */ jsxs("span", { className: "ml-1 text-xs", children: [
|
|
7411
8048
|
"\xB7 ",
|
|
7412
|
-
formatPostalCode(delivery.postalCode)
|
|
8049
|
+
formatPostalCode(delivery.postalCode, delivery.country)
|
|
7413
8050
|
] }),
|
|
7414
8051
|
cart.discountFreeShipping && /* @__PURE__ */ jsxs(
|
|
7415
8052
|
"button",
|
|
@@ -7425,10 +8062,10 @@ function CartDrawer() {
|
|
|
7425
8062
|
}
|
|
7426
8063
|
)
|
|
7427
8064
|
] }),
|
|
7428
|
-
/* @__PURE__ */ jsx("dd", { "data-testid": TID.cartShipping, "data-price": shipping.toFixed(2), children: shipping === 0 ? "
|
|
8065
|
+
/* @__PURE__ */ jsx("dd", { "data-testid": TID.cartShipping, "data-price": shipping.toFixed(2), children: shipping === 0 ? t("summary.free") : money(shipping) })
|
|
7429
8066
|
] }),
|
|
7430
8067
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between border-t pt-2 text-base font-semibold", children: [
|
|
7431
|
-
/* @__PURE__ */ jsx("dt", { children: "
|
|
8068
|
+
/* @__PURE__ */ jsx("dt", { children: t("summary.total") }),
|
|
7432
8069
|
/* @__PURE__ */ jsx("dd", { "data-testid": TID.cartTotal, "data-price": total.toFixed(2), children: money(total) })
|
|
7433
8070
|
] })
|
|
7434
8071
|
] }),
|
|
@@ -7443,7 +8080,7 @@ function CartDrawer() {
|
|
|
7443
8080
|
},
|
|
7444
8081
|
className: "sf-cta w-full bg-primary py-3.5 font-semibold text-primary-foreground shadow-md transition-all hover:-translate-y-0.5 hover:shadow-lg",
|
|
7445
8082
|
style: { borderRadius: "var(--sf-radius-button)" },
|
|
7446
|
-
children: "
|
|
8083
|
+
children: t("cart.checkout")
|
|
7447
8084
|
}
|
|
7448
8085
|
),
|
|
7449
8086
|
/* @__PURE__ */ jsx(Slot, { area: "cart", name: "afterSummary", context: cartSlotContext }),
|
|
@@ -7620,7 +8257,7 @@ async function placeStorefrontOrder({
|
|
|
7620
8257
|
customerId: customerId ?? void 0
|
|
7621
8258
|
});
|
|
7622
8259
|
if (replaced) return { order: replaced, customerId: customerId ?? replaced.customerId ?? "" };
|
|
7623
|
-
const
|
|
8260
|
+
const contributed = await collectOrderMetadata({
|
|
7624
8261
|
items: cart.lines.map((line) => ({
|
|
7625
8262
|
productId: line.productId,
|
|
7626
8263
|
quantity: line.quantity,
|
|
@@ -7629,6 +8266,7 @@ async function placeStorefrontOrder({
|
|
|
7629
8266
|
subtotal: cart.lines.reduce((sum, line) => sum + line.unitPrice * line.quantity, 0),
|
|
7630
8267
|
customerEmail: email
|
|
7631
8268
|
});
|
|
8269
|
+
const metadata = config.market ? { ...contributed ?? {}, market: config.market.code } : contributed;
|
|
7632
8270
|
const place = (withCustomerId) => provider.placeOrder({
|
|
7633
8271
|
customerId: withCustomerId,
|
|
7634
8272
|
customer: { name, email },
|
|
@@ -7696,6 +8334,181 @@ function useMyOrders() {
|
|
|
7696
8334
|
}, [customerId, email, tick]);
|
|
7697
8335
|
return { orders, loading, refresh };
|
|
7698
8336
|
}
|
|
8337
|
+
function Skeleton({ className = "", style }) {
|
|
8338
|
+
return /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `block rounded bg-muted ${className}`, style });
|
|
8339
|
+
}
|
|
8340
|
+
function SkeletonGroup({ label, className = "", children, ...rest }) {
|
|
8341
|
+
return /* @__PURE__ */ jsxs(
|
|
8342
|
+
"div",
|
|
8343
|
+
{
|
|
8344
|
+
role: "status",
|
|
8345
|
+
"aria-busy": "true",
|
|
8346
|
+
className: `animate-pulse motion-reduce:animate-none ${className}`,
|
|
8347
|
+
...rest,
|
|
8348
|
+
children: [
|
|
8349
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: label }),
|
|
8350
|
+
children
|
|
8351
|
+
]
|
|
8352
|
+
}
|
|
8353
|
+
);
|
|
8354
|
+
}
|
|
8355
|
+
function PulseDot({ className = "" }) {
|
|
8356
|
+
return /* @__PURE__ */ jsxs("span", { "aria-hidden": true, className: `relative flex h-2.5 w-2.5 shrink-0 ${className}`, children: [
|
|
8357
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inset-0 animate-ping rounded-full bg-current opacity-60 motion-reduce:animate-none" }),
|
|
8358
|
+
/* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2.5 w-2.5 rounded-full bg-current" })
|
|
8359
|
+
] });
|
|
8360
|
+
}
|
|
8361
|
+
function checkoutField(label, testId, value, onChange, props) {
|
|
8362
|
+
return /* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
8363
|
+
/* @__PURE__ */ jsx("span", { className: "mb-1.5 block text-xs font-medium text-muted-foreground", children: label }),
|
|
8364
|
+
/* @__PURE__ */ jsx(
|
|
8365
|
+
"input",
|
|
8366
|
+
{
|
|
8367
|
+
"data-testid": testId,
|
|
8368
|
+
"aria-label": label,
|
|
8369
|
+
value,
|
|
8370
|
+
onChange: (event) => onChange(event.target.value),
|
|
8371
|
+
className: "w-full rounded-lg border bg-background px-3.5 py-3 text-sm outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/10",
|
|
8372
|
+
...props
|
|
8373
|
+
}
|
|
8374
|
+
)
|
|
8375
|
+
] });
|
|
8376
|
+
}
|
|
8377
|
+
function checkoutSelect(label, testId, value, onChange, options, placeholder, props) {
|
|
8378
|
+
return /* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
8379
|
+
/* @__PURE__ */ jsx("span", { className: "mb-1.5 block text-xs font-medium text-muted-foreground", children: label }),
|
|
8380
|
+
/* @__PURE__ */ jsxs(
|
|
8381
|
+
"select",
|
|
8382
|
+
{
|
|
8383
|
+
"data-testid": testId,
|
|
8384
|
+
"aria-label": label,
|
|
8385
|
+
value,
|
|
8386
|
+
onChange: (event) => onChange(event.target.value),
|
|
8387
|
+
className: "w-full rounded-lg border bg-background px-3.5 py-3 text-sm outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/10",
|
|
8388
|
+
...props,
|
|
8389
|
+
children: [
|
|
8390
|
+
/* @__PURE__ */ jsx("option", { value: "", children: placeholder }),
|
|
8391
|
+
options.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
|
|
8392
|
+
]
|
|
8393
|
+
}
|
|
8394
|
+
)
|
|
8395
|
+
] });
|
|
8396
|
+
}
|
|
8397
|
+
var DRAFT_KEY = {
|
|
8398
|
+
postalCode: "zip",
|
|
8399
|
+
street: "street",
|
|
8400
|
+
number: "number",
|
|
8401
|
+
complement: "complement",
|
|
8402
|
+
district: "district",
|
|
8403
|
+
city: "city",
|
|
8404
|
+
region: "state"
|
|
8405
|
+
};
|
|
8406
|
+
var TEST_ID = {
|
|
8407
|
+
postalCode: TID.checkoutZip,
|
|
8408
|
+
street: TID.checkoutStreet,
|
|
8409
|
+
number: "checkout-number",
|
|
8410
|
+
complement: "checkout-complement",
|
|
8411
|
+
district: "checkout-district",
|
|
8412
|
+
city: TID.checkoutCity,
|
|
8413
|
+
region: "checkout-state"
|
|
8414
|
+
};
|
|
8415
|
+
function AddressForm({ country, language, value, onChange, onPostalCode, lookup, complement }) {
|
|
8416
|
+
const t = useT();
|
|
8417
|
+
const schema = getCountrySchema(country);
|
|
8418
|
+
const specs = new Map(schema.fields.map((spec) => [spec.key, spec]));
|
|
8419
|
+
const showComplement = complement?.visible !== false;
|
|
8420
|
+
const requireComplement = complement?.required === true;
|
|
8421
|
+
function input(spec) {
|
|
8422
|
+
const key = DRAFT_KEY[spec.key];
|
|
8423
|
+
const label = spec.label[language];
|
|
8424
|
+
const required = spec.required || spec.key === "complement" && requireComplement;
|
|
8425
|
+
const basePlaceholder = spec.placeholder?.[language] ?? label;
|
|
8426
|
+
const placeholder = required ? basePlaceholder : t("checkout.address.optional", { label: basePlaceholder });
|
|
8427
|
+
if (spec.key === "postalCode") {
|
|
8428
|
+
return checkoutField(label, TEST_ID.postalCode, value.zip, onPostalCode, {
|
|
8429
|
+
placeholder,
|
|
8430
|
+
inputMode: schema.postal.inputMode,
|
|
8431
|
+
autoComplete: "postal-code"
|
|
8432
|
+
});
|
|
8433
|
+
}
|
|
8434
|
+
if (spec.key === "region" && schema.region.input === "select" && schema.regions) {
|
|
8435
|
+
return checkoutSelect(
|
|
8436
|
+
label,
|
|
8437
|
+
TEST_ID.region,
|
|
8438
|
+
value.state,
|
|
8439
|
+
(next) => onChange("state", next),
|
|
8440
|
+
schema.regions.map((region) => ({
|
|
8441
|
+
value: schema.region.stores === "code" ? region.code : region.name,
|
|
8442
|
+
label: region.name
|
|
8443
|
+
})),
|
|
8444
|
+
t("checkout.address.choose"),
|
|
8445
|
+
{ autoComplete: spec.autoComplete }
|
|
8446
|
+
);
|
|
8447
|
+
}
|
|
8448
|
+
return checkoutField(label, TEST_ID[spec.key], value[key], (next) => onChange(key, next), {
|
|
8449
|
+
placeholder,
|
|
8450
|
+
...spec.autoComplete ? { autoComplete: spec.autoComplete } : {}
|
|
8451
|
+
});
|
|
8452
|
+
}
|
|
8453
|
+
function postalHint() {
|
|
8454
|
+
if (lookup === "loading") {
|
|
8455
|
+
return /* @__PURE__ */ jsxs(SkeletonGroup, { label: t("checkout.address.lookingUp"), className: "grid gap-1.5 px-1", children: [
|
|
8456
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-2.5 w-40" }),
|
|
8457
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-2.5 w-24" })
|
|
8458
|
+
] });
|
|
8459
|
+
}
|
|
8460
|
+
if (schema.postal.lookup === "viacep") {
|
|
8461
|
+
return /* @__PURE__ */ jsx("p", { className: "px-1 text-xs text-muted-foreground", children: lookup === "not-found" ? t("checkout.address.notFound") : t("checkout.address.filled") });
|
|
8462
|
+
}
|
|
8463
|
+
if (schema.postal.lookup === "prefix" && lookup === "found") {
|
|
8464
|
+
return /* @__PURE__ */ jsx("p", { className: "px-1 text-xs text-muted-foreground", children: t("checkout.address.regionFromPostal") });
|
|
8465
|
+
}
|
|
8466
|
+
return null;
|
|
8467
|
+
}
|
|
8468
|
+
return /* @__PURE__ */ jsx("div", { className: "grid gap-3", children: schema.rows.map((row) => {
|
|
8469
|
+
const cells = row.filter((key) => specs.has(key) && (key !== "complement" || showComplement));
|
|
8470
|
+
if (cells.length === 0) return null;
|
|
8471
|
+
if (cells.length === 1 && cells[0] === "postalCode") {
|
|
8472
|
+
return /* @__PURE__ */ jsxs("div", { className: "grid gap-1 sm:grid-cols-[200px_1fr] sm:items-center", children: [
|
|
8473
|
+
input(specs.get("postalCode")),
|
|
8474
|
+
postalHint()
|
|
8475
|
+
] }, "postalCode");
|
|
8476
|
+
}
|
|
8477
|
+
if (row.length === 1) return /* @__PURE__ */ jsx(React38.Fragment, { children: input(specs.get(cells[0])) }, cells[0]);
|
|
8478
|
+
return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: cells.map((key) => /* @__PURE__ */ jsx(React38.Fragment, { children: input(specs.get(key)) }, key)) }, cells.join("-"));
|
|
8479
|
+
}) });
|
|
8480
|
+
}
|
|
8481
|
+
function flag(iso2) {
|
|
8482
|
+
return iso2.toUpperCase().replace(/[^A-Z]/g, "").split("").map((c) => String.fromCodePoint(127462 + c.charCodeAt(0) - 65)).join("");
|
|
8483
|
+
}
|
|
8484
|
+
function CountrySelect({ country, allowed, onChange, className }) {
|
|
8485
|
+
const t = useT();
|
|
8486
|
+
const config = useStorefrontConfig();
|
|
8487
|
+
return /* @__PURE__ */ jsxs("label", { className: `flex items-center gap-2 text-sm ${className ?? ""}`, children: [
|
|
8488
|
+
/* @__PURE__ */ jsx(MapPin, { className: "h-4 w-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
8489
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: t("country.deliverTo") }),
|
|
8490
|
+
/* @__PURE__ */ jsx(
|
|
8491
|
+
"select",
|
|
8492
|
+
{
|
|
8493
|
+
"data-testid": "deliver-to-country",
|
|
8494
|
+
"aria-label": t("country.label"),
|
|
8495
|
+
value: country,
|
|
8496
|
+
onChange: (event) => onChange(event.target.value),
|
|
8497
|
+
className: "rounded-lg border bg-background px-2.5 py-1.5 text-sm font-medium outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/10",
|
|
8498
|
+
children: allowed.map((iso2) => /* @__PURE__ */ jsxs("option", { value: iso2, children: [
|
|
8499
|
+
flag(iso2),
|
|
8500
|
+
" ",
|
|
8501
|
+
countryName(iso2, config.language)
|
|
8502
|
+
] }, iso2))
|
|
8503
|
+
}
|
|
8504
|
+
)
|
|
8505
|
+
] });
|
|
8506
|
+
}
|
|
8507
|
+
function DeliverToPicker({ className }) {
|
|
8508
|
+
const buyer = useBuyerCountry();
|
|
8509
|
+
if (buyer.allowed.length < 2) return null;
|
|
8510
|
+
return /* @__PURE__ */ jsx(CountrySelect, { className, country: buyer.country, allowed: buyer.allowed, onChange: buyer.setCountry });
|
|
8511
|
+
}
|
|
7699
8512
|
|
|
7700
8513
|
// src/app/return-path.ts
|
|
7701
8514
|
var KEY2 = "fayz:sf:return-path";
|
|
@@ -7827,14 +8640,15 @@ function SignInModal({ defaultEmail = "", onClose, onSignedIn }) {
|
|
|
7827
8640
|
);
|
|
7828
8641
|
}
|
|
7829
8642
|
var LABELS2 = {
|
|
7830
|
-
1: "
|
|
7831
|
-
2: "
|
|
7832
|
-
3: "
|
|
7833
|
-
4: "
|
|
8643
|
+
1: "checkout.steps.1",
|
|
8644
|
+
2: "checkout.steps.2",
|
|
8645
|
+
3: "checkout.steps.3",
|
|
8646
|
+
4: "checkout.steps.4"
|
|
7834
8647
|
};
|
|
7835
8648
|
function CheckoutSteps({ current, onGoBackTo, omit }) {
|
|
8649
|
+
const t = useT();
|
|
7836
8650
|
const steps = [1, 2, 3, 4].filter((s2) => !omit?.includes(s2));
|
|
7837
|
-
return /* @__PURE__ */ jsxs("nav", { "data-testid": TID.checkoutSteps, "aria-label": "
|
|
8651
|
+
return /* @__PURE__ */ jsxs("nav", { "data-testid": TID.checkoutSteps, "aria-label": t("checkout.steps.label"), className: "mb-8", children: [
|
|
7838
8652
|
/* @__PURE__ */ jsx("ol", { className: "flex items-center gap-1.5 sm:gap-2", children: steps.map((step, index) => {
|
|
7839
8653
|
const done = step < current;
|
|
7840
8654
|
const active2 = step === current;
|
|
@@ -7874,7 +8688,7 @@ function CheckoutSteps({ current, onGoBackTo, omit }) {
|
|
|
7874
8688
|
children: done ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) : index + 1
|
|
7875
8689
|
}
|
|
7876
8690
|
),
|
|
7877
|
-
/* @__PURE__ */ jsx("span", { className: `hidden truncate text-sm sm:inline ${active2 ? "font-semibold" : ""}`, children: LABELS2[step] })
|
|
8691
|
+
/* @__PURE__ */ jsx("span", { className: `hidden truncate text-sm sm:inline ${active2 ? "font-semibold" : ""}`, children: t(LABELS2[step]) })
|
|
7878
8692
|
]
|
|
7879
8693
|
}
|
|
7880
8694
|
),
|
|
@@ -7888,34 +8702,10 @@ function CheckoutSteps({ current, onGoBackTo, omit }) {
|
|
|
7888
8702
|
/* @__PURE__ */ jsxs("p", { className: "mt-2 text-sm font-semibold sm:hidden", children: [
|
|
7889
8703
|
steps.indexOf(current) + 1,
|
|
7890
8704
|
". ",
|
|
7891
|
-
LABELS2[current]
|
|
8705
|
+
t(LABELS2[current])
|
|
7892
8706
|
] })
|
|
7893
8707
|
] });
|
|
7894
8708
|
}
|
|
7895
|
-
function Skeleton({ className = "", style }) {
|
|
7896
|
-
return /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `block rounded bg-muted ${className}`, style });
|
|
7897
|
-
}
|
|
7898
|
-
function SkeletonGroup({ label, className = "", children, ...rest }) {
|
|
7899
|
-
return /* @__PURE__ */ jsxs(
|
|
7900
|
-
"div",
|
|
7901
|
-
{
|
|
7902
|
-
role: "status",
|
|
7903
|
-
"aria-busy": "true",
|
|
7904
|
-
className: `animate-pulse motion-reduce:animate-none ${className}`,
|
|
7905
|
-
...rest,
|
|
7906
|
-
children: [
|
|
7907
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children: label }),
|
|
7908
|
-
children
|
|
7909
|
-
]
|
|
7910
|
-
}
|
|
7911
|
-
);
|
|
7912
|
-
}
|
|
7913
|
-
function PulseDot({ className = "" }) {
|
|
7914
|
-
return /* @__PURE__ */ jsxs("span", { "aria-hidden": true, className: `relative flex h-2.5 w-2.5 shrink-0 ${className}`, children: [
|
|
7915
|
-
/* @__PURE__ */ jsx("span", { className: "absolute inset-0 animate-ping rounded-full bg-current opacity-60 motion-reduce:animate-none" }),
|
|
7916
|
-
/* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2.5 w-2.5 rounded-full bg-current" })
|
|
7917
|
-
] });
|
|
7918
|
-
}
|
|
7919
8709
|
var SDK_URL = "https://sdk.mercadopago.com/js/v2";
|
|
7920
8710
|
var CONTAINER_ID = "fayz-mp-card-brick";
|
|
7921
8711
|
var DEVICE_SCRIPT_URL = "https://www.mercadopago.com/v2/security.js";
|
|
@@ -8041,13 +8831,13 @@ function CardBrick({ publicKey, amount, email, onSubmit, onError }) {
|
|
|
8041
8831
|
var POLL_MS = 3e3;
|
|
8042
8832
|
var RESUME_KEY = "fz.checkout.resume";
|
|
8043
8833
|
function useExpiry(expiresAt) {
|
|
8044
|
-
const target =
|
|
8834
|
+
const target = React38.useMemo(() => {
|
|
8045
8835
|
if (!expiresAt) return null;
|
|
8046
8836
|
const t = new Date(expiresAt).getTime();
|
|
8047
8837
|
return Number.isFinite(t) ? t : null;
|
|
8048
8838
|
}, [expiresAt]);
|
|
8049
|
-
const [now, setNow] =
|
|
8050
|
-
|
|
8839
|
+
const [now, setNow] = React38.useState(() => Date.now());
|
|
8840
|
+
React38.useEffect(() => {
|
|
8051
8841
|
if (target === null) return;
|
|
8052
8842
|
const id = setInterval(() => setNow(Date.now()), 1e3);
|
|
8053
8843
|
return () => clearInterval(id);
|
|
@@ -8580,30 +9370,49 @@ function pickLastAddress(orders) {
|
|
|
8580
9370
|
}
|
|
8581
9371
|
return null;
|
|
8582
9372
|
}
|
|
9373
|
+
function toShippingAddress(form, country) {
|
|
9374
|
+
const schema = getCountrySchema(country);
|
|
9375
|
+
const isBrazil = schema.iso2 === "BR";
|
|
9376
|
+
const has = (key) => schema.fields.some((f2) => f2.key === key);
|
|
9377
|
+
return {
|
|
9378
|
+
postalCode: isBrazil ? form.zip.trim() : normalizePostalCode(form.zip, country),
|
|
9379
|
+
street: form.street.trim(),
|
|
9380
|
+
number: has("number") ? form.number.trim() || void 0 : void 0,
|
|
9381
|
+
complement: form.complement.trim() || void 0,
|
|
9382
|
+
district: has("district") ? form.district.trim() || void 0 : void 0,
|
|
9383
|
+
city: form.city.trim(),
|
|
9384
|
+
// A UF is a code and is upper-cased; a province is a name and keeps its case.
|
|
9385
|
+
state: schema.region.stores === "code" ? form.state.trim().toUpperCase() : form.state.trim(),
|
|
9386
|
+
country: schema.iso2,
|
|
9387
|
+
phone: form.phone.trim() || void 0,
|
|
9388
|
+
document: (isBrazil ? documentDigits(form.document) : form.document.trim().toUpperCase()) || void 0
|
|
9389
|
+
};
|
|
9390
|
+
}
|
|
8583
9391
|
var PAYMENT_LABELS = {
|
|
8584
|
-
pix: { label: "
|
|
9392
|
+
pix: { label: "payment.pix.label", hint: "payment.pix.hint" },
|
|
8585
9393
|
// O cartão tem DOIS significados agora, e o texto muda com a loja: sem
|
|
8586
9394
|
// adquirente é a maquininha do entregador; com adquirente é a página segura
|
|
8587
|
-
// dele
|
|
8588
|
-
//
|
|
8589
|
-
credit_card: { label: "
|
|
8590
|
-
debit_card: { label: "
|
|
8591
|
-
boleto: { label: "
|
|
8592
|
-
cash: { label: "
|
|
8593
|
-
other: { label: "
|
|
9395
|
+
// dele — prometer "maquininha" para quem vai ser redirecionado é a loja
|
|
9396
|
+
// mentindo sobre a própria entrega.
|
|
9397
|
+
credit_card: { label: "payment.credit_card.label", hint: "payment.credit_card.hint" },
|
|
9398
|
+
debit_card: { label: "payment.debit_card.label", hint: "payment.debit_card.hint" },
|
|
9399
|
+
boleto: { label: "payment.boleto.label", hint: "payment.boleto.hint" },
|
|
9400
|
+
cash: { label: "payment.cash.label", hint: "payment.cash.hint" },
|
|
9401
|
+
other: { label: "payment.other.label", hint: "payment.other.hint" }
|
|
8594
9402
|
};
|
|
8595
|
-
|
|
9403
|
+
var BRAZIL_ONLY = ["pix", "boleto"];
|
|
9404
|
+
function placeOrderMessage(err, t) {
|
|
8596
9405
|
const message = errorMessage5(err);
|
|
8597
9406
|
if (/customer (email mismatch|does not belong|belongs to another)/i.test(message)) {
|
|
8598
|
-
return "
|
|
9407
|
+
return t("error.sessionMismatch");
|
|
8599
9408
|
}
|
|
8600
9409
|
if (/out of stock|insufficient|estoque/i.test(message)) {
|
|
8601
|
-
return "
|
|
9410
|
+
return t("error.outOfStock");
|
|
8602
9411
|
}
|
|
8603
9412
|
if (/delivery not available|postal code/i.test(message)) {
|
|
8604
|
-
return "
|
|
9413
|
+
return t("error.unserved");
|
|
8605
9414
|
}
|
|
8606
|
-
return message.replace(/^shop_[a-z_]+:\s*/i, "") || "
|
|
9415
|
+
return message.replace(/^shop_[a-z_]+:\s*/i, "") || t("error.placeOrder");
|
|
8607
9416
|
}
|
|
8608
9417
|
var DEV_BUILD = (() => {
|
|
8609
9418
|
try {
|
|
@@ -8612,36 +9421,28 @@ var DEV_BUILD = (() => {
|
|
|
8612
9421
|
return false;
|
|
8613
9422
|
}
|
|
8614
9423
|
})();
|
|
8615
|
-
function field(label, testId, value, onChange, props) {
|
|
8616
|
-
return /* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
8617
|
-
/* @__PURE__ */ jsx("span", { className: "mb-1.5 block text-xs font-medium text-muted-foreground", children: label }),
|
|
8618
|
-
/* @__PURE__ */ jsx(
|
|
8619
|
-
"input",
|
|
8620
|
-
{
|
|
8621
|
-
"data-testid": testId,
|
|
8622
|
-
"aria-label": label,
|
|
8623
|
-
value,
|
|
8624
|
-
onChange: (event) => onChange(event.target.value),
|
|
8625
|
-
className: "w-full rounded-lg border bg-background px-3.5 py-3 text-sm outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/10",
|
|
8626
|
-
...props
|
|
8627
|
-
}
|
|
8628
|
-
)
|
|
8629
|
-
] });
|
|
8630
|
-
}
|
|
8631
9424
|
function CheckoutPage() {
|
|
8632
9425
|
const config = useStorefrontConfig();
|
|
8633
9426
|
const cart = useCartStore();
|
|
8634
9427
|
const session = useSessionStore();
|
|
8635
9428
|
const delivery = useDeliveryStore();
|
|
8636
9429
|
const validateDiscount2 = useDiscountValidator();
|
|
8637
|
-
|
|
8638
|
-
|
|
9430
|
+
const t = useT();
|
|
9431
|
+
useStorefrontHead({ title: t("checkout.title", { store: config.name }) });
|
|
9432
|
+
const buyer = useBuyerCountry();
|
|
9433
|
+
const country = buyer.country;
|
|
9434
|
+
const isBrazil = country === "BR";
|
|
9435
|
+
const countrySchema = getCountrySchema(country);
|
|
9436
|
+
const paymentMethods = isBrazil ? config.payments.methods : config.payments.methods.filter((method) => !BRAZIL_ONLY.includes(method));
|
|
8639
9437
|
const policy = config.policy;
|
|
8640
9438
|
const requiresAccount = policy?.guestCheckout === false;
|
|
8641
9439
|
const fieldPolicy = policy?.checkoutFields ?? {};
|
|
8642
9440
|
const gatewayCheckout = config.payments.mode === "gateway" || !!policy?.paymentProvider;
|
|
8643
|
-
const shows = (key) => key === "document" ? gatewayCheckout || fieldPolicy.document?.visible === true : fieldPolicy[key]?.visible !== false;
|
|
8644
|
-
const requires = (key) =>
|
|
9441
|
+
const shows = (key) => key === "document" ? isBrazil && gatewayCheckout || fieldPolicy.document?.visible === true : fieldPolicy[key]?.visible !== false;
|
|
9442
|
+
const requires = (key) => (
|
|
9443
|
+
// A CPF is Brazil's; elsewhere the tax id is the buyer's to give or not.
|
|
9444
|
+
key === "document" && !isBrazil ? countrySchema.taxId?.required === "always" : key === "document" || key === "phone" ? gatewayCheckout || fieldPolicy[key]?.visible === true && fieldPolicy[key]?.required === true : fieldPolicy[key]?.visible !== false && fieldPolicy[key]?.required === true
|
|
9445
|
+
);
|
|
8645
9446
|
const [selectedAddressId, setSelectedAddressId] = useState("new");
|
|
8646
9447
|
const [savedAddresses, setSavedAddresses] = useState([]);
|
|
8647
9448
|
const [addressesLoading, setAddressesLoading] = useState(false);
|
|
@@ -8660,6 +9461,9 @@ function CheckoutPage() {
|
|
|
8660
9461
|
const [paymentMethod, setPaymentMethod] = useState(
|
|
8661
9462
|
resume ? "credit_card" : paymentMethods[0] ?? "pix"
|
|
8662
9463
|
);
|
|
9464
|
+
useEffect(() => {
|
|
9465
|
+
if (!paymentMethods.includes(paymentMethod) && paymentMethods[0]) setPaymentMethod(paymentMethods[0]);
|
|
9466
|
+
}, [paymentMethods, paymentMethod]);
|
|
8663
9467
|
const known = useKnownCustomer();
|
|
8664
9468
|
const [form, setForm] = useState({
|
|
8665
9469
|
email: session.email ?? "",
|
|
@@ -8674,7 +9478,7 @@ function CheckoutPage() {
|
|
|
8674
9478
|
district: "",
|
|
8675
9479
|
state: ""
|
|
8676
9480
|
});
|
|
8677
|
-
|
|
9481
|
+
React38.useEffect(() => {
|
|
8678
9482
|
if (!known.ready) return;
|
|
8679
9483
|
setForm((current) => ({
|
|
8680
9484
|
...current,
|
|
@@ -8718,7 +9522,7 @@ function CheckoutPage() {
|
|
|
8718
9522
|
const [applyingDiscount, setApplyingDiscount] = useState(false);
|
|
8719
9523
|
const [showSignin, setShowSignin] = useState(false);
|
|
8720
9524
|
const [placing, setPlacing] = useState(false);
|
|
8721
|
-
const leaving =
|
|
9525
|
+
const leaving = React38.useRef(false);
|
|
8722
9526
|
const [zipLookup, setZipLookup] = useState("idle");
|
|
8723
9527
|
const subtotal = selectSubtotal(cart);
|
|
8724
9528
|
const discountTotal = selectDiscountTotal(cart);
|
|
@@ -8726,7 +9530,7 @@ function CheckoutPage() {
|
|
|
8726
9530
|
const shipping = isPickup ? 0 : shippingRaw;
|
|
8727
9531
|
const total = selectTotal(cart, config) - (isPickup ? shippingRaw : 0);
|
|
8728
9532
|
const checkoutSlotContext = { subtotal, total };
|
|
8729
|
-
const checkoutSessionInput =
|
|
9533
|
+
const checkoutSessionInput = React38.useMemo(() => ({
|
|
8730
9534
|
items: cart.lines.map((line) => ({
|
|
8731
9535
|
productId: line.productId,
|
|
8732
9536
|
variantId: line.variantId ?? null,
|
|
@@ -8753,27 +9557,25 @@ function CheckoutPage() {
|
|
|
8753
9557
|
document: documentDigits(form.document) || void 0,
|
|
8754
9558
|
phone: form.phone.trim() || void 0
|
|
8755
9559
|
},
|
|
8756
|
-
shippingAddress:
|
|
8757
|
-
postalCode: form.zip.trim(),
|
|
8758
|
-
street: form.street.trim(),
|
|
8759
|
-
number: form.number.trim() || void 0,
|
|
8760
|
-
complement: form.complement.trim() || void 0,
|
|
8761
|
-
district: form.district.trim() || void 0,
|
|
8762
|
-
city: form.city.trim(),
|
|
8763
|
-
state: form.state.trim().toUpperCase(),
|
|
8764
|
-
phone: form.phone.trim() || void 0,
|
|
8765
|
-
document: documentDigits(form.document) || void 0
|
|
8766
|
-
},
|
|
9560
|
+
shippingAddress: deliveryAddress(),
|
|
8767
9561
|
discountCode: cart.discountCode ?? null,
|
|
8768
9562
|
paymentMethod,
|
|
8769
9563
|
// Qual adquirente cobra. Sai dos ajustes da loja e não de uma escolha do
|
|
8770
9564
|
// comprador — a função reconfere de qualquer forma, mas mandar daqui é o
|
|
8771
9565
|
// que faz o clique bater na função do gateway que a loja realmente conectou.
|
|
8772
|
-
provider: policy?.paymentProvider ?? null
|
|
9566
|
+
provider: policy?.paymentProvider ?? null,
|
|
9567
|
+
// The market (0116) the acquirer's open function prices and charges in.
|
|
9568
|
+
market: config.market?.code ?? null,
|
|
9569
|
+
country
|
|
8773
9570
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
8774
|
-
}), [cart.lines, cart.discountCode, form, paymentMethod, policy?.paymentProvider]);
|
|
9571
|
+
}), [cart.lines, cart.discountCode, form, paymentMethod, policy?.paymentProvider, country, config.market?.code]);
|
|
8775
9572
|
const [unavailable, setUnavailable] = useState([]);
|
|
8776
|
-
const cardIsCharged =
|
|
9573
|
+
const cardIsCharged = (
|
|
9574
|
+
// Outside Brazil a card is charged online only by a real acquirer: with no
|
|
9575
|
+
// provider the online panel is the mock's Pix, which a Spanish buyer cannot
|
|
9576
|
+
// pay. Without one the order is placed pending, as an offline payment is.
|
|
9577
|
+
(isBrazil || !!policy?.paymentProvider) && !unavailable.includes("credit_card") && (!policy?.paymentProvider || isChargeableProvider(policy.paymentProvider)) && (!policy?.paymentProvider || supportsCard(policy.paymentProvider))
|
|
9578
|
+
);
|
|
8777
9579
|
const acquirerMissing = unavailable.includes(paymentMethod);
|
|
8778
9580
|
const chargesOnline = (
|
|
8779
9581
|
// Pix é cobrado dentro da loja; cartão é pago na página do adquirente e
|
|
@@ -8792,17 +9594,17 @@ function CheckoutPage() {
|
|
|
8792
9594
|
setForm((current) => ({ ...current, [key]: value }));
|
|
8793
9595
|
};
|
|
8794
9596
|
async function setZip(value) {
|
|
8795
|
-
const masked = formatPostalCode(value);
|
|
9597
|
+
const masked = formatPostalCode(value, country);
|
|
8796
9598
|
setError(null);
|
|
8797
9599
|
setForm((current) => ({ ...current, zip: masked }));
|
|
8798
|
-
if (normalizePostalCode(masked
|
|
9600
|
+
if (!countrySchema.postal.pattern.test(normalizePostalCode(masked, country))) {
|
|
8799
9601
|
setZipLookup("idle");
|
|
8800
9602
|
return;
|
|
8801
9603
|
}
|
|
8802
9604
|
setZipLookup("loading");
|
|
8803
|
-
void delivery.resolve(masked, subtotal);
|
|
9605
|
+
void delivery.resolve(masked, subtotal, country);
|
|
8804
9606
|
try {
|
|
8805
|
-
const found = await lookupPostalCode(masked);
|
|
9607
|
+
const found = await lookupPostalCode(masked, country);
|
|
8806
9608
|
if (!found) {
|
|
8807
9609
|
setZipLookup("not-found");
|
|
8808
9610
|
return;
|
|
@@ -8812,7 +9614,7 @@ function CheckoutPage() {
|
|
|
8812
9614
|
...current,
|
|
8813
9615
|
street: found.street || current.street,
|
|
8814
9616
|
district: found.district || current.district,
|
|
8815
|
-
city: found.city,
|
|
9617
|
+
city: found.city || current.city,
|
|
8816
9618
|
state: found.state
|
|
8817
9619
|
}));
|
|
8818
9620
|
} catch {
|
|
@@ -8829,12 +9631,12 @@ function CheckoutPage() {
|
|
|
8829
9631
|
if (result.valid) {
|
|
8830
9632
|
cart.applyDiscount(appliedCode, result.percent, { freeShipping: result.freeShipping });
|
|
8831
9633
|
setDiscountCode(appliedCode);
|
|
8832
|
-
const effect = result.freeShipping ? "
|
|
8833
|
-
setDiscountSuccess(
|
|
8834
|
-
toast.success("
|
|
9634
|
+
const effect = result.freeShipping ? t("discount.freeShipping") : t("discount.percentOff", { percent: result.percent });
|
|
9635
|
+
setDiscountSuccess(t("discount.applied", { code: appliedCode, effect }));
|
|
9636
|
+
toast.success(t("discount.appliedToast"), `${appliedCode} \u2022 ${effect}`);
|
|
8835
9637
|
} else {
|
|
8836
|
-
setDiscountError(result.message ?? "
|
|
8837
|
-
toast.error("
|
|
9638
|
+
setDiscountError(result.message ?? t("discount.invalid"));
|
|
9639
|
+
toast.error(t("discount.invalidToast"), result.message ?? t("discount.checkCode"));
|
|
8838
9640
|
}
|
|
8839
9641
|
} finally {
|
|
8840
9642
|
setApplyingDiscount(false);
|
|
@@ -8865,7 +9667,8 @@ function CheckoutPage() {
|
|
|
8865
9667
|
void listAddresses(customerId).then((addresses) => {
|
|
8866
9668
|
if (cancelled || addresses.length === 0) return;
|
|
8867
9669
|
setSavedAddresses(addresses);
|
|
8868
|
-
|
|
9670
|
+
const here = addresses.find((address) => (address.country ?? "BR") === country);
|
|
9671
|
+
if (here) applySavedAddress(here);
|
|
8869
9672
|
}).catch(() => {
|
|
8870
9673
|
}).finally(() => {
|
|
8871
9674
|
if (!cancelled) setAddressesLoading(false);
|
|
@@ -8896,17 +9699,26 @@ function CheckoutPage() {
|
|
|
8896
9699
|
cancelled = true;
|
|
8897
9700
|
};
|
|
8898
9701
|
}, [session.customerId]);
|
|
9702
|
+
const shownCountry = React38.useRef(country);
|
|
9703
|
+
useEffect(() => {
|
|
9704
|
+
if (shownCountry.current === country) return;
|
|
9705
|
+
shownCountry.current = country;
|
|
9706
|
+
setZipLookup("idle");
|
|
9707
|
+
addNewAddress();
|
|
9708
|
+
}, [country]);
|
|
9709
|
+
const addressesHere = savedAddresses.filter((address) => (address.country ?? "BR") === country);
|
|
8899
9710
|
useEffect(() => {
|
|
8900
9711
|
if (addressMode !== "new") return;
|
|
8901
|
-
const
|
|
8902
|
-
const
|
|
9712
|
+
const keptAny = delivery.savedAddresses.find((a) => a.id === delivery.selectedAddressId);
|
|
9713
|
+
const kept = keptAny && (keptAny.country ?? "BR") === country ? keptAny : void 0;
|
|
9714
|
+
const looked = delivery.address && (delivery.address.country || "BR") === country ? delivery.address : null;
|
|
8903
9715
|
if (!kept && !looked) return;
|
|
8904
9716
|
setForm((current) => {
|
|
8905
9717
|
if (current.zip.trim() || current.street.trim()) return current;
|
|
8906
9718
|
if (kept) {
|
|
8907
9719
|
return {
|
|
8908
9720
|
...current,
|
|
8909
|
-
zip: formatPostalCode(kept.postalCode),
|
|
9721
|
+
zip: formatPostalCode(kept.postalCode, country),
|
|
8910
9722
|
street: kept.street,
|
|
8911
9723
|
number: kept.number,
|
|
8912
9724
|
complement: kept.complement ?? "",
|
|
@@ -8917,14 +9729,14 @@ function CheckoutPage() {
|
|
|
8917
9729
|
}
|
|
8918
9730
|
return {
|
|
8919
9731
|
...current,
|
|
8920
|
-
zip: formatPostalCode(looked.postalCode),
|
|
9732
|
+
zip: formatPostalCode(looked.postalCode, country),
|
|
8921
9733
|
street: looked.street,
|
|
8922
9734
|
district: looked.district,
|
|
8923
9735
|
city: looked.city,
|
|
8924
9736
|
state: looked.state
|
|
8925
9737
|
};
|
|
8926
9738
|
});
|
|
8927
|
-
}, [delivery.address, delivery.savedAddresses, delivery.selectedAddressId, addressMode]);
|
|
9739
|
+
}, [delivery.address, delivery.savedAddresses, delivery.selectedAddressId, addressMode, country]);
|
|
8928
9740
|
function applySavedAddress(address) {
|
|
8929
9741
|
setAddressMode("saved");
|
|
8930
9742
|
setSelectedAddressId(address.id);
|
|
@@ -8955,9 +9767,9 @@ function CheckoutPage() {
|
|
|
8955
9767
|
function fail(message, testId) {
|
|
8956
9768
|
setError(message);
|
|
8957
9769
|
if (testId) {
|
|
8958
|
-
const
|
|
8959
|
-
|
|
8960
|
-
|
|
9770
|
+
const field = document.querySelector(`[data-testid="${testId}"]`);
|
|
9771
|
+
field?.scrollIntoView({ block: "center", behavior: prefersReducedMotion() ? "auto" : "smooth" });
|
|
9772
|
+
field?.focus({ preventScroll: true });
|
|
8961
9773
|
}
|
|
8962
9774
|
return false;
|
|
8963
9775
|
}
|
|
@@ -8965,20 +9777,61 @@ function CheckoutPage() {
|
|
|
8965
9777
|
setError(null);
|
|
8966
9778
|
if (requiresAccount && !session.customerId) {
|
|
8967
9779
|
setShowSignin(true);
|
|
8968
|
-
return fail("
|
|
9780
|
+
return fail(t("error.requiresAccount"));
|
|
8969
9781
|
}
|
|
8970
9782
|
if (!form.email.trim() || !/.+@.+\..+/.test(form.email)) {
|
|
8971
|
-
return fail("
|
|
9783
|
+
return fail(t("error.email"), TID.checkoutEmail);
|
|
8972
9784
|
}
|
|
8973
|
-
if (!form.name.trim()) return fail("
|
|
9785
|
+
if (!form.name.trim()) return fail(t("error.name"), TID.checkoutName);
|
|
8974
9786
|
if (requires("phone") && !form.phone.trim()) {
|
|
8975
|
-
return fail("
|
|
9787
|
+
return fail(t("error.phone"), "checkout-phone");
|
|
8976
9788
|
}
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
)
|
|
9789
|
+
return validateDocument();
|
|
9790
|
+
}
|
|
9791
|
+
function validateDocument() {
|
|
9792
|
+
if (isBrazil) {
|
|
9793
|
+
if (requires("document") && !isValidDocument(form.document)) {
|
|
9794
|
+
return fail(
|
|
9795
|
+
form.document.trim() ? t("error.documentInvalid") : t("error.documentMissing"),
|
|
9796
|
+
TID.checkoutDocument
|
|
9797
|
+
);
|
|
9798
|
+
}
|
|
9799
|
+
return true;
|
|
9800
|
+
}
|
|
9801
|
+
const taxId = countrySchema.taxId;
|
|
9802
|
+
if (!form.document.trim()) {
|
|
9803
|
+
return requires("document") ? fail(t("error.documentMissing"), TID.checkoutDocument) : true;
|
|
9804
|
+
}
|
|
9805
|
+
if (taxId && !taxId.validate(form.document)) return fail(t("error.taxIdInvalid"), TID.checkoutDocument);
|
|
9806
|
+
return true;
|
|
9807
|
+
}
|
|
9808
|
+
function validateAddressFields() {
|
|
9809
|
+
if (isBrazil) {
|
|
9810
|
+
if (!form.street.trim() || !form.city.trim() || !form.zip.trim() || !form.district.trim()) {
|
|
9811
|
+
return fail(t("error.address"), TID.checkoutStreet);
|
|
9812
|
+
}
|
|
9813
|
+
if (!form.number.trim()) return fail(t("error.number"), "checkout-number");
|
|
9814
|
+
if (requires("complement") && !form.complement.trim()) {
|
|
9815
|
+
return fail(t("error.complement"), "checkout-complement");
|
|
9816
|
+
}
|
|
9817
|
+
if (!/^[A-Za-z]{2}$/.test(form.state.trim())) {
|
|
9818
|
+
return fail(t("error.state"), "checkout-state");
|
|
9819
|
+
}
|
|
9820
|
+
return true;
|
|
9821
|
+
}
|
|
9822
|
+
const errors = validateAddress(
|
|
9823
|
+
{ postalCode: form.zip, street: form.street, complement: form.complement, city: form.city, state: form.state },
|
|
9824
|
+
country,
|
|
9825
|
+
{ complement: requires("complement") }
|
|
9826
|
+
);
|
|
9827
|
+
if (errors.postalCode === "invalid") {
|
|
9828
|
+
return fail(t("error.postalInvalid", { example: countrySchema.postal.example }), TID.checkoutZip);
|
|
9829
|
+
}
|
|
9830
|
+
if (errors.postalCode || errors.street || errors.city) return fail(t("error.address"), errors.postalCode ? TID.checkoutZip : TID.checkoutStreet);
|
|
9831
|
+
if (errors.complement) return fail(t("error.complement"), "checkout-complement");
|
|
9832
|
+
if (errors.region) {
|
|
9833
|
+
const label = countrySchema.fields.find((f2) => f2.key === "region")?.label[config.language] ?? "";
|
|
9834
|
+
return fail(t("error.region", { label: label.toLowerCase() }), "checkout-state");
|
|
8982
9835
|
}
|
|
8983
9836
|
return true;
|
|
8984
9837
|
}
|
|
@@ -8986,21 +9839,9 @@ function CheckoutPage() {
|
|
|
8986
9839
|
setError(null);
|
|
8987
9840
|
if (isPickup) return true;
|
|
8988
9841
|
if (!selectRequiresShipping(cart)) return true;
|
|
8989
|
-
if (!
|
|
8990
|
-
|
|
8991
|
-
|
|
8992
|
-
if (!form.number.trim()) return fail("Falta o n\xFAmero do endere\xE7o.", "checkout-number");
|
|
8993
|
-
if (requires("complement") && !form.complement.trim()) {
|
|
8994
|
-
return fail("Informe o complemento (apto, bloco).", "checkout-complement");
|
|
8995
|
-
}
|
|
8996
|
-
if (!/^[A-Za-z]{2}$/.test(form.state.trim())) {
|
|
8997
|
-
return fail("Informe a UF com duas letras (ex.: RJ).", "checkout-state");
|
|
8998
|
-
}
|
|
8999
|
-
if (delivery.status === "unserved" && delivery.postalCode === normalizePostalCode(form.zip)) {
|
|
9000
|
-
return fail(
|
|
9001
|
-
delivery.refusedZone ? "Esta loja n\xE3o entrega nesse endere\xE7o. Tente outro." : "Ainda n\xE3o entregamos nesse CEP. Tente outro endere\xE7o.",
|
|
9002
|
-
TID.checkoutZip
|
|
9003
|
-
);
|
|
9842
|
+
if (!validateAddressFields()) return false;
|
|
9843
|
+
if (delivery.status === "unserved" && delivery.postalCode === normalizePostalCode(form.zip, country)) {
|
|
9844
|
+
return fail(delivery.refusedZone ? t("error.refusedZone") : t("error.unserved"), TID.checkoutZip);
|
|
9004
9845
|
}
|
|
9005
9846
|
return true;
|
|
9006
9847
|
}
|
|
@@ -9017,17 +9858,10 @@ function CheckoutPage() {
|
|
|
9017
9858
|
document: documentDigits(form.document) || void 0
|
|
9018
9859
|
};
|
|
9019
9860
|
}
|
|
9020
|
-
return
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
complement: form.complement.trim() || void 0,
|
|
9025
|
-
district: form.district.trim() || void 0,
|
|
9026
|
-
city: form.city.trim(),
|
|
9027
|
-
state: form.state.trim().toUpperCase(),
|
|
9028
|
-
phone: form.phone.trim() || void 0,
|
|
9029
|
-
document: documentDigits(form.document) || void 0
|
|
9030
|
-
};
|
|
9861
|
+
return deliveryAddress();
|
|
9862
|
+
}
|
|
9863
|
+
function deliveryAddress() {
|
|
9864
|
+
return toShippingAddress(form, country);
|
|
9031
9865
|
}
|
|
9032
9866
|
function advance() {
|
|
9033
9867
|
if (step === 1 && validateContact()) {
|
|
@@ -9074,7 +9908,7 @@ function CheckoutPage() {
|
|
|
9074
9908
|
cart.clear();
|
|
9075
9909
|
navigateTo(`/order/${order.id}`);
|
|
9076
9910
|
} catch (err) {
|
|
9077
|
-
setError(placeOrderMessage(err));
|
|
9911
|
+
setError(placeOrderMessage(err, t));
|
|
9078
9912
|
setPlacing(false);
|
|
9079
9913
|
}
|
|
9080
9914
|
}
|
|
@@ -9082,41 +9916,22 @@ function CheckoutPage() {
|
|
|
9082
9916
|
setError(null);
|
|
9083
9917
|
if (requiresAccount && !session.customerId) {
|
|
9084
9918
|
setShowSignin(true);
|
|
9085
|
-
return fail("
|
|
9919
|
+
return fail(t("error.requiresAccount"));
|
|
9086
9920
|
}
|
|
9087
9921
|
if (!form.email.trim() || !/.+@.+\..+/.test(form.email)) {
|
|
9088
|
-
return fail("
|
|
9922
|
+
return fail(t("error.email"), TID.checkoutEmail);
|
|
9089
9923
|
}
|
|
9090
9924
|
if (requires("phone") && !form.phone.trim()) {
|
|
9091
|
-
return fail("
|
|
9925
|
+
return fail(t("error.phone"), "checkout-phone");
|
|
9092
9926
|
}
|
|
9093
9927
|
if (!form.name.trim()) {
|
|
9094
|
-
return fail("
|
|
9095
|
-
}
|
|
9096
|
-
if (requires("document") && !isValidDocument(form.document)) {
|
|
9097
|
-
return fail(
|
|
9098
|
-
form.document.trim() ? "CPF ou CNPJ inv\xE1lido \u2014 confira os n\xFAmeros." : "Informe o CPF ou CNPJ do comprador.",
|
|
9099
|
-
TID.checkoutDocument
|
|
9100
|
-
);
|
|
9928
|
+
return fail(t("error.name"), TID.checkoutName);
|
|
9101
9929
|
}
|
|
9930
|
+
if (!validateDocument()) return false;
|
|
9102
9931
|
if (isPickup) return true;
|
|
9103
|
-
if (!
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
if (!form.number.trim()) {
|
|
9107
|
-
return fail("Falta o n\xFAmero do endere\xE7o.", "checkout-number");
|
|
9108
|
-
}
|
|
9109
|
-
if (requires("complement") && !form.complement.trim()) {
|
|
9110
|
-
return fail("Informe o complemento (apto, bloco).", "checkout-complement");
|
|
9111
|
-
}
|
|
9112
|
-
if (form.state.trim().length !== 2) {
|
|
9113
|
-
return fail("Informe a UF com duas letras (ex.: RJ).", "checkout-state");
|
|
9114
|
-
}
|
|
9115
|
-
if (selectRequiresShipping(cart) && delivery.status === "unserved" && delivery.postalCode === normalizePostalCode(form.zip)) {
|
|
9116
|
-
return fail(
|
|
9117
|
-
delivery.refusedZone ? "Esta loja n\xE3o entrega nesse endere\xE7o. Tente outro." : "Ainda n\xE3o entregamos nesse CEP. Tente outro endere\xE7o.",
|
|
9118
|
-
TID.checkoutZip
|
|
9119
|
-
);
|
|
9932
|
+
if (!validateAddressFields()) return false;
|
|
9933
|
+
if (selectRequiresShipping(cart) && delivery.status === "unserved" && delivery.postalCode === normalizePostalCode(form.zip, country)) {
|
|
9934
|
+
return fail(delivery.refusedZone ? t("error.refusedZone") : t("error.unserved"), TID.checkoutZip);
|
|
9120
9935
|
}
|
|
9121
9936
|
return true;
|
|
9122
9937
|
}
|
|
@@ -9131,15 +9946,15 @@ function CheckoutPage() {
|
|
|
9131
9946
|
}
|
|
9132
9947
|
),
|
|
9133
9948
|
/* @__PURE__ */ jsx("header", { className: "border-b bg-background", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto flex max-w-6xl items-center justify-between gap-4 px-4 py-6 sm:px-6", children: [
|
|
9134
|
-
/* @__PURE__ */ jsx(Link, { to: returnPath(config), className: "text-sm text-muted-foreground hover:text-foreground", children: "
|
|
9949
|
+
/* @__PURE__ */ jsx(Link, { to: returnPath(config), className: "text-sm text-muted-foreground hover:text-foreground", children: t("checkout.backToStore") }),
|
|
9135
9950
|
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
9136
9951
|
/* @__PURE__ */ jsx("div", { className: "sf-heading text-2xl font-bold tracking-tight", children: config.logo ?? config.name }),
|
|
9137
9952
|
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
|
|
9138
9953
|
/* @__PURE__ */ jsx(Lock, { className: "h-3.5 w-3.5" }),
|
|
9139
|
-
"
|
|
9954
|
+
t("checkout.secure")
|
|
9140
9955
|
] })
|
|
9141
9956
|
] }),
|
|
9142
|
-
/* @__PURE__ */ jsx("a", { href: "mailto:suporte@example.com", className: "text-sm text-muted-foreground hover:text-foreground", children: "
|
|
9957
|
+
/* @__PURE__ */ jsx("a", { href: "mailto:suporte@example.com", className: "text-sm text-muted-foreground hover:text-foreground", children: t("checkout.help") })
|
|
9143
9958
|
] }) }),
|
|
9144
9959
|
/* @__PURE__ */ jsxs("div", { className: "mx-auto grid max-w-6xl grid-cols-1 gap-8 px-4 py-8 sm:px-6 lg:grid-cols-5 lg:px-6", children: [
|
|
9145
9960
|
/* @__PURE__ */ jsxs("section", { className: "lg:col-span-3 lg:pr-10", children: [
|
|
@@ -9162,35 +9977,32 @@ function CheckoutPage() {
|
|
|
9162
9977
|
children: [
|
|
9163
9978
|
step === 1 && /* @__PURE__ */ jsxs("section", { children: [
|
|
9164
9979
|
/* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-center justify-between gap-4", children: [
|
|
9165
|
-
/* @__PURE__ */ jsx("h1", { className: "text-xl font-semibold tracking-tight", children: "
|
|
9166
|
-
session.email ? /* @__PURE__ */
|
|
9167
|
-
"Conectado como ",
|
|
9168
|
-
session.email
|
|
9169
|
-
] }) : /* @__PURE__ */ jsx(
|
|
9980
|
+
/* @__PURE__ */ jsx("h1", { className: "text-xl font-semibold tracking-tight", children: t("checkout.contact.title") }),
|
|
9981
|
+
session.email ? /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: t("checkout.contact.signedInAs", { email: session.email }) }) : /* @__PURE__ */ jsx(
|
|
9170
9982
|
"button",
|
|
9171
9983
|
{
|
|
9172
9984
|
type: "button",
|
|
9173
9985
|
onClick: () => setShowSignin((value) => !value),
|
|
9174
9986
|
className: "text-sm font-medium text-primary hover:underline",
|
|
9175
|
-
children: "
|
|
9987
|
+
children: t("checkout.contact.haveAccount")
|
|
9176
9988
|
}
|
|
9177
9989
|
)
|
|
9178
9990
|
] }),
|
|
9179
9991
|
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [
|
|
9180
|
-
|
|
9992
|
+
checkoutField(t("checkout.contact.email"), TID.checkoutEmail, form.email, set("email"), {
|
|
9181
9993
|
type: "email",
|
|
9182
|
-
placeholder: "
|
|
9994
|
+
placeholder: t("checkout.contact.email")
|
|
9183
9995
|
}),
|
|
9184
|
-
|
|
9185
|
-
placeholder: "
|
|
9996
|
+
checkoutField(t("checkout.contact.name"), TID.checkoutName, form.name, set("name"), {
|
|
9997
|
+
placeholder: t("checkout.contact.name")
|
|
9186
9998
|
}),
|
|
9187
|
-
shows("phone") &&
|
|
9999
|
+
shows("phone") && checkoutField(t("checkout.contact.phone"), "checkout-phone", form.phone, set("phone"), {
|
|
9188
10000
|
type: "tel",
|
|
9189
10001
|
autoComplete: "tel",
|
|
9190
|
-
placeholder: requires("phone") ? "
|
|
10002
|
+
placeholder: requires("phone") ? t("checkout.contact.phone") : t("checkout.contact.phoneOptional")
|
|
9191
10003
|
}),
|
|
9192
|
-
shows("document") &&
|
|
9193
|
-
"
|
|
10004
|
+
shows("document") && (isBrazil ? checkoutField(
|
|
10005
|
+
t("checkout.contact.document"),
|
|
9194
10006
|
TID.checkoutDocument,
|
|
9195
10007
|
form.document,
|
|
9196
10008
|
(value) => {
|
|
@@ -9202,12 +10014,19 @@ function CheckoutPage() {
|
|
|
9202
10014
|
// and a dash, which a number input silently refuses to hold.
|
|
9203
10015
|
inputMode: "numeric",
|
|
9204
10016
|
autoComplete: "off",
|
|
9205
|
-
placeholder: requires("document") ? "
|
|
10017
|
+
placeholder: requires("document") ? t("checkout.contact.document") : t("checkout.contact.documentOptional")
|
|
9206
10018
|
}
|
|
9207
|
-
)
|
|
10019
|
+
) : checkoutField(
|
|
10020
|
+
// The country's own tax id (Spain: NIF/NIE), unmasked: it has letters.
|
|
10021
|
+
countrySchema.taxId?.label[config.language] ?? t("checkout.contact.documentOptional"),
|
|
10022
|
+
TID.checkoutDocument,
|
|
10023
|
+
form.document,
|
|
10024
|
+
set("document"),
|
|
10025
|
+
{ autoComplete: "off", placeholder: countrySchema.taxId?.label[config.language] ?? "" }
|
|
10026
|
+
))
|
|
9208
10027
|
] }),
|
|
9209
10028
|
requiresAccount && !session.customerId && /* @__PURE__ */ jsxs("p", { className: "mt-3 rounded-lg border border-primary/30 bg-primary/5 px-3 py-2 text-sm", children: [
|
|
9210
|
-
"
|
|
10029
|
+
t("checkout.contact.requiresAccount"),
|
|
9211
10030
|
" ",
|
|
9212
10031
|
/* @__PURE__ */ jsx(
|
|
9213
10032
|
"button",
|
|
@@ -9215,27 +10034,28 @@ function CheckoutPage() {
|
|
|
9215
10034
|
type: "button",
|
|
9216
10035
|
onClick: () => setShowSignin(true),
|
|
9217
10036
|
className: "font-semibold text-primary hover:underline",
|
|
9218
|
-
children: "
|
|
10037
|
+
children: t("checkout.contact.signInOrCreate")
|
|
9219
10038
|
}
|
|
9220
10039
|
)
|
|
9221
10040
|
] })
|
|
9222
10041
|
] }),
|
|
9223
10042
|
step === 2 && /* @__PURE__ */ jsxs("section", { children: [
|
|
9224
|
-
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-xl font-semibold tracking-tight", children: "
|
|
10043
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-xl font-semibold tracking-tight", children: t("checkout.address.title") }),
|
|
10044
|
+
buyer.allowed.length > 1 && /* @__PURE__ */ jsx(CountrySelect, { className: "mb-3", country, allowed: buyer.allowed, onChange: buyer.setCountry }),
|
|
9225
10045
|
/* @__PURE__ */ jsxs("div", { className: "mb-3 grid gap-3", children: [
|
|
9226
|
-
addressesLoading && savedAddresses.length === 0 && /* @__PURE__ */ jsx(SkeletonGroup, { label: "
|
|
10046
|
+
addressesLoading && savedAddresses.length === 0 && /* @__PURE__ */ jsx(SkeletonGroup, { label: t("checkout.address.loadingSaved"), className: "grid gap-3", children: [0, 1].map((row) => /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-3", children: [
|
|
9227
10047
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-28" }),
|
|
9228
10048
|
/* @__PURE__ */ jsx(Skeleton, { className: "mt-2 h-3 w-3/4" }),
|
|
9229
10049
|
/* @__PURE__ */ jsx(Skeleton, { className: "mt-1.5 h-3 w-1/2" })
|
|
9230
10050
|
] }, row)) }),
|
|
9231
|
-
|
|
10051
|
+
addressesHere.map((address) => /* @__PURE__ */ jsx(
|
|
9232
10052
|
"div",
|
|
9233
10053
|
{
|
|
9234
10054
|
className: `group relative rounded-lg border p-3 pr-11 text-left text-sm transition hover:bg-muted/40 ${selectedAddressId === address.id ? "border-primary bg-primary/5" : "border-border bg-background"}`,
|
|
9235
10055
|
children: /* @__PURE__ */ jsxs("button", { type: "button", onClick: () => selectAddress(address.id), className: "block w-full text-left", children: [
|
|
9236
10056
|
/* @__PURE__ */ jsxs("span", { className: "flex items-center justify-between gap-3 font-semibold", children: [
|
|
9237
10057
|
address.label,
|
|
9238
|
-
addressMode === "saved" && selectedAddressId === address.id && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-[11px] font-bold text-primary", children: "
|
|
10058
|
+
addressMode === "saved" && selectedAddressId === address.id && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-[11px] font-bold text-primary", children: t("checkout.address.selected") })
|
|
9239
10059
|
] }),
|
|
9240
10060
|
/* @__PURE__ */ jsxs("span", { className: "mt-1 block text-muted-foreground", children: [
|
|
9241
10061
|
[address.street, address.number].filter(Boolean).join(", "),
|
|
@@ -9257,41 +10077,28 @@ function CheckoutPage() {
|
|
|
9257
10077
|
onClick: addNewAddress,
|
|
9258
10078
|
className: `rounded-lg border border-dashed p-3 text-left text-sm transition hover:bg-muted/40 ${addressMode === "new" ? "border-primary bg-primary/5" : "border-border bg-muted/20"}`,
|
|
9259
10079
|
children: [
|
|
9260
|
-
/* @__PURE__ */ jsx("span", { className: "block font-semibold text-primary", children:
|
|
9261
|
-
/* @__PURE__ */ jsx("span", { className: "mt-1 block text-muted-foreground", children: "
|
|
10080
|
+
/* @__PURE__ */ jsx("span", { className: "block font-semibold text-primary", children: addressesHere.length > 0 ? t("checkout.address.addNew") : t("checkout.address.enter") }),
|
|
10081
|
+
/* @__PURE__ */ jsx("span", { className: "mt-1 block text-muted-foreground", children: t("checkout.address.enterHint") })
|
|
9262
10082
|
]
|
|
9263
10083
|
}
|
|
9264
10084
|
)
|
|
9265
10085
|
] }),
|
|
9266
|
-
addressMode === "new" && /* @__PURE__ */
|
|
9267
|
-
|
|
9268
|
-
|
|
9269
|
-
|
|
9270
|
-
|
|
9271
|
-
|
|
9272
|
-
|
|
9273
|
-
|
|
9274
|
-
|
|
9275
|
-
|
|
9276
|
-
|
|
9277
|
-
|
|
9278
|
-
field("Endere\xE7o", TID.checkoutStreet, form.street, set("street"), { placeholder: "Rua, avenida\u2026" }),
|
|
9279
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
9280
|
-
field("N\xFAmero", "checkout-number", form.number, set("number"), { placeholder: "N\xFAmero" }),
|
|
9281
|
-
shows("complement") && field("Complemento", "checkout-complement", form.complement, set("complement"), {
|
|
9282
|
-
placeholder: requires("complement") ? "Apto, bloco" : "Apto, bloco (opcional)"
|
|
9283
|
-
})
|
|
9284
|
-
] }),
|
|
9285
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
9286
|
-
field("Bairro", "checkout-district", form.district, set("district"), { placeholder: "Bairro" }),
|
|
9287
|
-
field("UF", "checkout-state", form.state, set("state"), { placeholder: "UF" })
|
|
9288
|
-
] }),
|
|
9289
|
-
field("Cidade", TID.checkoutCity, form.city, set("city"), { placeholder: "Cidade" })
|
|
9290
|
-
] })
|
|
10086
|
+
addressMode === "new" && /* @__PURE__ */ jsx(
|
|
10087
|
+
AddressForm,
|
|
10088
|
+
{
|
|
10089
|
+
country,
|
|
10090
|
+
language: config.language,
|
|
10091
|
+
value: form,
|
|
10092
|
+
onChange: (key, value) => set(key)(value),
|
|
10093
|
+
onPostalCode: setZip,
|
|
10094
|
+
lookup: zipLookup,
|
|
10095
|
+
complement: { visible: shows("complement"), required: requires("complement") }
|
|
10096
|
+
}
|
|
10097
|
+
)
|
|
9291
10098
|
] }),
|
|
9292
10099
|
step === 3 && placing && /* @__PURE__ */ jsxs("section", { children: [
|
|
9293
|
-
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-xl font-semibold tracking-tight", children: "
|
|
9294
|
-
/* @__PURE__ */ jsxs(SkeletonGroup, { label: "
|
|
10100
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-xl font-semibold tracking-tight", children: t("checkout.confirming.title") }),
|
|
10101
|
+
/* @__PURE__ */ jsxs(SkeletonGroup, { label: t("checkout.confirming.label"), className: "rounded-xl border bg-card p-6 sm:p-8", children: [
|
|
9295
10102
|
/* @__PURE__ */ jsxs("div", { className: "grid gap-6 border-b pb-6 sm:grid-cols-[120px_minmax(0,1fr)]", children: [
|
|
9296
10103
|
/* @__PURE__ */ jsx(Skeleton, { className: "mx-auto h-24 w-24 rounded-full" }),
|
|
9297
10104
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -9310,13 +10117,13 @@ function CheckoutPage() {
|
|
|
9310
10117
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-16" })
|
|
9311
10118
|
] }, line.lineId ?? line.productId)) })
|
|
9312
10119
|
] }),
|
|
9313
|
-
/* @__PURE__ */ jsx("p", { className: "mt-3 text-center text-sm text-muted-foreground", children: "
|
|
10120
|
+
/* @__PURE__ */ jsx("p", { className: "mt-3 text-center text-sm text-muted-foreground", children: t("checkout.confirming.keepOpen") })
|
|
9314
10121
|
] }),
|
|
9315
10122
|
step === 3 && !placing && /* @__PURE__ */ jsxs("section", { children: [
|
|
9316
|
-
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-xl font-semibold tracking-tight", children: "
|
|
9317
|
-
/* @__PURE__ */ jsx("div", { className: "mb-3 grid gap-3", role: "radiogroup", "aria-label": "
|
|
9318
|
-
const base = PAYMENT_LABELS[method];
|
|
9319
|
-
const copy = method === "credit_card" && cardIsCharged ? { ...base, hint: "
|
|
10123
|
+
/* @__PURE__ */ jsx("h2", { className: "mb-3 text-xl font-semibold tracking-tight", children: t("checkout.payment.title") }),
|
|
10124
|
+
/* @__PURE__ */ jsx("div", { className: "mb-3 grid gap-3", role: "radiogroup", "aria-label": t("checkout.payment.label"), children: paymentMethods.map((method) => {
|
|
10125
|
+
const base = { label: t(PAYMENT_LABELS[method].label), hint: t(PAYMENT_LABELS[method].hint) };
|
|
10126
|
+
const copy = method === "credit_card" && cardIsCharged ? { ...base, hint: t("checkout.payment.cardOnline") } : base;
|
|
9320
10127
|
const selected = paymentMethod === method;
|
|
9321
10128
|
return (
|
|
9322
10129
|
// Cada forma de pagamento abre o que ELA pede, embaixo dela
|
|
@@ -9338,7 +10145,7 @@ function CheckoutPage() {
|
|
|
9338
10145
|
/* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
|
|
9339
10146
|
copy.label
|
|
9340
10147
|
] }),
|
|
9341
|
-
selected && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-[11px] font-bold text-primary", children: "
|
|
10148
|
+
selected && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-[11px] font-bold text-primary", children: t("checkout.address.selected") })
|
|
9342
10149
|
] }),
|
|
9343
10150
|
/* @__PURE__ */ jsx("span", { className: "mt-1 block text-muted-foreground", children: copy.hint })
|
|
9344
10151
|
]
|
|
@@ -9376,10 +10183,10 @@ function CheckoutPage() {
|
|
|
9376
10183
|
void confirmWithoutCharge();
|
|
9377
10184
|
},
|
|
9378
10185
|
className: "min-h-12 w-full rounded-xl bg-primary px-6 py-3 font-semibold text-primary-foreground transition hover:opacity-90 disabled:opacity-60",
|
|
9379
|
-
children:
|
|
10186
|
+
children: t("checkout.payment.placeOrder", { total: money(total) })
|
|
9380
10187
|
}
|
|
9381
10188
|
),
|
|
9382
|
-
/* @__PURE__ */ jsx("p", { className: "mt-2 text-center text-xs text-muted-foreground", children: "
|
|
10189
|
+
/* @__PURE__ */ jsx("p", { className: "mt-2 text-center text-xs text-muted-foreground", children: t("checkout.payment.pendingNote") })
|
|
9383
10190
|
] }),
|
|
9384
10191
|
DEV_BUILD && chargesOnline && /* @__PURE__ */ jsxs("div", { className: "mt-6 rounded-xl border border-dashed border-amber-500/60 bg-amber-500/5 p-4", children: [
|
|
9385
10192
|
/* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-amber-600", children: "Somente em desenvolvimento" }),
|
|
@@ -9405,15 +10212,15 @@ function CheckoutPage() {
|
|
|
9405
10212
|
] }),
|
|
9406
10213
|
step === 4 && paidOrderId && /* @__PURE__ */ jsxs("section", { "data-testid": TID.checkoutDone, className: "rounded-xl border bg-card p-8 text-center", children: [
|
|
9407
10214
|
/* @__PURE__ */ jsx(SuccessMark, {}),
|
|
9408
|
-
/* @__PURE__ */ jsx("h2", { className: "mt-4 text-2xl font-bold tracking-tight", children: "
|
|
9409
|
-
/* @__PURE__ */ jsx("p", { className: "mt-2 text-muted-foreground", children: "
|
|
10215
|
+
/* @__PURE__ */ jsx("h2", { className: "mt-4 text-2xl font-bold tracking-tight", children: t("checkout.done.title") }),
|
|
10216
|
+
/* @__PURE__ */ jsx("p", { className: "mt-2 text-muted-foreground", children: t("checkout.done.text") }),
|
|
9410
10217
|
/* @__PURE__ */ jsx(
|
|
9411
10218
|
"button",
|
|
9412
10219
|
{
|
|
9413
10220
|
type: "button",
|
|
9414
10221
|
onClick: () => navigateTo(`/order/${paidOrderId}`),
|
|
9415
10222
|
className: "mt-6 inline-flex min-h-11 items-center rounded-lg bg-primary px-6 py-3 text-sm font-semibold text-primary-foreground transition hover:opacity-90",
|
|
9416
|
-
children: "
|
|
10223
|
+
children: t("checkout.done.viewOrder")
|
|
9417
10224
|
}
|
|
9418
10225
|
)
|
|
9419
10226
|
] }),
|
|
@@ -9425,7 +10232,7 @@ function CheckoutPage() {
|
|
|
9425
10232
|
type: "submit",
|
|
9426
10233
|
"data-testid": TID.checkoutContinue,
|
|
9427
10234
|
className: "min-h-12 rounded-lg bg-primary px-6 py-4 text-sm font-bold text-primary-foreground transition hover:opacity-90",
|
|
9428
|
-
children: step === 1 ? isPickup ?
|
|
10235
|
+
children: step === 1 ? isPickup ? t("checkout.goToPayment", { total: money(total) }) : t("checkout.continueToDelivery") : t("checkout.goToPayment", { total: money(total) })
|
|
9429
10236
|
}
|
|
9430
10237
|
),
|
|
9431
10238
|
step === 2 && /* @__PURE__ */ jsx(
|
|
@@ -9435,17 +10242,17 @@ function CheckoutPage() {
|
|
|
9435
10242
|
"data-testid": TID.checkoutBack,
|
|
9436
10243
|
onClick: () => goToStep(1),
|
|
9437
10244
|
className: "min-h-11 rounded-lg border px-6 py-3 text-sm font-medium transition hover:bg-muted",
|
|
9438
|
-
children: "
|
|
10245
|
+
children: t("checkout.backToContact")
|
|
9439
10246
|
}
|
|
9440
10247
|
),
|
|
9441
|
-
/* @__PURE__ */ jsx(Link, { to: returnPath(config), className: "text-center text-sm text-muted-foreground hover:text-foreground", children: "
|
|
10248
|
+
/* @__PURE__ */ jsx(Link, { to: returnPath(config), className: "text-center text-sm text-muted-foreground hover:text-foreground", children: t("checkout.backToCart") })
|
|
9442
10249
|
] })
|
|
9443
10250
|
]
|
|
9444
10251
|
}
|
|
9445
10252
|
)
|
|
9446
10253
|
] }),
|
|
9447
10254
|
/* @__PURE__ */ jsxs("aside", { className: "rounded-xl border bg-muted/20 p-5 lg:sticky lg:top-6 lg:col-span-2 lg:self-start", children: [
|
|
9448
|
-
/* @__PURE__ */ jsx("h2", { className: "sr-only", children: "
|
|
10255
|
+
/* @__PURE__ */ jsx("h2", { className: "sr-only", children: t("summary.title") }),
|
|
9449
10256
|
/* @__PURE__ */ jsx("ul", { className: "space-y-4", children: cart.lines.map((line) => /* @__PURE__ */ jsxs("li", { className: "flex gap-3 text-sm", children: [
|
|
9450
10257
|
/* @__PURE__ */ jsxs("div", { className: "relative h-16 w-16 flex-none overflow-hidden rounded-lg border bg-background", children: [
|
|
9451
10258
|
line.imageUrl && /* @__PURE__ */ jsx(SmoothImage, { src: line.imageUrl, alt: line.name, className: "h-full w-full object-cover", variant: { width: 96 } }),
|
|
@@ -9470,7 +10277,7 @@ function CheckoutPage() {
|
|
|
9470
10277
|
{
|
|
9471
10278
|
"data-testid": TID.discountInput,
|
|
9472
10279
|
type: "text",
|
|
9473
|
-
placeholder: "
|
|
10280
|
+
placeholder: t("discount.placeholder"),
|
|
9474
10281
|
value: discountCode,
|
|
9475
10282
|
onChange: (event) => {
|
|
9476
10283
|
setDiscountCode(event.target.value);
|
|
@@ -9488,7 +10295,7 @@ function CheckoutPage() {
|
|
|
9488
10295
|
onClick: applyDiscountCode,
|
|
9489
10296
|
disabled: applyingDiscount || !discountCode.trim(),
|
|
9490
10297
|
className: "rounded-lg border px-3 py-2 text-sm font-semibold hover:bg-muted disabled:opacity-50",
|
|
9491
|
-
children: "
|
|
10298
|
+
children: t("discount.apply")
|
|
9492
10299
|
}
|
|
9493
10300
|
)
|
|
9494
10301
|
] }),
|
|
@@ -9497,12 +10304,12 @@ function CheckoutPage() {
|
|
|
9497
10304
|
] }),
|
|
9498
10305
|
/* @__PURE__ */ jsxs("dl", { className: "mt-8 space-y-3 border-t pt-6 text-sm", children: [
|
|
9499
10306
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
9500
|
-
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: "
|
|
10307
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: t("summary.subtotal") }),
|
|
9501
10308
|
/* @__PURE__ */ jsx("dd", { "data-price": subtotal.toFixed(2), children: money(subtotal) })
|
|
9502
10309
|
] }),
|
|
9503
10310
|
discountTotal > 0 && /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-emerald-700", "data-testid": TID.discountRow, children: [
|
|
9504
10311
|
/* @__PURE__ */ jsxs("dt", { children: [
|
|
9505
|
-
"
|
|
10312
|
+
t("summary.discount"),
|
|
9506
10313
|
" ",
|
|
9507
10314
|
/* @__PURE__ */ jsxs(
|
|
9508
10315
|
"button",
|
|
@@ -9525,7 +10332,7 @@ function CheckoutPage() {
|
|
|
9525
10332
|
] }),
|
|
9526
10333
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
9527
10334
|
/* @__PURE__ */ jsxs("dt", { className: cart.discountFreeShipping ? "text-emerald-700" : "text-muted-foreground", children: [
|
|
9528
|
-
isPickup ? "
|
|
10335
|
+
isPickup ? t("summary.pickup") : t("summary.delivery"),
|
|
9529
10336
|
cart.discountFreeShipping && /* @__PURE__ */ jsxs(
|
|
9530
10337
|
"button",
|
|
9531
10338
|
{
|
|
@@ -9540,23 +10347,23 @@ function CheckoutPage() {
|
|
|
9540
10347
|
}
|
|
9541
10348
|
)
|
|
9542
10349
|
] }),
|
|
9543
|
-
/* @__PURE__ */ jsx("dd", { "data-price": shipping.toFixed(2), children: isPickup ? "
|
|
10350
|
+
/* @__PURE__ */ jsx("dd", { "data-price": shipping.toFixed(2), children: isPickup ? t("summary.noFee") : shipping === 0 ? t("summary.free") : money(shipping) })
|
|
9544
10351
|
] }),
|
|
9545
10352
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between border-t pt-5 text-lg font-bold", children: [
|
|
9546
|
-
/* @__PURE__ */ jsx("dt", { children: "
|
|
10353
|
+
/* @__PURE__ */ jsx("dt", { children: t("summary.total") }),
|
|
9547
10354
|
/* @__PURE__ */ jsx("dd", { "data-price": total.toFixed(2), children: money(total) })
|
|
9548
10355
|
] })
|
|
9549
10356
|
] }),
|
|
9550
10357
|
/* @__PURE__ */ jsxs("div", { className: "mt-6 flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
9551
10358
|
/* @__PURE__ */ jsx(ShieldCheck, { className: "h-4 w-4 text-primary" }),
|
|
9552
|
-
"
|
|
10359
|
+
t("summary.protected")
|
|
9553
10360
|
] }),
|
|
9554
10361
|
/* @__PURE__ */ jsx("div", { className: "mt-6 border-t pt-5", children: /* @__PURE__ */ jsx(Slot, { area: "checkout", name: "afterForm", context: checkoutSlotContext }) })
|
|
9555
10362
|
] }),
|
|
9556
10363
|
/* @__PURE__ */ jsxs("footer", { className: "flex flex-wrap gap-4 border-t pt-5 text-xs text-muted-foreground lg:col-span-5", children: [
|
|
9557
|
-
/* @__PURE__ */ jsx(Link, { to: "/privacy", className: "hover:text-foreground", children: "
|
|
9558
|
-
/* @__PURE__ */ jsx(Link, { to: "/terms", className: "hover:text-foreground", children: "
|
|
9559
|
-
/* @__PURE__ */ jsx(Link, { to: "/refunds", className: "hover:text-foreground", children: "
|
|
10364
|
+
/* @__PURE__ */ jsx(Link, { to: "/privacy", className: "hover:text-foreground", children: t("legal.privacy") }),
|
|
10365
|
+
/* @__PURE__ */ jsx(Link, { to: "/terms", className: "hover:text-foreground", children: t("legal.terms") }),
|
|
10366
|
+
/* @__PURE__ */ jsx(Link, { to: "/refunds", className: "hover:text-foreground", children: t("legal.refunds") })
|
|
9560
10367
|
] })
|
|
9561
10368
|
] })
|
|
9562
10369
|
] });
|
|
@@ -9759,17 +10566,17 @@ function MenuToolbar({
|
|
|
9759
10566
|
onQuery,
|
|
9760
10567
|
autoFocusSearch
|
|
9761
10568
|
}) {
|
|
9762
|
-
const inputRef =
|
|
9763
|
-
const [active2, setActive] =
|
|
9764
|
-
|
|
10569
|
+
const inputRef = React38.useRef(null);
|
|
10570
|
+
const [active2, setActive] = React38.useState(null);
|
|
10571
|
+
React38.useEffect(() => {
|
|
9765
10572
|
setActive(
|
|
9766
10573
|
(current) => current && sections.some((s2) => s2.slug === current) ? current : sections[0]?.slug ?? null
|
|
9767
10574
|
);
|
|
9768
10575
|
}, [sections]);
|
|
9769
|
-
|
|
10576
|
+
React38.useEffect(() => {
|
|
9770
10577
|
if (autoFocusSearch) inputRef.current?.focus();
|
|
9771
10578
|
}, [autoFocusSearch]);
|
|
9772
|
-
|
|
10579
|
+
React38.useEffect(() => {
|
|
9773
10580
|
if (typeof IntersectionObserver === "undefined") return;
|
|
9774
10581
|
const seen = /* @__PURE__ */ new Map();
|
|
9775
10582
|
const observer = new IntersectionObserver(
|
|
@@ -9956,10 +10763,10 @@ function ItemSheet({
|
|
|
9956
10763
|
}) {
|
|
9957
10764
|
const config = useStorefrontConfig();
|
|
9958
10765
|
const money = (v) => formatMoney(v, config.currency, config.locale);
|
|
9959
|
-
const groups =
|
|
9960
|
-
const [options, setOptions] =
|
|
9961
|
-
const [notes, setNotes] =
|
|
9962
|
-
const [quantity, setQuantity] =
|
|
10766
|
+
const groups = React38.useMemo(() => getProductOptionGroups(product), [product]);
|
|
10767
|
+
const [options, setOptions] = React38.useState({});
|
|
10768
|
+
const [notes, setNotes] = React38.useState("");
|
|
10769
|
+
const [quantity, setQuantity] = React38.useState(1);
|
|
9963
10770
|
const image = product.images?.find((i) => i.isPrimary) ?? product.images?.[0];
|
|
9964
10771
|
const stock = product.inventoryCount;
|
|
9965
10772
|
const missing = groups.filter((g) => !options[g.label]);
|
|
@@ -10153,8 +10960,8 @@ function ScheduleSheet({ onClose }) {
|
|
|
10153
10960
|
const scheduledFor = useDeliveryStore((s2) => s2.scheduledFor);
|
|
10154
10961
|
const setScheduledFor = useDeliveryStore((s2) => s2.setScheduledFor);
|
|
10155
10962
|
const timezone = useServiceStore((s2) => s2.service?.timezone) ?? "America/Sao_Paulo";
|
|
10156
|
-
const [slots, setSlots] =
|
|
10157
|
-
|
|
10963
|
+
const [slots, setSlots] = React38.useState(null);
|
|
10964
|
+
React38.useEffect(() => {
|
|
10158
10965
|
let alive = true;
|
|
10159
10966
|
void (async () => {
|
|
10160
10967
|
const rows = await getShopProvider()?.listScheduleSlots?.(fulfillmentType) ?? [];
|
|
@@ -10164,7 +10971,7 @@ function ScheduleSheet({ onClose }) {
|
|
|
10164
10971
|
alive = false;
|
|
10165
10972
|
};
|
|
10166
10973
|
}, [fulfillmentType]);
|
|
10167
|
-
const days =
|
|
10974
|
+
const days = React38.useMemo(() => {
|
|
10168
10975
|
const fmtDay = new Intl.DateTimeFormat("pt-BR", {
|
|
10169
10976
|
weekday: "long",
|
|
10170
10977
|
day: "2-digit",
|
|
@@ -10250,8 +11057,8 @@ function hhmm(time) {
|
|
|
10250
11057
|
}
|
|
10251
11058
|
function ServiceHoursModal({ onClose }) {
|
|
10252
11059
|
const fulfillmentType = useServiceStore((s2) => s2.fulfillmentType);
|
|
10253
|
-
const [hours, setHours] =
|
|
10254
|
-
|
|
11060
|
+
const [hours, setHours] = React38.useState(null);
|
|
11061
|
+
React38.useEffect(() => {
|
|
10255
11062
|
let alive = true;
|
|
10256
11063
|
void (async () => {
|
|
10257
11064
|
const rows = await getShopProvider()?.listServiceHours?.(fulfillmentType) ?? [];
|
|
@@ -10261,7 +11068,7 @@ function ServiceHoursModal({ onClose }) {
|
|
|
10261
11068
|
alive = false;
|
|
10262
11069
|
};
|
|
10263
11070
|
}, [fulfillmentType]);
|
|
10264
|
-
const byDay =
|
|
11071
|
+
const byDay = React38.useMemo(() => {
|
|
10265
11072
|
const map = /* @__PURE__ */ new Map();
|
|
10266
11073
|
for (const h of hours ?? []) {
|
|
10267
11074
|
const list = map.get(h.weekday) ?? [];
|
|
@@ -10338,7 +11145,7 @@ function AddressSheet({ onClose }) {
|
|
|
10338
11145
|
const selectAddress = useDeliveryStore((s2) => s2.selectAddress);
|
|
10339
11146
|
const removeAddress = useDeliveryStore((s2) => s2.removeAddress);
|
|
10340
11147
|
const subtotal = selectSubtotal(useCartStore());
|
|
10341
|
-
const [adding, setAdding] =
|
|
11148
|
+
const [adding, setAdding] = React38.useState(saved.length === 0);
|
|
10342
11149
|
return /* @__PURE__ */ jsx(
|
|
10343
11150
|
"div",
|
|
10344
11151
|
{
|
|
@@ -10372,7 +11179,7 @@ function AddressSheet({ onClose }) {
|
|
|
10372
11179
|
)
|
|
10373
11180
|
] }),
|
|
10374
11181
|
adding ? /* @__PURE__ */ jsx(
|
|
10375
|
-
|
|
11182
|
+
AddressForm2,
|
|
10376
11183
|
{
|
|
10377
11184
|
onDone: () => {
|
|
10378
11185
|
setAdding(false);
|
|
@@ -10436,7 +11243,7 @@ function AddressSheet({ onClose }) {
|
|
|
10436
11243
|
}
|
|
10437
11244
|
);
|
|
10438
11245
|
}
|
|
10439
|
-
function
|
|
11246
|
+
function AddressForm2({ onDone }) {
|
|
10440
11247
|
const resolve = useDeliveryStore((s2) => s2.resolve);
|
|
10441
11248
|
const saveAddress = useDeliveryStore((s2) => s2.saveAddress);
|
|
10442
11249
|
const looked = useDeliveryStore((s2) => s2.address);
|
|
@@ -10444,16 +11251,16 @@ function AddressForm({ onDone }) {
|
|
|
10444
11251
|
const storeError = useDeliveryStore((s2) => s2.error);
|
|
10445
11252
|
const refusedZone = useDeliveryStore((s2) => s2.refusedZone);
|
|
10446
11253
|
const subtotal = selectSubtotal(useCartStore());
|
|
10447
|
-
const [cep, setCep] =
|
|
10448
|
-
const [number, setNumber] =
|
|
10449
|
-
const [complement, setComplement] =
|
|
10450
|
-
const [reference, setReference] =
|
|
10451
|
-
const [label, setLabel] =
|
|
10452
|
-
const [touched, setTouched] =
|
|
10453
|
-
const numberRef =
|
|
11254
|
+
const [cep, setCep] = React38.useState("");
|
|
11255
|
+
const [number, setNumber] = React38.useState("");
|
|
11256
|
+
const [complement, setComplement] = React38.useState("");
|
|
11257
|
+
const [reference, setReference] = React38.useState("");
|
|
11258
|
+
const [label, setLabel] = React38.useState("");
|
|
11259
|
+
const [touched, setTouched] = React38.useState(false);
|
|
11260
|
+
const numberRef = React38.useRef(null);
|
|
10454
11261
|
const digits = normalizePostalCode(cep);
|
|
10455
11262
|
const found = Boolean(looked) && normalizePostalCode(looked.postalCode) === digits;
|
|
10456
|
-
|
|
11263
|
+
React38.useEffect(() => {
|
|
10457
11264
|
if (found) numberRef.current?.focus();
|
|
10458
11265
|
}, [found]);
|
|
10459
11266
|
async function lookUp() {
|
|
@@ -10616,16 +11423,16 @@ var HIGHLIGHT_LIMIT = 6;
|
|
|
10616
11423
|
function MenuPage() {
|
|
10617
11424
|
const config = useStorefrontConfig();
|
|
10618
11425
|
const addItem = useCartStore((s2) => s2.addItem);
|
|
10619
|
-
const [openProduct, setOpenProduct] =
|
|
10620
|
-
const [showHours, setShowHours] =
|
|
10621
|
-
const [showClosed, setShowClosed] =
|
|
10622
|
-
const [showAddress, setShowAddress] =
|
|
10623
|
-
const [showSchedule, setShowSchedule] =
|
|
10624
|
-
const [query, setQuery] =
|
|
11426
|
+
const [openProduct, setOpenProduct] = React38.useState(null);
|
|
11427
|
+
const [showHours, setShowHours] = React38.useState(false);
|
|
11428
|
+
const [showClosed, setShowClosed] = React38.useState(false);
|
|
11429
|
+
const [showAddress, setShowAddress] = React38.useState(false);
|
|
11430
|
+
const [showSchedule, setShowSchedule] = React38.useState(false);
|
|
11431
|
+
const [query, setQuery] = React38.useState("");
|
|
10625
11432
|
const serviceState = useServiceStore();
|
|
10626
11433
|
const refreshService = useServiceStore((s2) => s2.refresh);
|
|
10627
11434
|
const isOpen = selectIsOpen(serviceState);
|
|
10628
|
-
|
|
11435
|
+
React38.useEffect(() => {
|
|
10629
11436
|
void refreshService();
|
|
10630
11437
|
}, [refreshService]);
|
|
10631
11438
|
const cart = useCartStore();
|
|
@@ -10645,7 +11452,7 @@ function MenuPage() {
|
|
|
10645
11452
|
const loading = products.status === "loading" || products.status === "idle";
|
|
10646
11453
|
const items = products.data ?? [];
|
|
10647
11454
|
const cats = categories.data ?? [];
|
|
10648
|
-
const allSections =
|
|
11455
|
+
const allSections = React38.useMemo(() => {
|
|
10649
11456
|
const byCategory = /* @__PURE__ */ new Map();
|
|
10650
11457
|
const loose = [];
|
|
10651
11458
|
for (const p of items) {
|
|
@@ -10673,7 +11480,7 @@ function MenuPage() {
|
|
|
10673
11480
|
}
|
|
10674
11481
|
return ordered;
|
|
10675
11482
|
}, [items, cats]);
|
|
10676
|
-
const highlights =
|
|
11483
|
+
const highlights = React38.useMemo(() => {
|
|
10677
11484
|
const slugs = config.delivery?.highlightSlugs;
|
|
10678
11485
|
if (slugs?.length) {
|
|
10679
11486
|
const bySlug = new Map(items.map((p) => [p.slug, p]));
|
|
@@ -10682,7 +11489,7 @@ function MenuPage() {
|
|
|
10682
11489
|
return items.filter((p) => p.compareAtPrice != null && p.compareAtPrice > p.price && p.inventoryCount > 0).slice(0, HIGHLIGHT_LIMIT);
|
|
10683
11490
|
}, [items, config.delivery?.highlightSlugs]);
|
|
10684
11491
|
const normalized = query.trim().toLowerCase();
|
|
10685
|
-
const sections =
|
|
11492
|
+
const sections = React38.useMemo(() => {
|
|
10686
11493
|
if (!normalized) return allSections;
|
|
10687
11494
|
return allSections.map((section) => ({
|
|
10688
11495
|
...section,
|
|
@@ -10835,7 +11642,7 @@ function MenuPage() {
|
|
|
10835
11642
|
);
|
|
10836
11643
|
}
|
|
10837
11644
|
function BottomBarSpace() {
|
|
10838
|
-
|
|
11645
|
+
React38.useEffect(() => {
|
|
10839
11646
|
const root = document.documentElement;
|
|
10840
11647
|
root.style.setProperty("--fayz-bottom-bar", "4.5rem");
|
|
10841
11648
|
return () => {
|
|
@@ -11106,7 +11913,7 @@ function OrderConfirmationPage({ orderId }) {
|
|
|
11106
11913
|
const [loading, setLoading] = useState(true);
|
|
11107
11914
|
const money = (v) => formatMoney(v, config.currency, config.locale);
|
|
11108
11915
|
useStorefrontHead({ title: order ? `Pedido #${order.orderNumber} \u2014 ${config.name}` : config.name });
|
|
11109
|
-
const reload =
|
|
11916
|
+
const reload = React38.useCallback(() => {
|
|
11110
11917
|
let cancelled = false;
|
|
11111
11918
|
getShopProvider().getOrder(orderId).then((o) => {
|
|
11112
11919
|
if (!cancelled) setOrder(o);
|
|
@@ -11135,7 +11942,7 @@ function OrderConfirmationPage({ orderId }) {
|
|
|
11135
11942
|
] }, column)) }),
|
|
11136
11943
|
/* @__PURE__ */ jsxs("div", { className: "mt-6", children: [
|
|
11137
11944
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-32" }),
|
|
11138
|
-
/* @__PURE__ */ jsx("div", { className: "mt-3 flex items-center gap-2", children: [0, 1, 2, 3].map((node) => /* @__PURE__ */ jsxs(
|
|
11945
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 flex items-center gap-2", children: [0, 1, 2, 3].map((node) => /* @__PURE__ */ jsxs(React38.Fragment, { children: [
|
|
11139
11946
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-7 shrink-0 rounded-full" }),
|
|
11140
11947
|
node < 3 && /* @__PURE__ */ jsx(Skeleton, { className: "h-px flex-1" })
|
|
11141
11948
|
] }, node)) })
|
|
@@ -11422,7 +12229,7 @@ function OrdersPanel() {
|
|
|
11422
12229
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-24 rounded-full" })
|
|
11423
12230
|
] }),
|
|
11424
12231
|
/* @__PURE__ */ jsx(Skeleton, { className: "mt-2 h-3 w-20" }),
|
|
11425
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 flex items-center gap-2", children: [0, 1, 2, 3].map((node) => /* @__PURE__ */ jsxs(
|
|
12232
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 flex items-center gap-2", children: [0, 1, 2, 3].map((node) => /* @__PURE__ */ jsxs(React38.Fragment, { children: [
|
|
11426
12233
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-6 shrink-0 rounded-full" }),
|
|
11427
12234
|
node < 3 && /* @__PURE__ */ jsx(Skeleton, { className: "h-px flex-1" })
|
|
11428
12235
|
] }, node)) }),
|
|
@@ -11678,7 +12485,7 @@ function PolicyPage({ kind }) {
|
|
|
11678
12485
|
] }) })
|
|
11679
12486
|
] });
|
|
11680
12487
|
}
|
|
11681
|
-
var StorefrontErrorBoundary = class extends
|
|
12488
|
+
var StorefrontErrorBoundary = class extends React38.Component {
|
|
11682
12489
|
constructor() {
|
|
11683
12490
|
super(...arguments);
|
|
11684
12491
|
this.state = { error: null };
|
|
@@ -12162,7 +12969,7 @@ function sectionToJsonSchema(name) {
|
|
|
12162
12969
|
}
|
|
12163
12970
|
};
|
|
12164
12971
|
const required = ["version"];
|
|
12165
|
-
for (const [
|
|
12972
|
+
for (const [field, fieldSpec] of Object.entries(spec.fields)) {
|
|
12166
12973
|
const node = { type: fieldSpec.type, description: fieldSpec.description };
|
|
12167
12974
|
if (fieldSpec.enum) node.enum = [...fieldSpec.enum];
|
|
12168
12975
|
if (fieldSpec.deprecated) {
|
|
@@ -12171,8 +12978,8 @@ function sectionToJsonSchema(name) {
|
|
|
12171
12978
|
node["x-fayz-replacement"] = fieldSpec.deprecated.replacement;
|
|
12172
12979
|
node["x-fayz-removed-at-section-version"] = fieldSpec.deprecated.removedAtVersion;
|
|
12173
12980
|
}
|
|
12174
|
-
properties[
|
|
12175
|
-
if (fieldSpec.required) required.push(
|
|
12981
|
+
properties[field] = node;
|
|
12982
|
+
if (fieldSpec.required) required.push(field);
|
|
12176
12983
|
}
|
|
12177
12984
|
return {
|
|
12178
12985
|
type: "object",
|
|
@@ -12467,22 +13274,22 @@ function collectSettingIds(settings) {
|
|
|
12467
13274
|
}
|
|
12468
13275
|
var TOKEN_KEY = /^[a-zA-Z][a-zA-Z0-9-]*$/;
|
|
12469
13276
|
function validateTheme(errors, section) {
|
|
12470
|
-
for (const
|
|
12471
|
-
const scale = section[
|
|
13277
|
+
for (const field of THEME_SCALE_FIELDS) {
|
|
13278
|
+
const scale = section[field];
|
|
12472
13279
|
if (scale === void 0) continue;
|
|
12473
13280
|
if (!isRecord(scale)) continue;
|
|
12474
13281
|
for (const [key, value] of Object.entries(scale)) {
|
|
12475
|
-
const path = `theme.${
|
|
13282
|
+
const path = `theme.${field}.${key}`;
|
|
12476
13283
|
if (!TOKEN_KEY.test(key)) {
|
|
12477
13284
|
push(
|
|
12478
13285
|
errors,
|
|
12479
13286
|
path,
|
|
12480
13287
|
"invalid-token-key",
|
|
12481
|
-
`"${key}" cannot become the CSS custom property ${THEME_SCALE_VAR_PREFIX[
|
|
13288
|
+
`"${key}" cannot become the CSS custom property ${THEME_SCALE_VAR_PREFIX[field]}-${key} \u2014 token keys match ${TOKEN_KEY}`
|
|
12482
13289
|
);
|
|
12483
13290
|
}
|
|
12484
13291
|
if (typeof value !== "string") {
|
|
12485
|
-
push(errors, path, "invalid-value", `a ${
|
|
13292
|
+
push(errors, path, "invalid-value", `a ${field} token is a CSS value string, got ${typeof value}`);
|
|
12486
13293
|
}
|
|
12487
13294
|
}
|
|
12488
13295
|
}
|
|
@@ -12540,9 +13347,9 @@ function validateSectionEnvelope(errors, name, section) {
|
|
|
12540
13347
|
);
|
|
12541
13348
|
}
|
|
12542
13349
|
}
|
|
12543
|
-
for (const [
|
|
12544
|
-
if (fieldSpec.required && section[
|
|
12545
|
-
push(errors, `${name}.${
|
|
13350
|
+
for (const [field, fieldSpec] of Object.entries(spec.fields)) {
|
|
13351
|
+
if (fieldSpec.required && section[field] === void 0) {
|
|
13352
|
+
push(errors, `${name}.${field}`, "missing-field", `section "${name}" requires "${field}"`);
|
|
12546
13353
|
}
|
|
12547
13354
|
}
|
|
12548
13355
|
return true;
|
|
@@ -12704,7 +13511,7 @@ function validateEntitiesSection(errors, section) {
|
|
|
12704
13511
|
}
|
|
12705
13512
|
const fields = declaration.fields;
|
|
12706
13513
|
const fieldNames = Object.keys(fields);
|
|
12707
|
-
for (const [name,
|
|
13514
|
+
for (const [name, field] of Object.entries(fields)) {
|
|
12708
13515
|
const fieldPath = `${path}.fields.${name}`;
|
|
12709
13516
|
if (!ENTITY_FIELD_RE.test(name)) {
|
|
12710
13517
|
push(errors, fieldPath, "invalid-value", `"${name}" is not a valid field name \u2014 fields are snake_case`);
|
|
@@ -12713,19 +13520,19 @@ function validateEntitiesSection(errors, section) {
|
|
|
12713
13520
|
push(errors, fieldPath, "invalid-value", `"${name}" is a structural record column`, RESERVED_ENTITY_FIELDS);
|
|
12714
13521
|
continue;
|
|
12715
13522
|
}
|
|
12716
|
-
if (!isRecord(
|
|
13523
|
+
if (!isRecord(field) || typeof field.type !== "string") {
|
|
12717
13524
|
push(errors, fieldPath, "invalid-value", "a field is {type: <entity field type>, label?, required?, \u2026}");
|
|
12718
13525
|
continue;
|
|
12719
13526
|
}
|
|
12720
|
-
if (!ENTITY_FIELD_TYPES.includes(
|
|
12721
|
-
push(errors, `${fieldPath}.type`, "unknown-entity-field-type", `"${
|
|
13527
|
+
if (!ENTITY_FIELD_TYPES.includes(field.type)) {
|
|
13528
|
+
push(errors, `${fieldPath}.type`, "unknown-entity-field-type", `"${field.type}" is not an entity field type`, ENTITY_FIELD_TYPES);
|
|
12722
13529
|
continue;
|
|
12723
13530
|
}
|
|
12724
|
-
if (
|
|
12725
|
-
if (typeof
|
|
13531
|
+
if (field.type === "ref") {
|
|
13532
|
+
if (typeof field.entity !== "string" || !field.entity) {
|
|
12726
13533
|
push(errors, fieldPath, "invalid-value", `a ref field names its target: {type: 'ref', entity: '<key>'}`);
|
|
12727
13534
|
} else {
|
|
12728
|
-
checkEntityRef(errors, `${fieldPath}.entity`,
|
|
13535
|
+
checkEntityRef(errors, `${fieldPath}.entity`, field.entity);
|
|
12729
13536
|
}
|
|
12730
13537
|
}
|
|
12731
13538
|
}
|
|
@@ -12856,10 +13663,10 @@ function validatePromotionsSection(errors, section) {
|
|
|
12856
13663
|
if (method.allocation !== void 0 && !APPLICATION_METHOD_ALLOCATIONS.includes(method.allocation)) {
|
|
12857
13664
|
push(errors, `${methodPath}.allocation`, "invalid-value", `"${String(method.allocation)}" is not an allocation`, APPLICATION_METHOD_ALLOCATIONS);
|
|
12858
13665
|
}
|
|
12859
|
-
for (const
|
|
12860
|
-
const value = method[
|
|
13666
|
+
for (const field of ["maxQuantity", "applyToQuantity", "buyRulesMinQuantity"]) {
|
|
13667
|
+
const value = method[field];
|
|
12861
13668
|
if (value !== void 0 && value !== null && (typeof value !== "number" || value < 1)) {
|
|
12862
|
-
push(errors, `${methodPath}.${
|
|
13669
|
+
push(errors, `${methodPath}.${field}`, "invalid-value", `${field} is a positive integer when set`);
|
|
12863
13670
|
}
|
|
12864
13671
|
}
|
|
12865
13672
|
validateRuleList(errors, `${methodPath}.targetRules`, method.targetRules);
|
|
@@ -12876,8 +13683,8 @@ function validateHandleRef(errors, path, name) {
|
|
|
12876
13683
|
}
|
|
12877
13684
|
}
|
|
12878
13685
|
function validateCode(errors, section) {
|
|
12879
|
-
for (const
|
|
12880
|
-
if (section[
|
|
13686
|
+
for (const field of ["logo", "provider", "auth", "footerCredit"]) {
|
|
13687
|
+
if (section[field] !== void 0) validateHandleRef(errors, `code.${field}`, section[field]);
|
|
12881
13688
|
}
|
|
12882
13689
|
const components = section.components;
|
|
12883
13690
|
if (isRecord(components)) {
|
|
@@ -13294,6 +14101,6 @@ ${formatErrors(report.errors)}`;
|
|
|
13294
14101
|
return config;
|
|
13295
14102
|
}
|
|
13296
14103
|
|
|
13297
|
-
export { AddressSheet, AddressStrip, BEFORE_PLACE_ORDER_VALVE, BLOCK_STRUCTURAL_KEYS, BenefitsRow, BlockDataError, CART_LINE_ANNOTATION_POINT, CATALOG_BODY_BLOCK, CHECKOUT_FIELD_POINT, CartDrawer, CatalogPage, CategoryShowcase, CheckoutPage, ClosedStoreDialog, CollectionCta, CollectionHero, ContentPage, CountdownBand, EmailConfirmationRequiredError, EntityListBlock, FaqSection, FiltersPanel, FormBlock, HeroSection, ImageTiles, ItemSheet, Link, ManifestoBlock, MediaCarousel, MenuItemRow, MenuPage, MenuToolbar, MotifStrip, MyPurchasesPage, NewsletterBand, ORDER_METADATA_POINT, OrderConfirmationPage, OrderTrackingTimeline, PAGE_DATA_SCRIPT_ID, PLACEHOLDER_ASPECTS, PRODUCT_BODY_BLOCK, PRODUCT_CARD_BADGE_POINT, PageDataScope, PaymentTerms, Price, ProductCard, ProductDetailPage, ProductEnquiryForm, ProductGallery, ProductGrid, ProductOptionSelector, ProductRail, ProductReviews, ProductSlider, ProductSpecs, ProductSpotlight, PromoBanner, QuantityInput, Reveal, STOREFRONT_COMPONENT_KEYS, STOREFRONT_PAGE_KINDS, STOREFRONT_SLOTS, STORE_BACKEND_PROVIDERS, STORE_COMMERCE_MODES, STORE_DOCUMENT_KIND, STORE_PAYMENT_METHOD_KINDS, STORE_PAYMENT_MODES, STORE_ROUTE_CHROMES, STORE_ROUTE_KINDS, STORE_SECTIONS, STORE_SECTION_NAMES, ScheduleSheet, SealsBand, SearchOverlay, ServiceHoursModal, Slot, SmoothImage, StepsSection, StoreCover, StorefrontConfigHost, StorefrontConfigProvider, StorefrontFooter, StorefrontHeader, StorefrontPage, StorefrontRouterProvider, StorefrontShell, StorefrontThemeStyle, StoryQuote, THEME_SCALE_FIELDS, THEME_SCALE_VAR_PREFIX, TID, Testimonials, TierCards, applyStoreSettings, bannerPlaceholder, blockInstanceId, buildEnquiryFromForm, checkPageBlocks, collectDataNeeds, collectOrderMetadata, contentPagePath, createStorefront, createStorefrontApp, currentStaticRenderPass, defaultPageBlocks, entityListBlockMeta, establishCustomerSession, exportStore, formatMoney, formatProductOptionSelection, getCartLineAnnotations, getCheckoutFieldContributions, getCustomerAuthAdapter, getProductCardBadges, getProductOptionGroups, hydrateStoreDocument, hydratedEntriesFor, initStorefrontRuntime, isJsonValue, isKnownPath, isNestedBlockRef, isPublicPath, isRecord, listSlots, matchContentPage, matchPath, matchesFacets, mergeCollectionFacet, mergePageTheme, navigateTo, nextMilestone, normalizeProductOptionSelection, orderGalleryImages, overrideComponent, overrideProps, pageSeo, pageThemeSelector, pickProductCardImage, placeStorefrontOrder, prefersReducedMotion, primaryImageUrl, productCardComponentContract, productJsonLd, productOptionSelectionKey, productPlaceholder, productSeo, readHydratedPageData, registerStorefrontBlocks, registerStorefrontEntities, registerStorefrontExtensionPoints, registerStorefrontLoaders, resetPageDiagnostics, resetProductOptionsDeprecationWarnings, resetStorefrontExtensionPoints, resolveAuthAdapter, resolveConfig, resolveDataParams, resolveOverride, resolvePageData, resolvePageDataNeed, resolvePaymentTerms, resolveStorefrontProvider, resolveStorefrontRoute, resolveVariantForSelection, roundCents, routePathParams, runBeforePlaceOrderValve, sectionToJsonSchema, sectionsToBlocks, selectCount, selectDiscountTotal, selectIsOpen, selectRequiresShipping, selectShipping, selectShowsHours, selectSubtotal, selectTotal, selectionPrice, serializePageData, shellRouterAdapter, signInByEmail, signOutCustomer, signUpCustomer, slugifyStoreName, storefrontComponentContracts, storefrontPaths, themeToCss, toBlockNodes, toFacetMap, useBlockData, useCartStore, useCatalogStore, useCategories, useDeliveryStore, useDiscountValidator, useEnquiry, useHashPath, useInView, useLoader, useMyOrders, useNavigate, usePopOnChange, useProduct, useProducts, useRoutePath, useRouterAdapter, useScrollToTopOnNavigate, useScrolled, useServiceStore, useSessionStore, useSlotContext, useStorefrontActions, useStorefrontConfig, useStorefrontConfigOptional, useStorefrontHead, useStorefrontPage, useStorefrontPageOptional, usedSlots, validateStore, withFacet, withStaticRenderPass };
|
|
13298
|
-
//# sourceMappingURL=chunk-
|
|
13299
|
-
//# sourceMappingURL=chunk-
|
|
14104
|
+
export { AddressForm, AddressSheet, AddressStrip, BEFORE_PLACE_ORDER_VALVE, BLOCK_STRUCTURAL_KEYS, BUYER_COUNTRY_COOKIE, BenefitsRow, BlockDataError, CART_LINE_ANNOTATION_POINT, CATALOG_BODY_BLOCK, CHECKOUT_FIELD_POINT, CartDrawer, CatalogPage, CategoryShowcase, CheckoutPage, ClosedStoreDialog, CollectionCta, CollectionHero, ContentPage, CountdownBand, CountrySelect, DeliverToPicker, EmailConfirmationRequiredError, EntityListBlock, FaqSection, FiltersPanel, FormBlock, HeroSection, ImageTiles, ItemSheet, Link, MESSAGES, ManifestoBlock, MediaCarousel, MenuItemRow, MenuPage, MenuToolbar, MotifStrip, MyPurchasesPage, NewsletterBand, ORDER_METADATA_POINT, OrderConfirmationPage, OrderTrackingTimeline, PAGE_DATA_SCRIPT_ID, PLACEHOLDER_ASPECTS, PRODUCT_BODY_BLOCK, PRODUCT_CARD_BADGE_POINT, PageDataScope, PaymentTerms, Price, ProductCard, ProductDetailPage, ProductEnquiryForm, ProductGallery, ProductGrid, ProductOptionSelector, ProductRail, ProductReviews, ProductSlider, ProductSpecs, ProductSpotlight, PromoBanner, QuantityInput, Reveal, STOREFRONT_COMPONENT_KEYS, STOREFRONT_PAGE_KINDS, STOREFRONT_SLOTS, STORE_BACKEND_PROVIDERS, STORE_COMMERCE_MODES, STORE_DOCUMENT_KIND, STORE_PAYMENT_METHOD_KINDS, STORE_PAYMENT_MODES, STORE_ROUTE_CHROMES, STORE_ROUTE_KINDS, STORE_SECTIONS, STORE_SECTION_NAMES, ScheduleSheet, SealsBand, SearchOverlay, ServiceHoursModal, Slot, SmoothImage, StepsSection, StoreCover, StorefrontConfigHost, StorefrontConfigProvider, StorefrontFooter, StorefrontHeader, StorefrontPage, StorefrontRouterProvider, StorefrontShell, StorefrontThemeStyle, StoryQuote, THEME_SCALE_FIELDS, THEME_SCALE_VAR_PREFIX, TID, Testimonials, TierCards, applyStoreSettings, bannerPlaceholder, blockInstanceId, buildEnquiryFromForm, checkPageBlocks, collectDataNeeds, collectOrderMetadata, contentPagePath, createStorefront, createStorefrontApp, currentStaticRenderPass, defaultPageBlocks, entityListBlockMeta, establishCustomerSession, exportStore, formatMoney, formatProductOptionSelection, getCartLineAnnotations, getCheckoutFieldContributions, getCustomerAuthAdapter, getProductCardBadges, getProductOptionGroups, hydrateStoreDocument, hydratedEntriesFor, initStorefrontRuntime, isJsonValue, isKnownPath, isNestedBlockRef, isPublicPath, isRecord, listSlots, marketForCountry, marketUnitPrice, matchContentPage, matchPath, matchesFacets, mergeCollectionFacet, mergePageTheme, navigateTo, nextMilestone, normalizeLanguage, normalizeProductOptionSelection, orderGalleryImages, overrideComponent, overrideProps, pageSeo, pageThemeSelector, pickProductCardImage, placeStorefrontOrder, prefersReducedMotion, primaryImageUrl, productCardComponentContract, productJsonLd, productOptionSelectionKey, productPlaceholder, productSeo, readHydratedPageData, registerStorefrontBlocks, registerStorefrontEntities, registerStorefrontExtensionPoints, registerStorefrontLoaders, resetPageDiagnostics, resetProductOptionsDeprecationWarnings, resetStorefrontExtensionPoints, resolveAuthAdapter, resolveConfig, resolveDataParams, resolveOverride, resolvePageData, resolvePageDataNeed, resolvePaymentTerms, resolveStorefrontProvider, resolveStorefrontRoute, resolveVariantForSelection, roundCents, routePathParams, runBeforePlaceOrderValve, sectionToJsonSchema, sectionsToBlocks, selectCount, selectDiscountTotal, selectIsOpen, selectRequiresShipping, selectShipping, selectShowsHours, selectSubtotal, selectTotal, selectionPrice, serializePageData, shellRouterAdapter, signInByEmail, signOutCustomer, signUpCustomer, slugifyStoreName, storefrontComponentContracts, storefrontPaths, themeToCss, toBlockNodes, toFacetMap, translate, useBlockData, useBuyerCountry, useBuyerStore, useCartStore, useCatalogStore, useCategories, useDeliveryStore, useDiscountValidator, useEnquiry, useHashPath, useInView, useLoader, useMarketProduct, useMarketStore, useMyOrders, useNavigate, usePopOnChange, useProduct, useProducts, useRoutePath, useRouterAdapter, useScrollToTopOnNavigate, useScrolled, useServiceStore, useSessionStore, useSlotContext, useStorefrontActions, useStorefrontConfig, useStorefrontConfigOptional, useStorefrontHead, useStorefrontPage, useStorefrontPageOptional, useT, usedSlots, validateStore, withFacet, withMarketPrice, withStaticRenderPass };
|
|
14105
|
+
//# sourceMappingURL=chunk-DK3KK373.js.map
|
|
14106
|
+
//# sourceMappingURL=chunk-DK3KK373.js.map
|