@ecomiq/storefront 3.1.1 → 3.3.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.
Files changed (84) hide show
  1. package/README.md +17 -0
  2. package/dist/{account-CZZ-ku6L.js → account-DMM0ZZYb.js} +25 -8
  3. package/dist/account.d.ts +1 -0
  4. package/dist/{address-defaults-BqjRhS82.js → address-defaults-Bj8j8noq.js} +2 -1
  5. package/dist/address-defaults.d.ts +1 -0
  6. package/dist/analytics/{config-DN5B1GOG.js → config-rY3DYQyP.js} +1 -1
  7. package/dist/{bank-accounts-MpKIxHaX.js → bank-accounts-CktJ_34-.js} +1 -1
  8. package/dist/buyer-rules-DBhUoaZX.js +20 -0
  9. package/dist/buyer-rules.d.ts +13 -0
  10. package/dist/{captcha-CZkpghTO.js → captcha-BgiQrAfa.js} +1 -1
  11. package/dist/{cart-actions-IKRYGqfj.js → cart-actions-C2Csh1k0.js} +1 -1
  12. package/dist/{catalog-hooks-DjmpXROv.js → catalog-hooks-Dk_58L_I.js} +1 -1
  13. package/dist/{checkout-DsI1MY14.js → checkout-DnfQ8WhP.js} +29 -14
  14. package/dist/{complaint-book-aAQfGBvo.js → complaint-book-DvxhgbsM.js} +11 -6
  15. package/dist/{culqi-authentication-DHxjPJRE.js → culqi-authentication-CThvkZYc.js} +1 -1
  16. package/dist/{customer-document-fields-BzLdztjM.js → customer-document-fields-CkydNlq2.js} +2 -2
  17. package/dist/{customer-login-form-k_q7_7FX.js → customer-login-form-CnXH_JcT.js} +2 -2
  18. package/dist/{customer-registration-form-PrBqUuI9.js → customer-registration-form-CwwytTsq.js} +10 -2
  19. package/dist/{documents-T1mzc_j8.js → documents-Ka-EL9m0.js} +29 -1
  20. package/dist/entries/account.js +5 -5
  21. package/dist/entries/analytics.js +1 -1
  22. package/dist/entries/cart.js +2 -2
  23. package/dist/entries/checkout.d.ts +4 -1
  24. package/dist/entries/checkout.js +11 -8
  25. package/dist/entries/order.js +7 -7
  26. package/dist/index.d.ts +3 -2
  27. package/dist/index.js +32 -31
  28. package/dist/{invoice-fields-BzDfV1nR.js → invoice-fields-BPRnSo_s.js} +3 -3
  29. package/dist/{mercadopago-dialog-CpGlgKBl.js → mercadopago-dialog-C8pRoGAB.js} +2 -2
  30. package/dist/{order-display-CUXVESaF.js → order-display-CK-5wCsa.js} +1 -1
  31. package/dist/{order-draft-D8sqUUNp.js → order-draft-XI7gDVeO.js} +1 -1
  32. package/dist/{order-payment-continuation-CS6omD7E.js → order-payment-continuation-DEGeYVyv.js} +3 -3
  33. package/dist/{order-payment-in-review-D5Y8bjGA.js → order-payment-in-review-D81gcAOe.js} +1 -1
  34. package/dist/{order-status-QsmEO-89.js → order-status-C61ywW-E.js} +2 -2
  35. package/dist/{page-seo-BKG-Ta6t.js → page-seo-BdyKwykI.js} +3 -3
  36. package/dist/{pages-DyItxkdE.js → pages-ClOPuk55.js} +3 -3
  37. package/dist/{payment-dialog-frame-xtidt_eM.js → payment-dialog-frame-C2n--N7s.js} +1 -1
  38. package/dist/{personalization-fields-CwBR8oGr.js → personalization-fields-BtNqpVpB.js} +1 -1
  39. package/dist/phone-B350moyr.js +13 -0
  40. package/dist/phone-field-D4io3zeV.js +141 -0
  41. package/dist/phone-field.d.ts +44 -0
  42. package/dist/phone.d.ts +2 -0
  43. package/dist/{preview-JWdMO6kX.js → preview-GypCcfup.js} +2 -2
  44. package/dist/{preview-address-bvieGEKb.js → preview-address-BobkvMlP.js} +1 -1
  45. package/dist/{preview-cart-COIP3Vfh.js → preview-cart-CRSPTs6g.js} +1 -1
  46. package/dist/{public-pages-Byh01h-6.js → public-pages-BZXH5gt9.js} +2 -2
  47. package/dist/{registration-h_00PAhj.js → registration-BmWt3-eT.js} +9 -4
  48. package/dist/registration.d.ts +1 -0
  49. package/dist/{route-text-B6pWdevi.js → route-text-CkupKB1b.js} +1 -1
  50. package/dist/{section-preview-BiYfeE-d.js → section-preview-C7QbWAzE.js} +2 -2
  51. package/dist/sections/account-addresses.js +20 -9
  52. package/dist/sections/account-order.js +4 -4
  53. package/dist/sections/account-orders.js +3 -3
  54. package/dist/sections/account-profile.d.ts +1 -0
  55. package/dist/sections/account-profile.js +21 -11
  56. package/dist/sections/checkout.js +63 -26
  57. package/dist/sections/complaint-book.js +39 -18
  58. package/dist/sections/design-system.js +1 -1
  59. package/dist/sections/draft-invoice.js +3 -3
  60. package/dist/sections/order-tracking.js +1 -1
  61. package/dist/{sections-CgpjubkB.js → sections-BkjGSM28.js} +1 -1
  62. package/dist/{seo-D9UdUMg9.js → seo-Cz1O5oxh.js} +2 -2
  63. package/dist/{session-DR_9-bcf.js → session-CsuzPSJs.js} +6 -6
  64. package/dist/{settings-B0NO2A6Y.js → settings-CiW3OroM.js} +20 -14
  65. package/dist/settings.d.ts +2 -1
  66. package/dist/{store-uU2gWdMY.js → store-BGDvRGNS.js} +14 -6
  67. package/dist/store.d.ts +8 -4
  68. package/dist/{storefront-language-Bnt-TU2F.js → storefront-language-20hJejSi.js} +5 -2
  69. package/dist/{storefront-text-Co7iUnLM.js → storefront-text-ClFfYMVk.js} +2 -2
  70. package/dist/{storefront-text-en-DzYmdOuY.js → storefront-text-en-DTTFnk6W.js} +8 -0
  71. package/dist/{storefront-text-pt-CizClH0I.js → storefront-text-pt-DuXQ0rti.js} +8 -0
  72. package/dist/{stripe-dialog-D88qfkUS.js → stripe-dialog-vlflY1WI.js} +2 -2
  73. package/dist/{telemetry-HuZXWBPi.js → telemetry-k9sM5iBG.js} +3 -0
  74. package/dist/{templates-AgGupnPA.js → templates-BM3WvMlA.js} +2 -2
  75. package/dist/{urls-D4uinJVd.js → urls-BR4wv2K2.js} +1 -1
  76. package/dist/{use-checkout-Jdk8P12A.js → use-checkout-BmVOLp_x.js} +1 -1
  77. package/dist/{use-checkout-payment-BGX-BE6D.js → use-checkout-payment-C2t511ck.js} +1 -1
  78. package/dist/{voucher-payment-B3o9ybg6.js → voucher-payment-Cbq4DRiL.js} +1 -1
  79. package/dist/{worker-cbXmLvfR.js → worker-BxlCSjSF.js} +3 -3
  80. package/package.json +4 -2
  81. package/src/sections/account-addresses.tsx +11 -7
  82. package/src/sections/account-profile.tsx +12 -7
  83. package/src/sections/checkout.tsx +45 -9
  84. package/src/sections/complaint-book.tsx +15 -4
@@ -6,6 +6,7 @@ import { CustomerMe } from "@ecomiq/core";
6
6
  export declare const catalog: SectionCatalog;
7
7
  export declare function AccountProfile({ loaderData, actionData }: {
8
8
  loaderData: {
9
+ countryCode: string;
9
10
  me: CustomerMe;
10
11
  countries: {
11
12
  code: string;
@@ -1,5 +1,6 @@
1
- import { useStorefrontText } from "../storefront-language-Bnt-TU2F.js";
2
- import { CustomerDocumentFields } from "../customer-document-fields-BzLdztjM.js";
1
+ import { PhoneField } from "../phone-field-D4io3zeV.js";
2
+ import { useStorefrontText } from "../storefront-language-20hJejSi.js";
3
+ import { CustomerDocumentFields } from "../customer-document-fields-CkydNlq2.js";
3
4
  import { ProfileForm } from "../account-forms-AVk71ko7.js";
4
5
  import { useNavigation } from "react-router";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -26,9 +27,15 @@ function Labeled({ label, hint, className = "", children }) {
26
27
  ]
27
28
  });
28
29
  }
30
+ function PhoneInputBox(props) {
31
+ return /* @__PURE__ */ jsx(Input, {
32
+ ...props,
33
+ className: "min-w-0 flex-1 rounded-s-none"
34
+ });
35
+ }
29
36
  function AccountProfile({ loaderData, actionData }) {
30
37
  const storefrontTranslate = useStorefrontText();
31
- const { me, countries } = loaderData;
38
+ const { me, countries, countryCode } = loaderData;
32
39
  const busy = useNavigation().state !== "idle";
33
40
  return /* @__PURE__ */ jsxs("div", {
34
41
  className: "flex flex-col gap-6",
@@ -74,14 +81,17 @@ function AccountProfile({ loaderData, actionData }) {
74
81
  maxLength: 100
75
82
  })
76
83
  }),
77
- /* @__PURE__ */ jsx(Labeled, {
78
- label: storefrontTranslate("Celular"),
79
- children: /* @__PURE__ */ jsx(Input, {
80
- name: "phone",
81
- type: "tel",
82
- autoComplete: "tel",
83
- defaultValue: me.phone ?? ""
84
- })
84
+ /* @__PURE__ */ jsxs("div", {
85
+ className: "flex flex-col gap-1.5 text-sm",
86
+ children: [/* @__PURE__ */ jsx("label", {
87
+ htmlFor: "phone",
88
+ className: "font-medium",
89
+ children: storefrontTranslate("Celular")
90
+ }), /* @__PURE__ */ jsx(PhoneField, {
91
+ countryCode,
92
+ initial: me.phone ?? "",
93
+ inputComponent: PhoneInputBox
94
+ })]
85
95
  }),
86
96
  /* @__PURE__ */ jsxs("div", {
87
97
  className: "flex flex-col gap-1.5 text-sm",
@@ -1,19 +1,21 @@
1
- import { BankAccountList } from "../bank-accounts-MpKIxHaX.js";
2
- import { useStorefrontText } from "../storefront-language-Bnt-TU2F.js";
1
+ import { BankAccountList } from "../bank-accounts-CktJ_34-.js";
2
+ import { useStorefrontText } from "../storefront-language-20hJejSi.js";
3
3
  import { PaymentLogo } from "../payment-logo-BoPaGJc_.js";
4
4
  import { money } from "../money-DtGOtDri.js";
5
- import { section, setting } from "../settings-B0NO2A6Y.js";
6
- import { placeValue, useGeoCascade } from "../catalog-hooks-DjmpXROv.js";
5
+ import { section, setting } from "../settings-CiW3OroM.js";
6
+ import { placeValue, useGeoCascade } from "../catalog-hooks-Dk_58L_I.js";
7
+ import { EMAIL_ERROR, EMAIL_PATTERN } from "../buyer-rules-DBhUoaZX.js";
7
8
  import { CheckoutForm, OrderBumpForm, PromoCodeForm } from "../checkout-form-CbOIdENC.js";
8
- import { CulqiAuthentication } from "../culqi-authentication-DHxjPJRE.js";
9
- import { InvoiceFields } from "../invoice-fields-BzDfV1nR.js";
10
- import { MercadoPagoDialog } from "../mercadopago-dialog-CpGlgKBl.js";
9
+ import { CulqiAuthentication } from "../culqi-authentication-CThvkZYc.js";
10
+ import { InvoiceFields } from "../invoice-fields-BPRnSo_s.js";
11
+ import { MercadoPagoDialog } from "../mercadopago-dialog-C8pRoGAB.js";
11
12
  import { PaymentMethods } from "../payment-methods-B8ocTgFZ.js";
12
- import { StripeAuthentication, StripeDialog, findStripeWallet, useAvailableStripeWallets } from "../stripe-dialog-D88qfkUS.js";
13
+ import { PhoneField } from "../phone-field-D4io3zeV.js";
14
+ import { StripeAuthentication, StripeDialog, findStripeWallet, useAvailableStripeWallets } from "../stripe-dialog-vlflY1WI.js";
13
15
  import { summaryLines } from "../cart-summary-B6vtRGBO.js";
14
- import { useCheckout } from "../use-checkout-Jdk8P12A.js";
15
- import { useCheckoutPayment } from "../use-checkout-payment-BGX-BE6D.js";
16
- import { ItemPersonalization } from "../personalization-fields-CwBR8oGr.js";
16
+ import { useCheckout } from "../use-checkout-BmVOLp_x.js";
17
+ import { useCheckoutPayment } from "../use-checkout-payment-C2t511ck.js";
18
+ import { ItemPersonalization } from "../personalization-fields-BtNqpVpB.js";
17
19
  import { Link, useRouteLoaderData } from "react-router";
18
20
  import { lineTotal } from "@ecomiq/core";
19
21
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -132,6 +134,31 @@ function Field({ label, className, ...props }) {
132
134
  })]
133
135
  });
134
136
  }
137
+ function PhoneInputBox({ className, ...props }) {
138
+ const label = useStorefrontText()("Celular");
139
+ return /* @__PURE__ */ jsxs("label", {
140
+ className: `relative block flex-1 ${className ?? ""}`,
141
+ children: [/* @__PURE__ */ jsx("input", {
142
+ placeholder: label,
143
+ className: `${FIELD} rounded-s-none`,
144
+ ...props
145
+ }), /* @__PURE__ */ jsx("span", {
146
+ className: FLOAT,
147
+ children: label
148
+ })]
149
+ });
150
+ }
151
+ function CheckoutPhoneField({ countryCode, initial, className }) {
152
+ return /* @__PURE__ */ jsx(PhoneField, {
153
+ countryCode,
154
+ initial,
155
+ required: true,
156
+ className,
157
+ inputComponent: PhoneInputBox,
158
+ selectClassName: "rounded-s-md border border-e-0 border-input bg-background px-3 text-foreground focus-within:border-ring focus-within:ring-1 focus-within:ring-ring group-data-[fields=filled]/checkout:border-transparent group-data-[fields=filled]/checkout:bg-muted",
159
+ errorClassName: "text-sm text-destructive sm:col-span-2"
160
+ });
161
+ }
135
162
  function Choice({ label, className, children, ...props }) {
136
163
  return /* @__PURE__ */ jsxs("label", {
137
164
  className: `relative block ${className ?? ""}`,
@@ -229,11 +256,13 @@ function Address({ countries, defaults }) {
229
256
  label: storefrontTranslate("Región"),
230
257
  name: "department",
231
258
  defaultValue: defaults.department ?? "",
259
+ maxLength: 200,
232
260
  required: true
233
261
  }), /* @__PURE__ */ jsx(Field, {
234
262
  label: storefrontTranslate("Ciudad"),
235
263
  name: "district",
236
264
  defaultValue: defaults.district ?? "",
265
+ maxLength: 200,
237
266
  required: true
238
267
  })] }),
239
268
  /* @__PURE__ */ jsx(Field, {
@@ -241,21 +270,28 @@ function Address({ countries, defaults }) {
241
270
  name: "line",
242
271
  autoComplete: "street-address",
243
272
  defaultValue: defaults.line ?? "",
273
+ minLength: 3,
274
+ maxLength: 200,
244
275
  required: true,
245
276
  className: "sm:col-span-2"
246
277
  }),
247
278
  /* @__PURE__ */ jsx(Field, {
248
279
  label: storefrontTranslate("Referencia (opcional)"),
249
280
  name: "reference",
250
- defaultValue: defaults.reference ?? ""
281
+ defaultValue: defaults.reference ?? "",
282
+ maxLength: 500
251
283
  }),
252
- /* @__PURE__ */ jsx(Field, {
253
- label: storefrontTranslate("Celular"),
254
- name: "phone",
255
- type: "tel",
256
- autoComplete: "tel",
257
- defaultValue: defaults.phone ?? "",
258
- required: true
284
+ geo.structured ? null : /* @__PURE__ */ jsx(Field, {
285
+ label: storefrontTranslate("Código postal (opcional)"),
286
+ name: "postalCode",
287
+ autoComplete: "postal-code",
288
+ defaultValue: defaults.postalCode ?? "",
289
+ maxLength: 20
290
+ }),
291
+ /* @__PURE__ */ jsx(CheckoutPhoneField, {
292
+ countryCode: country,
293
+ initial: defaults.phone ?? "",
294
+ className: geo.structured ? "" : "sm:col-span-2"
259
295
  })
260
296
  ]
261
297
  });
@@ -586,6 +622,9 @@ function Checkout({ data, result, ...root }) {
586
622
  type: "email",
587
623
  autoComplete: "email",
588
624
  defaultValue: cart.email ?? me?.email ?? "",
625
+ pattern: EMAIL_PATTERN,
626
+ title: storefrontTranslate(EMAIL_ERROR),
627
+ maxLength: 200,
589
628
  required: true,
590
629
  className: "sm:col-span-2"
591
630
  }),
@@ -594,6 +633,7 @@ function Checkout({ data, result, ...root }) {
594
633
  name: "firstName",
595
634
  autoComplete: "given-name",
596
635
  defaultValue: cart.firstName ?? me?.firstName ?? "",
636
+ maxLength: 100,
597
637
  required: true
598
638
  }),
599
639
  /* @__PURE__ */ jsx(Field, {
@@ -601,15 +641,12 @@ function Checkout({ data, result, ...root }) {
601
641
  name: "lastName",
602
642
  autoComplete: "family-name",
603
643
  defaultValue: cart.lastName ?? me?.lastName ?? "",
644
+ maxLength: 100,
604
645
  required: true
605
646
  }),
606
- /* @__PURE__ */ jsx(Field, {
607
- label: storefrontTranslate("Celular"),
608
- name: "phone",
609
- type: "tel",
610
- autoComplete: "tel",
611
- defaultValue: cart.phone ?? me?.phone ?? "",
612
- required: true,
647
+ /* @__PURE__ */ jsx(CheckoutPhoneField, {
648
+ countryCode: data.countryCode,
649
+ initial: cart.phone ?? me?.phone ?? "",
613
650
  className: "sm:col-span-2"
614
651
  }),
615
652
  /* @__PURE__ */ jsx(InvoiceFields, {
@@ -1,9 +1,10 @@
1
- import { Captcha } from "../captcha-CZkpghTO.js";
2
- import { COMPLAINT_DOCUMENT_TYPES, identityDocumentRule } from "../documents-T1mzc_j8.js";
3
- import { useStorefrontText } from "../storefront-language-Bnt-TU2F.js";
4
- import { complaintBookAttachmentError, complaintBookNumber } from "../complaint-book-aAQfGBvo.js";
1
+ import { Captcha } from "../captcha-BgiQrAfa.js";
2
+ import { COMPLAINT_DOCUMENT_TYPES, identityDocumentRule } from "../documents-Ka-EL9m0.js";
3
+ import { useStorefrontText } from "../storefront-language-20hJejSi.js";
4
+ import { complaintBookAttachmentError, complaintBookNumber } from "../complaint-book-DvxhgbsM.js";
5
5
  import { CustomerCsrfField } from "../customer-csrf-C1oDX-Py.js";
6
6
  import { money } from "../money-DtGOtDri.js";
7
+ import { PhoneField } from "../phone-field-D4io3zeV.js";
7
8
  import { Form, useNavigation } from "react-router";
8
9
  import { COMPLAINT_BOOK_ATTACHMENT_TYPES, formatOrderDate } from "@ecomiq/core";
9
10
  import { Fragment, useRef, useState } from "react";
@@ -68,6 +69,12 @@ function providerRows(book) {
68
69
  ["Dirección", book.providerAddress]
69
70
  ];
70
71
  }
72
+ function PhoneInputBox(props) {
73
+ return /* @__PURE__ */ jsx(Input, {
74
+ ...props,
75
+ className: "min-w-0 flex-1 rounded-s-none"
76
+ });
77
+ }
71
78
  function Field({ label, name, className, ...props }) {
72
79
  return /* @__PURE__ */ jsxs("div", {
73
80
  className: `flex flex-col gap-2 ${className ?? ""}`,
@@ -178,7 +185,7 @@ function Attachments() {
178
185
  ]
179
186
  });
180
187
  }
181
- function ComplaintForm({ book, error, countries }) {
188
+ function ComplaintForm({ book, error, countries, storeCountry }) {
182
189
  const storefrontTranslate = useStorefrontText();
183
190
  const busy = useNavigation().state !== "idle";
184
191
  const [kind, setKind] = useState("nationalId");
@@ -271,13 +278,19 @@ function ComplaintForm({ book, error, countries }) {
271
278
  required: true,
272
279
  className: "sm:col-span-2"
273
280
  }),
274
- /* @__PURE__ */ jsx(Field, {
275
- label: storefrontTranslate("Celular"),
276
- name: "consumerPhone",
277
- type: "tel",
278
- autoComplete: "tel",
279
- maxLength: 30,
280
- required: true
281
+ /* @__PURE__ */ jsxs("div", {
282
+ className: "flex flex-col gap-2",
283
+ children: [/* @__PURE__ */ jsx(Label, {
284
+ htmlFor: "complaint-consumerPhone",
285
+ children: storefrontTranslate("Celular")
286
+ }), /* @__PURE__ */ jsx(PhoneField, {
287
+ countryCode: storeCountry,
288
+ initial: "",
289
+ name: "consumerPhone",
290
+ id: "complaint-consumerPhone",
291
+ required: true,
292
+ inputComponent: PhoneInputBox
293
+ })]
281
294
  }),
282
295
  /* @__PURE__ */ jsx(Field, {
283
296
  label: storefrontTranslate("Correo"),
@@ -322,12 +335,19 @@ function ComplaintForm({ book, error, countries }) {
322
335
  required: true,
323
336
  className: "sm:col-span-2"
324
337
  }),
325
- /* @__PURE__ */ jsx(Field, {
326
- label: storefrontTranslate("Celular"),
327
- name: "guardianPhone",
328
- type: "tel",
329
- maxLength: 30,
330
- required: true
338
+ /* @__PURE__ */ jsxs("div", {
339
+ className: "flex flex-col gap-2",
340
+ children: [/* @__PURE__ */ jsx(Label, {
341
+ htmlFor: "complaint-guardianPhone",
342
+ children: storefrontTranslate("Celular")
343
+ }), /* @__PURE__ */ jsx(PhoneField, {
344
+ countryCode: storeCountry,
345
+ initial: "",
346
+ name: "guardianPhone",
347
+ id: "complaint-guardianPhone",
348
+ required: true,
349
+ inputComponent: PhoneInputBox
350
+ })]
331
351
  }),
332
352
  /* @__PURE__ */ jsx(Field, {
333
353
  label: storefrontTranslate("Correo"),
@@ -529,6 +549,7 @@ function ComplaintBook({ loaderData, actionData, ...root }) {
529
549
  title: storefrontTranslate("Proveedor"),
530
550
  rows: providerRows(book)
531
551
  }), /* @__PURE__ */ jsx(ComplaintForm, {
552
+ storeCountry: loaderData.countryCode,
532
553
  countries: loaderData.countries,
533
554
  book,
534
555
  error
@@ -1,4 +1,4 @@
1
- import { useStorefrontText } from "../storefront-language-Bnt-TU2F.js";
1
+ import { useStorefrontText } from "../storefront-language-20hJejSi.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { Button } from "@theme/ui/button";
4
4
  import { Input } from "@theme/ui/input";
@@ -1,9 +1,9 @@
1
- import { useStorefrontText } from "../storefront-language-Bnt-TU2F.js";
1
+ import { useStorefrontText } from "../storefront-language-20hJejSi.js";
2
2
  import { CustomerCsrfField } from "../customer-csrf-C1oDX-Py.js";
3
3
  import { money } from "../money-DtGOtDri.js";
4
- import { setting } from "../settings-B0NO2A6Y.js";
4
+ import { setting } from "../settings-CiW3OroM.js";
5
5
  import { orderSummaryLines } from "../cart-summary-B6vtRGBO.js";
6
- import { ItemPersonalization } from "../personalization-fields-CwBR8oGr.js";
6
+ import { ItemPersonalization } from "../personalization-fields-BtNqpVpB.js";
7
7
  import { Form, Link, useNavigation } from "react-router";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { Button } from "@theme/ui/button";
@@ -1,4 +1,4 @@
1
- import { setting } from "../settings-B0NO2A6Y.js";
1
+ import { setting } from "../settings-CiW3OroM.js";
2
2
  import { Form } from "react-router";
3
3
  import { formatTrackingStatus } from "@ecomiq/core";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,5 +1,5 @@
1
1
  import "./source-marker-DhqSkW7n.js";
2
- import { store } from "./store-uU2gWdMY.js";
2
+ import { store } from "./store-BGDvRGNS.js";
3
3
  import { data, useLoaderData } from "react-router";
4
4
  import { Suspense, createElement, use } from "react";
5
5
  // src/sections.ts
@@ -1,5 +1,5 @@
1
- import { store } from "./store-uU2gWdMY.js";
2
- import { absoluteUrl, canonicalOrigin } from "./urls-D4uinJVd.js";
1
+ import { store } from "./store-BGDvRGNS.js";
2
+ import { absoluteUrl, canonicalOrigin } from "./urls-BR4wv2K2.js";
3
3
  // src/seo.ts
4
4
  const PRIVATE_PATHS = [
5
5
  "/cart",
@@ -1,12 +1,12 @@
1
- import { loadStorefrontTranslations, storefrontText } from "./storefront-text-Co7iUnLM.js";
2
- import { captchaResponse } from "./captcha-CZkpghTO.js";
1
+ import { loadStorefrontTranslations, storefrontText } from "./storefront-text-ClFfYMVk.js";
2
+ import { captchaResponse } from "./captcha-BgiQrAfa.js";
3
3
  import { base64Url, customerCookies, customerSessionId, equalSecret } from "./customer-cookies-DHOgFAMV.js";
4
4
  import { safeNext } from "./form-BtQcbXlJ.js";
5
- import { PREVIEW_TOKEN } from "./preview-JWdMO6kX.js";
5
+ import { PREVIEW_TOKEN } from "./preview-GypCcfup.js";
6
6
  import { customerClientHeaders, customerCsrfTokenForRequest, rejectCrossOriginAction } from "./request-security-CRsRMgwj.js";
7
- import { store } from "./store-uU2gWdMY.js";
8
- import { requestUrl } from "./urls-D4uinJVd.js";
9
- import { worker } from "./worker-cbXmLvfR.js";
7
+ import { store } from "./store-BGDvRGNS.js";
8
+ import { requestUrl } from "./urls-BR4wv2K2.js";
9
+ import { worker } from "./worker-BxlCSjSF.js";
10
10
  import { data, redirect } from "react-router";
11
11
  import { ApiError } from "@ecomiq/core";
12
12
  import { z } from "zod";
@@ -41,38 +41,44 @@ function section(defaults, props) {
41
41
  }
42
42
  return values;
43
43
  }
44
- async function pickProducts(client, source) {
44
+ function productSourceQuery(source) {
45
45
  const limit = source.limit ?? 8;
46
46
  if (source.products && source.products.length > 0) {
47
47
  const slugs = source.products.slice(0, limit);
48
- return (await client.getProducts({
48
+ return {
49
49
  slugs,
50
50
  pageSize: slugs.length,
51
51
  includeFilters: false
52
- })).products;
52
+ };
53
53
  }
54
54
  if (source.collection) {
55
- const collections = await client.getCollections().catch(() => []);
56
55
  const slug = source.collection.trim().toLowerCase();
57
- const collection = collections.find((item) => item.slug.toLowerCase() === slug);
58
- if (collection === void 0) return [];
59
- return (await client.getProducts({
60
- collectionId: collection.id,
56
+ if (slug === "") return null;
57
+ return {
58
+ collections: [slug],
61
59
  pageSize: limit,
62
60
  sort: source.sort,
63
61
  includeFilters: false
64
- })).products;
62
+ };
65
63
  }
66
- if (source.category) return (await client.getProducts({
64
+ if (source.category) return {
67
65
  categories: [source.category],
68
66
  pageSize: limit,
69
67
  sort: source.sort,
70
68
  includeFilters: false
71
- })).products;
72
- return (await client.getProducts({
69
+ };
70
+ return {
73
71
  pageSize: limit,
74
72
  sort: source.sort,
75
73
  includeFilters: false
76
- })).products;
74
+ };
75
+ }
76
+ async function pickProducts(client, source) {
77
+ const query = productSourceQuery(source);
78
+ return query === null ? [] : (await client.getProducts(query)).products;
79
+ }
80
+ async function pickProductsWithReviews(client, source, reviews = {}) {
81
+ const query = productSourceQuery(source);
82
+ return query === null ? [] : client.getProductsWithReviews(query, reviews);
77
83
  }
78
- export { pickProducts, section, setting };
84
+ export { pickProducts, pickProductsWithReviews, section, setting };
@@ -1,4 +1,4 @@
1
- import { CatalogLink, CatalogLinkReference, ProductSort, ProductSummary, StorefrontClient } from "@ecomiq/core";
1
+ import { CatalogLink, CatalogLinkReference, ProductReviewsOptions, ProductSort, ProductSummary, ProductWithReviews, StorefrontClient } from "@ecomiq/core";
2
2
  import { ComponentProps, ReactNode } from "react";
3
3
  declare function link(url: string, label?: string, reference?: null): string;
4
4
  declare function link(url: string, label: string | undefined, reference: CatalogLinkReference): CatalogLink;
@@ -48,4 +48,5 @@ export type ProductSource = {
48
48
  sort?: ProductSort;
49
49
  };
50
50
  export declare function pickProducts(client: StorefrontClient, source: ProductSource): Promise<ProductSummary[]>;
51
+ export declare function pickProductsWithReviews(client: StorefrontClient, source: ProductSource, reviews?: ProductReviewsOptions): Promise<ProductWithReviews[]>;
51
52
  export {};
@@ -1,8 +1,8 @@
1
1
  import { apiCacheFetch, uncachedFetch } from "./api-cache-DsuIn5hX.js";
2
- import { previewClient } from "./preview-JWdMO6kX.js";
2
+ import { previewClient } from "./preview-GypCcfup.js";
3
3
  import { productPreviewClient } from "./product-preview-BspMAecJ.js";
4
- import { observeStorefrontClient } from "./telemetry-HuZXWBPi.js";
5
- import { worker } from "./worker-cbXmLvfR.js";
4
+ import { observeStorefrontClient } from "./telemetry-k9sM5iBG.js";
5
+ import { worker } from "./worker-BxlCSjSF.js";
6
6
  import { data } from "react-router";
7
7
  import { ApiError, GraphQLResponseError, createClient } from "@ecomiq/core";
8
8
  import { z } from "zod";
@@ -13,6 +13,8 @@ const REQUEST_READS = /* @__PURE__ */ new Set([
13
13
  "getLayout",
14
14
  "getStoreId",
15
15
  "getCollections",
16
+ "getCollectionCovers",
17
+ "getCollectionsWithProducts",
16
18
  "getPaymentMethods",
17
19
  "getCollectionBySlug",
18
20
  "getPageBySlug",
@@ -24,6 +26,7 @@ const REQUEST_READS = /* @__PURE__ */ new Set([
24
26
  "getSellers",
25
27
  "getSellerBySlug",
26
28
  "getProducts",
29
+ "getProductsWithReviews",
27
30
  "getProductBySlug",
28
31
  "getRelatedProducts",
29
32
  "listProductReviews",
@@ -85,9 +88,14 @@ const CollectionImagesSchema = z.record(z.string(), z.object({ products: z.array
85
88
  async function collectionImageCandidates({ client, collections, pageSize }) {
86
89
  const missing = [...new Map(collections.filter((collection) => !collection.imageUrl).map((collection) => [collection.id, collection])).values()].sort((left, right) => left.id.localeCompare(right.id));
87
90
  const candidates = /* @__PURE__ */ new Map();
91
+ const pending = missing.filter((collection) => {
92
+ if (collection.imageCandidates === void 0) return true;
93
+ candidates.set(collection.id, collection.imageCandidates.slice(0, pageSize));
94
+ return false;
95
+ });
88
96
  const batches = [];
89
- for (let offset = 0; offset < missing.length; offset += 10) {
90
- const batch = missing.slice(offset, offset + 10);
97
+ for (let offset = 0; offset < pending.length; offset += 10) {
98
+ const batch = pending.slice(offset, offset + 10);
91
99
  const variables = Object.fromEntries(batch.map((collection, index) => [`c${index}`, {
92
100
  collectionId: collection.id,
93
101
  pageSize,
@@ -123,7 +131,7 @@ async function withImages(client, collections) {
123
131
  pageSize: 6
124
132
  });
125
133
  const used = /* @__PURE__ */ new Set();
126
- return collections.map((collection) => {
134
+ return collections.map(({ imageCandidates, ...collection }) => {
127
135
  const options = collection.imageUrl ? [collection.imageUrl] : candidates.get(collection.id) ?? [];
128
136
  const image = options.find((option) => !used.has(option)) ?? options[0] ?? null;
129
137
  if (image !== null) used.add(image);
package/dist/store.d.ts CHANGED
@@ -2,16 +2,20 @@ import { RouterContextProvider } from "react-router";
2
2
  import { Collection, StorefrontClient } from "@ecomiq/core";
3
3
  export declare function store(context: Readonly<RouterContextProvider>): StorefrontClient;
4
4
  export declare function found<T>(read: Promise<T>, missing?: (status: number) => boolean): Promise<T>;
5
+ type CoverableCollection = Collection & {
6
+ imageCandidates?: readonly string[];
7
+ };
5
8
  export declare function collectionImageCandidates({ client, collections, pageSize }: {
6
9
  client: StorefrontClient;
7
- collections: readonly Collection[];
10
+ collections: readonly CoverableCollection[];
8
11
  pageSize: number;
9
12
  }): Promise<ReadonlyMap<string, readonly string[]>>;
10
- export declare function withImages(client: StorefrontClient, collections: Collection[]): Promise<{
11
- collection: Collection;
13
+ export declare function withImages<T extends CoverableCollection>(client: StorefrontClient, collections: T[]): Promise<{
14
+ collection: Omit<T, "imageCandidates">;
12
15
  image: string | null;
13
16
  }[]>;
14
17
  export declare function readCountries(client: StorefrontClient): Promise<{
15
18
  code: string;
16
19
  name: string;
17
- }[]>;
20
+ }[]>;
21
+ export {};
@@ -1,4 +1,4 @@
1
- import { storefrontText } from "./storefront-text-Co7iUnLM.js";
1
+ import { storefrontText } from "./storefront-text-ClFfYMVk.js";
2
2
  import { createContext, useContext } from "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  // src/storefront-language.tsx
@@ -23,7 +23,10 @@ function useStorefrontText() {
23
23
  const { translations } = useContext(StorefrontLanguage);
24
24
  return (source, values) => storefrontText(translations, source, values);
25
25
  }
26
+ function useStorefrontLanguage() {
27
+ return useContext(StorefrontLanguage).language;
28
+ }
26
29
  function useStorefrontLocale() {
27
30
  return useContext(StorefrontLanguage);
28
31
  }
29
- export { StorefrontLanguageProvider, useStorefrontLocale, useStorefrontText };
32
+ export { StorefrontLanguageProvider, useStorefrontLanguage, useStorefrontLocale, useStorefrontText };
@@ -1,8 +1,8 @@
1
1
  // src/storefront-text.ts
2
2
  async function loadStorefrontTranslations(language) {
3
3
  const code = language.split("-")[0];
4
- if (code === "en") return (await import("./storefront-text-en-DzYmdOuY.js")).default;
5
- if (code === "pt") return (await import("./storefront-text-pt-CizClH0I.js")).default;
4
+ if (code === "en") return (await import("./storefront-text-en-DTTFnk6W.js")).default;
5
+ if (code === "pt") return (await import("./storefront-text-pt-DuXQ0rti.js")).default;
6
6
  return {};
7
7
  }
8
8
  function storefrontText(translations, source, values = {}) {
@@ -88,6 +88,14 @@ const translations = {
88
88
  "Revisa el documento del comprador.": "Check the buyer's document.",
89
89
  "La entrega debe ser dentro del país de la tienda.": "Delivery must be within the shop's country.",
90
90
  "Completa la dirección de entrega.": "Complete the delivery address.",
91
+ "Revisa tu celular: ese número no es válido para el país elegido.": "Check your mobile number: it isn't valid for the selected country.",
92
+ "País del celular": "Phone country",
93
+ "Revisa tu correo: debe verse como nombre@dominio.com.": "Check your email: it should look like name@domain.com.",
94
+ "Revisa tu nombre y apellidos.": "Check your first and last name.",
95
+ "Escribe la dirección completa, con calle y número.": "Enter the full address, with street and number.",
96
+ "Elige el departamento, la provincia y el distrito de la lista.": "Choose the department, province and district from the list.",
97
+ "Vuelve a subir el comprobante de pago.": "Upload the payment receipt again.",
98
+ "Código postal (opcional)": "Postal code (optional)",
91
99
  "Primero indica la dirección de entrega.": "Enter the delivery address first.",
92
100
  "Las opciones de envío cambiaron. Elige un método para cada paquete.": "Shipping options have changed. Choose a method for each package.",
93
101
  "Elige un medio de pago.": "Choose a payment method.",
@@ -88,6 +88,14 @@ const translations = {
88
88
  "Revisa el documento del comprador.": "Revise o documento do comprador.",
89
89
  "La entrega debe ser dentro del país de la tienda.": "A entrega deve ser dentro do país da loja.",
90
90
  "Completa la dirección de entrega.": "Preencha o endereço de entrega.",
91
+ "Revisa tu celular: ese número no es válido para el país elegido.": "Confira seu celular: esse número não é válido para o país escolhido.",
92
+ "País del celular": "País do celular",
93
+ "Revisa tu correo: debe verse como nombre@dominio.com.": "Confira seu e-mail: deve ser como nome@dominio.com.",
94
+ "Revisa tu nombre y apellidos.": "Confira seu nome e sobrenome.",
95
+ "Escribe la dirección completa, con calle y número.": "Escreva o endereço completo, com rua e número.",
96
+ "Elige el departamento, la provincia y el distrito de la lista.": "Escolha o departamento, a província e o distrito da lista.",
97
+ "Vuelve a subir el comprobante de pago.": "Envie o comprovante de pagamento novamente.",
98
+ "Código postal (opcional)": "CEP (opcional)",
91
99
  "Primero indica la dirección de entrega.": "Informe primeiro o endereço de entrega.",
92
100
  "Las opciones de envío cambiaron. Elige un método para cada paquete.": "As opções de frete mudaram. Escolha um método para cada pacote.",
93
101
  "Elige un medio de pago.": "Escolha um meio de pagamento.",
@@ -1,6 +1,6 @@
1
- import { useStorefrontLocale, useStorefrontText } from "./storefront-language-Bnt-TU2F.js";
1
+ import { useStorefrontLocale, useStorefrontText } from "./storefront-language-20hJejSi.js";
2
2
  import { money } from "./money-DtGOtDri.js";
3
- import { PaymentDialogFrame } from "./payment-dialog-frame-xtidt_eM.js";
3
+ import { PaymentDialogFrame } from "./payment-dialog-frame-C2n--N7s.js";
4
4
  import { confirmingPaymentUrl } from "./payment-return-5cjypwIw.js";
5
5
  import { useNavigate } from "react-router";
6
6
  import { useEffect, useRef, useState } from "react";
@@ -28,6 +28,8 @@ const timedClientMethods = /* @__PURE__ */ new Set([
28
28
  "getLayout",
29
29
  "getStoreId",
30
30
  "getCollections",
31
+ "getCollectionCovers",
32
+ "getCollectionsWithProducts",
31
33
  "getPaymentMethods",
32
34
  "getCollectionBySlug",
33
35
  "getPageBySlug",
@@ -40,6 +42,7 @@ const timedClientMethods = /* @__PURE__ */ new Set([
40
42
  "getSellers",
41
43
  "getSellerBySlug",
42
44
  "getProducts",
45
+ "getProductsWithReviews",
43
46
  "getProductBySlug",
44
47
  "getRelatedProducts",
45
48
  "autocompleteProducts",
@@ -1,5 +1,5 @@
1
- import { loadSections, withSections } from "./sections-CgpjubkB.js";
2
- import { worker } from "./worker-cbXmLvfR.js";
1
+ import { loadSections, withSections } from "./sections-BkjGSM28.js";
2
+ import { worker } from "./worker-BxlCSjSF.js";
3
3
  // src/templates.ts
4
4
  const TEMPLATE = "ecomiqTemplate";
5
5
  const NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
@@ -1,6 +1,6 @@
1
1
  import { readCatalog } from "./catalog-7gJ-l5hW.js";
2
2
  import { documentUrl } from "./document-url-CGsAl5Tf.js";
3
- import { store } from "./store-uU2gWdMY.js";
3
+ import { store } from "./store-BGDvRGNS.js";
4
4
  import { data, redirect } from "react-router";
5
5
  import { sanitizeHtml } from "@ecomiq/core";
6
6
  // src/urls.ts