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