@ecomiq/storefront 0.1.0 → 0.1.1

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/react.js CHANGED
@@ -1,15 +1,412 @@
1
- import axios from 'axios';
2
1
  import { z } from 'zod';
2
+ import { Modal } from '@ecomiq/ui/components/modal';
3
+ import { formatCurrency as formatCurrency$1, StorefrontPageDetailSchema as StorefrontPageDetailSchema$1, useCart as useCart$1, useStore as useStore$1, useStorefrontAuthClient as useStorefrontAuthClient$1, useStorefrontSession as useStorefrontSession$1, SignInForm, SignUpForm, storefrontStoreRecord as storefrontStoreRecord$1 } from '@ecomiq/storefront/react';
4
+ import { toast, Toaster as Toaster$1 } from 'sonner';
5
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
6
+ import { useTheme } from 'next-themes';
7
+ import axios from 'axios';
3
8
  import { QueryClient, hydrate, QueryClientProvider, useMutation, useQuery, useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
4
- import { createContext, useRef, useEffect, useContext, useState, useMemo, useCallback } from 'react';
5
- import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
9
+ import React2, { createContext, useRef, useEffect, useContext, useState, useMemo, useCallback } from 'react';
6
10
  import { create } from 'zustand';
7
11
  import { persist } from 'zustand/middleware';
8
12
  import { createAuthMiddleware, createAuthEndpoint, formCsrfMiddleware } from 'better-auth/api';
9
13
  import { APIError } from 'better-auth';
10
14
  import { setSessionCookie } from 'better-auth/cookies';
11
15
  import { parseUserOutput } from 'better-auth/db';
12
- import { formatCurrency as formatCurrency$1, StorefrontPageDetailSchema as StorefrontPageDetailSchema$1 } from '@ecomiq/storefront/react';
16
+
17
+ var __defProp = Object.defineProperty;
18
+ var __getOwnPropNames = Object.getOwnPropertyNames;
19
+ var __esm = (fn, res) => function __init() {
20
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
21
+ };
22
+ var __export = (target, all) => {
23
+ for (var name in all)
24
+ __defProp(target, name, { get: all[name], enumerable: true });
25
+ };
26
+
27
+ // src/core/client/store-api-client.ts
28
+ function setClientStoreId(storeId) {
29
+ if (typeof window === "undefined") return;
30
+ clientStoreIdGetter = storeId?.trim() || null;
31
+ }
32
+ async function getStoreApiBaseUrl() {
33
+ if (typeof window !== "undefined") {
34
+ return STORE_API_PATH;
35
+ }
36
+ if (serverRequestOriginGetter) {
37
+ return `${serverRequestOriginGetter.replace(/\/$/, "")}/${STORE_API_PATH.replace(/^\//, "")}`;
38
+ }
39
+ return STORE_API_PATH;
40
+ }
41
+ async function getStoreApiClient() {
42
+ const baseUrl = await getStoreApiBaseUrl();
43
+ return new StoreApiClient(baseUrl);
44
+ }
45
+ var STORE_API_PATH, serverRequestOriginGetter, serverStoreIdGetter, clientStoreIdGetter, StoreApiClient;
46
+ var init_store_api_client = __esm({
47
+ "src/core/client/store-api-client.ts"() {
48
+ STORE_API_PATH = "/api/store";
49
+ serverRequestOriginGetter = null;
50
+ serverStoreIdGetter = null;
51
+ clientStoreIdGetter = null;
52
+ StoreApiClient = class {
53
+ baseUrl;
54
+ constructor(baseUrl = STORE_API_PATH) {
55
+ this.baseUrl = baseUrl.replace(/\/$/, "");
56
+ }
57
+ async request(path, init, options) {
58
+ const pathNorm = path.replace(/^\/+/, "");
59
+ const url = path.startsWith("http") ? path : `${this.baseUrl}/${pathNorm}`;
60
+ const headers = new Headers(init.headers ?? {});
61
+ headers.set("Content-Type", "application/json");
62
+ headers.set("Accept-Encoding", "identity");
63
+ const explicitStoreId = options?.xStoreId?.trim();
64
+ const runtimeStoreId = explicitStoreId || (typeof window === "undefined" ? serverStoreIdGetter : clientStoreIdGetter);
65
+ if (runtimeStoreId && !headers.has("x-store-id")) {
66
+ headers.set("X-Store-Id", runtimeStoreId);
67
+ }
68
+ if (options?.xStoreDomain) {
69
+ headers.set("X-Store-Domain", options.xStoreDomain);
70
+ }
71
+ if (options?.xCartId) {
72
+ headers.set("X-Cart-Token", options.xCartId);
73
+ }
74
+ const bearer = typeof options?.bearerToken === "string" && options.bearerToken.trim().length > 0 ? options.bearerToken.trim() : void 0;
75
+ if (bearer) {
76
+ headers.set(
77
+ "Authorization",
78
+ bearer.toLowerCase().startsWith("bearer ") ? bearer : `Bearer ${bearer}`
79
+ );
80
+ }
81
+ const isServer = typeof window === "undefined";
82
+ const res = await fetch(url, {
83
+ ...init,
84
+ headers,
85
+ credentials: isServer ? "same-origin" : "include",
86
+ ...options?.noStore ? { cache: "no-store" } : {},
87
+ ...options?.cacheKey && isServer && !options?.noStore ? {
88
+ next: {
89
+ revalidate: 60,
90
+ tags: [options.cacheKey]
91
+ }
92
+ } : {}
93
+ });
94
+ if (!res.ok) {
95
+ let body;
96
+ try {
97
+ const errorText = await res.text();
98
+ body = errorText ? JSON.parse(errorText) : void 0;
99
+ } catch {
100
+ body = void 0;
101
+ }
102
+ const msg = typeof body === "object" && body !== null && "title" in body && typeof body.title === "string" ? body.title : res.statusText || "Store API error";
103
+ const err = new Error(msg);
104
+ err.status = res.status;
105
+ err.body = body;
106
+ throw err;
107
+ }
108
+ const text = await res.text();
109
+ if (!text) return void 0;
110
+ return JSON.parse(text);
111
+ }
112
+ get(path, options) {
113
+ return this.request(path, { method: "GET" }, options);
114
+ }
115
+ post(path, data, options) {
116
+ return this.request(
117
+ path,
118
+ {
119
+ method: "POST",
120
+ body: data != null ? JSON.stringify(data) : void 0
121
+ },
122
+ options
123
+ );
124
+ }
125
+ patch(path, data, options) {
126
+ return this.request(path, {
127
+ method: "PATCH",
128
+ body: data != null ? JSON.stringify(data) : void 0
129
+ }, options);
130
+ }
131
+ put(path, data, options) {
132
+ return this.request(
133
+ path,
134
+ {
135
+ method: "PUT",
136
+ body: data != null ? JSON.stringify(data) : void 0
137
+ },
138
+ options
139
+ );
140
+ }
141
+ delete(path, options) {
142
+ return this.request(path, { method: "DELETE" }, options);
143
+ }
144
+ };
145
+ new StoreApiClient(STORE_API_PATH);
146
+ }
147
+ });
148
+ function customerAuthOptions(accessToken) {
149
+ const token = typeof accessToken === "string" && accessToken.trim().length > 0 ? accessToken.trim() : void 0;
150
+ return token ? { bearerToken: token } : {};
151
+ }
152
+ async function registerCustomer(data) {
153
+ const payload = CustomerRegisterRequestSchema.parse(data);
154
+ const client = await getStoreApiClient();
155
+ return client.post("customer/register", payload);
156
+ }
157
+ async function getCustomerMe(accessToken) {
158
+ const client = await getStoreApiClient();
159
+ const response = await client.get("customer", customerAuthOptions(accessToken));
160
+ return CustomerMeSchema.parse(response);
161
+ }
162
+ var CustomerRegisterRequestSchema, CustomerAddressSchema, CustomerMeSchema;
163
+ var init_store_api_customer_service = __esm({
164
+ "src/core/client/store-api-customer.service.ts"() {
165
+ init_store_api_client();
166
+ CustomerRegisterRequestSchema = z.object({
167
+ email: z.string().email(),
168
+ firstName: z.string().trim().min(1),
169
+ lastName: z.string().trim().min(1),
170
+ countryIsoCode: z.string().trim().length(2),
171
+ password: z.string(),
172
+ phone: z.string().trim().optional()
173
+ });
174
+ CustomerAddressSchema = z.object({
175
+ /** Presente en listados cuando el upstream expone el id para PUT/DELETE. */
176
+ id: z.string().optional(),
177
+ addressKey: z.string(),
178
+ countryIsoCode: z.string(),
179
+ addressLine: z.string(),
180
+ addressNumber: z.string(),
181
+ department: z.string(),
182
+ province: z.string(),
183
+ district: z.string(),
184
+ phone: z.string(),
185
+ cellPhone: z.string(),
186
+ postalCode: z.string(),
187
+ reference: z.string(),
188
+ latitude: z.number().nullable(),
189
+ longitude: z.number().nullable(),
190
+ isDefault: z.boolean()
191
+ });
192
+ CustomerAddressSchema.omit({ id: true });
193
+ CustomerMeSchema = z.object({
194
+ id: z.string(),
195
+ storeId: z.string(),
196
+ email: z.string().email(),
197
+ firstName: z.string(),
198
+ lastName: z.string(),
199
+ phone: z.string(),
200
+ identificationNumber: z.string().nullable(),
201
+ identificationType: z.string().nullable(),
202
+ entityName: z.string().nullable(),
203
+ dateOfBirth: z.string().nullable(),
204
+ gender: z.string().nullable(),
205
+ countryIsoCode: z.string(),
206
+ role: z.string().nullable(),
207
+ companyName: z.string().nullable(),
208
+ consent: z.boolean(),
209
+ userId: z.string(),
210
+ customerType: z.string(),
211
+ status: z.string(),
212
+ entityIdentificationNumber: z.string().nullable(),
213
+ defaultAddressId: z.string().nullable(),
214
+ metadata: z.unknown().nullable(),
215
+ totalOrders: z.number(),
216
+ avgOrders: z.number(),
217
+ lastOrderId: z.string().nullable(),
218
+ lastOrderDate: z.string().nullable(),
219
+ loyaltyPoints: z.number(),
220
+ addresses: z.array(CustomerAddressSchema),
221
+ createdOn: z.string(),
222
+ updatedOn: z.string().nullable()
223
+ });
224
+ z.object({
225
+ firstName: z.string().trim().min(1),
226
+ lastName: z.string().trim().min(1),
227
+ phone: z.string().trim(),
228
+ identificationNumber: z.string().nullable(),
229
+ identificationType: z.string().nullable(),
230
+ entityName: z.string().nullable(),
231
+ entityIdentificationNumber: z.string().nullable(),
232
+ gender: z.string().nullable(),
233
+ role: z.string().nullable(),
234
+ companyName: z.string().nullable(),
235
+ dateOfBirth: z.string().nullable(),
236
+ consent: z.boolean(),
237
+ countryIsoCode: z.string().trim().length(2)
238
+ });
239
+ }
240
+ });
241
+ var ModalsFactory;
242
+ var init_modals_factory = __esm({
243
+ "src/react/shell/components/modals-factory.tsx"() {
244
+ "use client";
245
+ init_store_api_customer_service();
246
+ ModalsFactory = () => {
247
+ const cart = useCart$1();
248
+ const store = useStore$1();
249
+ const authClient = useStorefrontAuthClient$1();
250
+ const { refetch } = useStorefrontSession$1();
251
+ const handlerLogin = async (values) => {
252
+ const settings = store.data;
253
+ const record = storefrontStoreRecord$1(settings);
254
+ const checkout = record?.checkoutSettings;
255
+ if (!record?.id) {
256
+ toast.error("Tienda no disponible");
257
+ return;
258
+ }
259
+ const identityScope = checkout?.identityScope === "tenant" ? "tenant" : "store";
260
+ const identityHeaders = {
261
+ "x-Identity-Scope": identityScope,
262
+ "x-Store-Id": record.id
263
+ };
264
+ if (record.tenantId) {
265
+ identityHeaders["x-Tenant-Id"] = record.tenantId;
266
+ }
267
+ try {
268
+ const response = await authClient.$fetch("/ecomiq-oauth/sign-in", {
269
+ method: "POST",
270
+ headers: identityHeaders,
271
+ body: { email: values.email, password: values.password }
272
+ });
273
+ if (response.error) {
274
+ toast.error(response.error.message);
275
+ return;
276
+ }
277
+ const me = await getCustomerMe();
278
+ const displayName = `${me.firstName} ${me.lastName}`.trim() || me.email;
279
+ const updateUserResponse = await authClient.$fetch("/update-user", {
280
+ method: "POST",
281
+ body: {
282
+ name: displayName,
283
+ firstName: me.firstName,
284
+ lastName: me.lastName,
285
+ phone: me.phone
286
+ }
287
+ });
288
+ if (updateUserResponse.error) {
289
+ throw new Error(updateUserResponse.error?.message ?? "No se pudo sincronizar el perfil");
290
+ }
291
+ if (me.email) {
292
+ cart.setCheckoutCustomerLocal({
293
+ email: me.email,
294
+ firstName: me.firstName,
295
+ lastName: me.lastName,
296
+ phone: me.phone ?? ""
297
+ });
298
+ }
299
+ await refetch();
300
+ toast.success("Sesi\xF3n iniciada correctamente");
301
+ store.closeModal("login");
302
+ } catch (error) {
303
+ console.error("Error al iniciar sesion:", error);
304
+ toast.error("Error al iniciar sesion");
305
+ }
306
+ };
307
+ const handlerSignup = async (values) => {
308
+ try {
309
+ await registerCustomer({
310
+ email: values.email,
311
+ firstName: values.firstName,
312
+ lastName: values.lastName,
313
+ countryIsoCode: values.countryIsoCode,
314
+ password: values.password,
315
+ phone: values.phone
316
+ });
317
+ toast.success("Cuenta creada correctamente");
318
+ store.closeModal("signup");
319
+ setTimeout(() => {
320
+ store.openModal("login");
321
+ }, 1e3);
322
+ } catch (error) {
323
+ console.error("Error al registrarse:", error);
324
+ toast.error("Error al registrarse");
325
+ }
326
+ };
327
+ return /* @__PURE__ */ jsxs(
328
+ Modal,
329
+ {
330
+ isOpen: store.modals.login || store.modals.signup,
331
+ onClose: () => store.closeAllModals(),
332
+ children: [
333
+ store.modals.login && /* @__PURE__ */ jsxs(Fragment, { children: [
334
+ /* @__PURE__ */ jsx(SignInForm, { onSubmit: (values) => handlerLogin(values) }),
335
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-center items-center mt-4", children: [
336
+ /* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "No tienes cuenta?" }),
337
+ /* @__PURE__ */ jsx(
338
+ "button",
339
+ {
340
+ type: "button",
341
+ onClick: () => store.openModal("signup"),
342
+ className: "text-primary hover:underline ml-2 cursor-pointer",
343
+ children: "Registrate"
344
+ }
345
+ )
346
+ ] })
347
+ ] }),
348
+ store.modals.signup && /* @__PURE__ */ jsxs(Fragment, { children: [
349
+ /* @__PURE__ */ jsx(SignUpForm, { onSubmit: (values) => handlerSignup(values) }),
350
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-center items-center mt-4", children: [
351
+ /* @__PURE__ */ jsx("p", { className: "text-gray-500", children: "Ya tienes cuenta?" }),
352
+ /* @__PURE__ */ jsx(
353
+ "button",
354
+ {
355
+ type: "button",
356
+ onClick: () => store.openModal("login"),
357
+ className: "text-primary hover:underline ml-2 cursor-pointer",
358
+ children: "Inicia sesion"
359
+ }
360
+ )
361
+ ] })
362
+ ] })
363
+ ]
364
+ }
365
+ );
366
+ };
367
+ }
368
+ });
369
+ var Toaster;
370
+ var init_Toaster = __esm({
371
+ "src/react/shell/components/Toaster.tsx"() {
372
+ "use client";
373
+ Toaster = ({ ...props }) => {
374
+ const { theme = "system" } = useTheme();
375
+ return /* @__PURE__ */ jsx(
376
+ Toaster$1,
377
+ {
378
+ theme,
379
+ className: "toaster group",
380
+ style: {
381
+ "--normal-bg": "var(--popover)",
382
+ "--normal-text": "var(--popover-foreground)",
383
+ "--normal-border": "var(--border)"
384
+ },
385
+ ...props
386
+ }
387
+ );
388
+ };
389
+ }
390
+ });
391
+
392
+ // src/react/shell/providers/ecomiq-shell-ui.tsx
393
+ var ecomiq_shell_ui_exports = {};
394
+ __export(ecomiq_shell_ui_exports, {
395
+ EcomiqShellUi: () => EcomiqShellUi
396
+ });
397
+ function EcomiqShellUi() {
398
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
399
+ /* @__PURE__ */ jsx(ModalsFactory, {}),
400
+ /* @__PURE__ */ jsx(Toaster, { position: "bottom-right" })
401
+ ] });
402
+ }
403
+ var init_ecomiq_shell_ui = __esm({
404
+ "src/react/shell/providers/ecomiq-shell-ui.tsx"() {
405
+ "use client";
406
+ init_modals_factory();
407
+ init_Toaster();
408
+ }
409
+ });
13
410
 
14
411
  // src/core/constants/api-paths.ts
15
412
  var STOREFRONT_API_PATH_PREFIX = "v1";
@@ -1719,6 +2116,31 @@ var useCart = create()(
1719
2116
  { name: "cart-storage" }
1720
2117
  )
1721
2118
  );
2119
+ init_store_api_client();
2120
+ function EcomiqProvider({
2121
+ store,
2122
+ authClient,
2123
+ children,
2124
+ withShellUi = false
2125
+ }) {
2126
+ useStore.setState({ data: store ?? null });
2127
+ useEffect(() => {
2128
+ setClientStoreId(store?.store.id ?? null);
2129
+ return () => setClientStoreId(null);
2130
+ }, [store]);
2131
+ const [queryClient] = useState(() => new QueryClient());
2132
+ return /* @__PURE__ */ jsx(StorefrontAuthProvider, { authClient, children: /* @__PURE__ */ jsxs(QueryClientProvider, { client: queryClient, children: [
2133
+ children,
2134
+ withShellUi ? /* @__PURE__ */ jsx(EcomiqShellUi2, {}) : null
2135
+ ] }) });
2136
+ }
2137
+ function EcomiqShellUi2() {
2138
+ const [ui, setUi] = useState(null);
2139
+ useEffect(() => {
2140
+ void Promise.resolve().then(() => (init_ecomiq_shell_ui(), ecomiq_shell_ui_exports)).then((mod) => setUi(() => mod.EcomiqShellUi));
2141
+ }, []);
2142
+ return ui ? React2.createElement(ui) : null;
2143
+ }
1722
2144
 
1723
2145
  // src/react/auth/ecomiq-oauth-password-constants.ts
1724
2146
  var PLUGIN_ID = "ecomiq-oauth-password";
@@ -2016,979 +2438,6 @@ function ecomiqOAuthPasswordClient() {
2016
2438
  ]
2017
2439
  };
2018
2440
  }
2019
-
2020
- // src/react/components/cms-sections/utils.ts
2021
- var PRODUCT_SORTS = /* @__PURE__ */ new Set([
2022
- "price_asc",
2023
- "price_desc",
2024
- "name_asc",
2025
- "name_desc",
2026
- "newest"
2027
- ]);
2028
- function orderedBlocks(blocks) {
2029
- return [...blocks ?? []].sort((a, b) => a.order - b.order);
2030
- }
2031
- function getCmsSectionKey(section, index) {
2032
- return section.id ?? `${canonicalSectionType(section.type)}-${section.order}-${index}`;
2033
- }
2034
- function getCmsBlockKey(block, index) {
2035
- return block.id ?? `${block.type}-${block.order}-${index}`;
2036
- }
2037
- function canonicalSectionType(type) {
2038
- if (type === "page-hero") {
2039
- return "hero";
2040
- }
2041
- if (type === "featured-products") {
2042
- return "product-list";
2043
- }
2044
- return type;
2045
- }
2046
- function storefrontHref(value) {
2047
- const href = value.trim();
2048
- if (!href) {
2049
- return "#";
2050
- }
2051
- if (href === "#" || href.startsWith("http://") || href.startsWith("https://") || href.startsWith("mailto:") || href.startsWith("tel:")) {
2052
- return href;
2053
- }
2054
- if (href === "/") {
2055
- return "/store";
2056
- }
2057
- if (href.startsWith("/store") || href.startsWith("/product")) {
2058
- return href;
2059
- }
2060
- if (href.startsWith("/collections") || href.startsWith("/pages") || href.startsWith("/account")) {
2061
- return `/store${href}`;
2062
- }
2063
- return href;
2064
- }
2065
- function sectionTitleContent(section) {
2066
- return settingContent(section.settings, "title") || settingContent(section.settings, "name");
2067
- }
2068
- function settingString(settings, key) {
2069
- const value = settings?.[key];
2070
- return typeof value === "string" ? value : "";
2071
- }
2072
- function settingContent(settings, key) {
2073
- const value = settings?.[key];
2074
- if (typeof value === "string" || typeof value === "number") {
2075
- return value;
2076
- }
2077
- if (value == null || typeof value === "boolean") {
2078
- return "";
2079
- }
2080
- return value;
2081
- }
2082
- function settingNumber(settings, key, fallback) {
2083
- const value = settings?.[key];
2084
- if (typeof value === "number" && Number.isFinite(value)) {
2085
- return value;
2086
- }
2087
- if (typeof value === "string") {
2088
- const parsed = Number(value);
2089
- return Number.isFinite(parsed) ? parsed : fallback;
2090
- }
2091
- return fallback;
2092
- }
2093
- function layoutChildren(settings, key) {
2094
- const children = settings.children;
2095
- if (typeof children !== "object" || children === null || Array.isArray(children)) {
2096
- return [];
2097
- }
2098
- const value = children[key];
2099
- return Array.isArray(value) ? value : [];
2100
- }
2101
- function layoutPadding(value) {
2102
- switch (value) {
2103
- case "none":
2104
- return "py-0";
2105
- case "small":
2106
- return "py-6";
2107
- case "large":
2108
- return "py-16";
2109
- default:
2110
- return "py-10";
2111
- }
2112
- }
2113
- function layoutMaxWidth(value) {
2114
- switch (value) {
2115
- case "full":
2116
- return "max-w-none";
2117
- case "narrow":
2118
- return "max-w-3xl";
2119
- default:
2120
- return "max-w-7xl";
2121
- }
2122
- }
2123
- function layoutBackground(value) {
2124
- switch (value) {
2125
- case "muted":
2126
- return "bg-neutral-50";
2127
- case "dark":
2128
- return "bg-neutral-950 text-white";
2129
- default:
2130
- return "bg-white";
2131
- }
2132
- }
2133
- function layoutGap(value) {
2134
- switch (value) {
2135
- case "none":
2136
- return "gap-0";
2137
- case "small":
2138
- return "gap-3";
2139
- case "large":
2140
- return "gap-8";
2141
- default:
2142
- return "gap-5";
2143
- }
2144
- }
2145
- function layoutAlign(value) {
2146
- switch (value) {
2147
- case "start":
2148
- return "items-start";
2149
- case "center":
2150
- return "items-center";
2151
- case "end":
2152
- return "items-end";
2153
- default:
2154
- return "items-stretch";
2155
- }
2156
- }
2157
- function layoutJustify(value) {
2158
- switch (value) {
2159
- case "center":
2160
- return "justify-center";
2161
- case "end":
2162
- return "justify-end";
2163
- case "between":
2164
- return "justify-between";
2165
- default:
2166
- return "justify-start";
2167
- }
2168
- }
2169
- function productSortValue(value) {
2170
- return PRODUCT_SORTS.has(value) ? value : "newest";
2171
- }
2172
- function sanitizeHtml(html) {
2173
- return html.replace(/<script[\s\S]*?>[\s\S]*?<\/script>/gi, "").replace(/<style[\s\S]*?>[\s\S]*?<\/style>/gi, "").replace(/<(iframe|object|embed|link|meta)[\s\S]*?>/gi, "").replace(/\son\w+\s*=\s*(['"]).*?\1/gi, "").replace(/\s(href|src)\s*=\s*(['"])\s*javascript:[\s\S]*?\2/gi, "");
2174
- }
2175
- var DEFAULT_CMS_IMAGE_URL = "data:image/svg+xml;charset=UTF-8," + encodeURIComponent(`
2176
- <svg xmlns="http://www.w3.org/2000/svg" width="640" height="360" viewBox="0 0 640 360">
2177
- <rect width="640" height="360" fill="#f4f4f5"/>
2178
- <rect x="40" y="36" width="560" height="288" rx="20" fill="#ffffff" stroke="#d4d4d8"/>
2179
- <path d="M148 246l102-102 78 78 48-48 120 120H148z" fill="#d4d4d8"/>
2180
- <circle cx="456" cy="118" r="32" fill="#e4e4e7"/>
2181
- </svg>
2182
- `);
2183
- function SectionHeading({ section }) {
2184
- const title = sectionTitleContent(section);
2185
- const subtitle = settingContent(section.settings, "subtitle");
2186
- if (!title && !subtitle) {
2187
- return null;
2188
- }
2189
- return /* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
2190
- title ? /* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold tracking-tight text-neutral-950", children: title }) : null,
2191
- subtitle ? /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-neutral-600", children: subtitle }) : null
2192
- ] });
2193
- }
2194
- function EmptyState({ children }) {
2195
- return /* @__PURE__ */ jsx("p", { className: "rounded-lg border border-dashed p-6 text-center text-sm text-neutral-500", children });
2196
- }
2197
- function DefaultLink({ href, className, children }) {
2198
- return /* @__PURE__ */ jsx("a", { href, className, children });
2199
- }
2200
- function CmsImage({
2201
- src,
2202
- fallbackSrc = DEFAULT_CMS_IMAGE_URL,
2203
- onError,
2204
- ...props
2205
- }) {
2206
- const imageSrc = src?.trim() || fallbackSrc;
2207
- return /* @__PURE__ */ jsx(
2208
- "img",
2209
- {
2210
- src: imageSrc,
2211
- onError: (event) => {
2212
- onError?.(event);
2213
- const image = event.currentTarget;
2214
- if (image.dataset.cmsFallback === "true") {
2215
- return;
2216
- }
2217
- image.dataset.cmsFallback = "true";
2218
- image.src = fallbackSrc;
2219
- },
2220
- ...props
2221
- }
2222
- );
2223
- }
2224
- function RichTextSection({ section }) {
2225
- const html = settingString(section.settings, "html") || settingString(section.settings, "content") || settingString(section.settings, "richText");
2226
- return /* @__PURE__ */ jsxs("section", { className: "container mx-auto px-4 py-10", children: [
2227
- /* @__PURE__ */ jsx(SectionHeading, { section }),
2228
- html ? /* @__PURE__ */ jsx(
2229
- "div",
2230
- {
2231
- className: "prose prose-neutral max-w-none",
2232
- dangerouslySetInnerHTML: { __html: sanitizeHtml(html) }
2233
- }
2234
- ) : null
2235
- ] });
2236
- }
2237
- function CustomHtmlSection({ section }) {
2238
- const html = settingString(section.settings, "html") || settingString(section.settings, "content");
2239
- if (!html) {
2240
- return null;
2241
- }
2242
- return /* @__PURE__ */ jsx(
2243
- "section",
2244
- {
2245
- className: "cms-custom-html",
2246
- dangerouslySetInnerHTML: { __html: sanitizeHtml(html) }
2247
- }
2248
- );
2249
- }
2250
- function FloatingBlockSection({
2251
- section,
2252
- linkComponent: LinkComponent
2253
- }) {
2254
- const settings = section.settings ?? {};
2255
- const title = settingContent(settings, "title");
2256
- const text = settingContent(settings, "text");
2257
- const imageUrl = settingString(settings, "imageUrl");
2258
- const linkText = settingContent(settings, "linkText");
2259
- const linkUrl = storefrontHref(settingString(settings, "linkUrl"));
2260
- const x = boundedPercent(settingNumber(settings, "x", 8));
2261
- const y = boundedPercent(settingNumber(settings, "y", 12));
2262
- const width = Math.min(
2263
- Math.max(boundedPercent(settingNumber(settings, "width", 28)), 12),
2264
- 90
2265
- );
2266
- const zIndex = Math.max(Math.round(settingNumber(settings, "zIndex", 20)), 1);
2267
- if (!title && !text && !imageUrl) {
2268
- return null;
2269
- }
2270
- const content = /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-lg border border-black/10 bg-white text-neutral-950 shadow-lg", children: [
2271
- imageUrl ? /* @__PURE__ */ jsx("div", { className: "aspect-[16/9] bg-neutral-100", children: /* @__PURE__ */ jsx(
2272
- CmsImage,
2273
- {
2274
- src: imageUrl,
2275
- alt: "",
2276
- className: "h-full w-full object-cover",
2277
- loading: "lazy"
2278
- }
2279
- ) }) : null,
2280
- /* @__PURE__ */ jsxs("div", { className: "p-4", children: [
2281
- title ? /* @__PURE__ */ jsx("p", { className: "text-base font-semibold leading-6", children: title }) : null,
2282
- text ? /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm leading-5 text-neutral-600", children: text }) : null,
2283
- linkText && linkUrl !== "#" ? /* @__PURE__ */ jsx("span", { className: "mt-3 inline-flex text-sm font-medium underline underline-offset-4", children: linkText }) : null
2284
- ] })
2285
- ] });
2286
- return /* @__PURE__ */ jsx(
2287
- "div",
2288
- {
2289
- className: "absolute",
2290
- style: {
2291
- left: `${x}%`,
2292
- top: `${y}%`,
2293
- width: `${width}%`,
2294
- zIndex
2295
- },
2296
- children: linkText && linkUrl !== "#" ? /* @__PURE__ */ jsx(LinkComponent, { href: linkUrl, children: content }) : content
2297
- }
2298
- );
2299
- }
2300
- function FaqSection({ section }) {
2301
- const items = orderedBlocks(section.blocks);
2302
- return /* @__PURE__ */ jsxs("section", { className: "container mx-auto px-4 py-12", children: [
2303
- /* @__PURE__ */ jsx(SectionHeading, { section }),
2304
- /* @__PURE__ */ jsx("div", { className: "divide-y rounded-lg border bg-white", children: items.map((item, index) => /* @__PURE__ */ jsxs("details", { className: "group p-4", children: [
2305
- /* @__PURE__ */ jsx("summary", { className: "cursor-pointer text-sm font-medium text-neutral-950", children: settingContent(item.settings, "question") || settingContent(item.settings, "title") }),
2306
- /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm leading-6 text-neutral-600", children: settingContent(item.settings, "answer") || settingContent(item.settings, "content") })
2307
- ] }, getCmsBlockKey(item, index))) })
2308
- ] });
2309
- }
2310
- function boundedPercent(value) {
2311
- if (!Number.isFinite(value)) {
2312
- return 0;
2313
- }
2314
- return Math.min(Math.max(value, 0), 100);
2315
- }
2316
- function NewsletterSection({ section }) {
2317
- const title = sectionTitleContent(section) || "Recibe novedades";
2318
- const subtitle = settingContent(section.settings, "subtitle");
2319
- const placeholder = settingString(section.settings, "placeholder") || "tu@email.com";
2320
- const buttonText = settingContent(section.settings, "buttonText") || "Suscribirme";
2321
- return /* @__PURE__ */ jsx("section", { className: "bg-neutral-950 px-4 py-14 text-white", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-2xl text-center", children: [
2322
- /* @__PURE__ */ jsx("h2", { className: "text-3xl font-semibold", children: title }),
2323
- subtitle ? /* @__PURE__ */ jsx("p", { className: "mt-3 text-white/70", children: subtitle }) : null,
2324
- /* @__PURE__ */ jsxs("form", { className: "mt-6 flex flex-col gap-2 sm:flex-row", children: [
2325
- /* @__PURE__ */ jsx(
2326
- "input",
2327
- {
2328
- type: "email",
2329
- placeholder,
2330
- className: "h-10 flex-1 rounded-md border border-white/20 bg-white px-3 text-sm text-neutral-950 outline-none"
2331
- }
2332
- ),
2333
- /* @__PURE__ */ jsx(
2334
- "button",
2335
- {
2336
- type: "submit",
2337
- className: "h-10 rounded-md bg-white px-5 text-sm font-medium text-neutral-950",
2338
- children: buttonText
2339
- }
2340
- )
2341
- ] })
2342
- ] }) });
2343
- }
2344
- function IconRowSection({
2345
- section,
2346
- linkComponent: LinkComponent
2347
- }) {
2348
- return /* @__PURE__ */ jsxs("section", { className: "container mx-auto px-4 py-10", children: [
2349
- /* @__PURE__ */ jsx(SectionHeading, { section }),
2350
- /* @__PURE__ */ jsx("div", { className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-4", children: orderedBlocks(section.blocks).map((block, index) => {
2351
- const settings = block.settings ?? {};
2352
- const href = storefrontHref(settingString(settings, "linkUrl"));
2353
- const content = /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-white p-4", children: [
2354
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-neutral-950", children: settingContent(settings, "title") || settingContent(settings, "label") }),
2355
- /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-neutral-600", children: settingContent(settings, "subtitle") || settingContent(settings, "description") })
2356
- ] });
2357
- return href === "#" ? /* @__PURE__ */ jsx("div", { children: content }, getCmsBlockKey(block, index)) : /* @__PURE__ */ jsx(LinkComponent, { href, children: content }, getCmsBlockKey(block, index));
2358
- }) })
2359
- ] });
2360
- }
2361
- function TestimonialsSection({
2362
- section
2363
- }) {
2364
- return /* @__PURE__ */ jsxs("section", { className: "container mx-auto px-4 py-12", children: [
2365
- /* @__PURE__ */ jsx(SectionHeading, { section }),
2366
- /* @__PURE__ */ jsx("div", { className: "grid gap-4 md:grid-cols-3", children: orderedBlocks(section.blocks).map((block, index) => /* @__PURE__ */ jsxs(
2367
- "blockquote",
2368
- {
2369
- className: "rounded-lg border bg-white p-5",
2370
- children: [
2371
- /* @__PURE__ */ jsx("p", { className: "text-sm leading-6 text-neutral-700", children: settingString(block.settings, "quote") || settingContent(block.settings, "content") || settingContent(block.settings, "text") }),
2372
- /* @__PURE__ */ jsx("footer", { className: "mt-4 text-sm font-medium text-neutral-950", children: settingContent(block.settings, "author") || settingContent(block.settings, "name") })
2373
- ]
2374
- },
2375
- getCmsBlockKey(block, index)
2376
- )) })
2377
- ] });
2378
- }
2379
- function StatsSection({ section }) {
2380
- return /* @__PURE__ */ jsxs("section", { className: "container mx-auto px-4 py-12", children: [
2381
- /* @__PURE__ */ jsx(SectionHeading, { section }),
2382
- /* @__PURE__ */ jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-4", children: orderedBlocks(section.blocks).map((block, index) => /* @__PURE__ */ jsxs(
2383
- "div",
2384
- {
2385
- className: "rounded-lg border bg-white p-5",
2386
- children: [
2387
- /* @__PURE__ */ jsx("p", { className: "text-3xl font-semibold text-neutral-950", children: settingContent(block.settings, "value") }),
2388
- /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-neutral-600", children: settingContent(block.settings, "label") || settingContent(block.settings, "title") })
2389
- ]
2390
- },
2391
- getCmsBlockKey(block, index)
2392
- )) })
2393
- ] });
2394
- }
2395
- function TimelineSection({ section }) {
2396
- return /* @__PURE__ */ jsxs("section", { className: "container mx-auto px-4 py-12", children: [
2397
- /* @__PURE__ */ jsx(SectionHeading, { section }),
2398
- /* @__PURE__ */ jsx("div", { className: "space-y-4 border-l pl-5", children: orderedBlocks(section.blocks).map((block, index) => /* @__PURE__ */ jsxs("article", { className: "relative", children: [
2399
- /* @__PURE__ */ jsx("span", { className: "absolute -left-[27px] top-1 size-3 rounded-full bg-neutral-950" }),
2400
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-neutral-950", children: settingContent(block.settings, "title") }),
2401
- /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-neutral-600", children: settingContent(block.settings, "description") || settingContent(block.settings, "content") })
2402
- ] }, getCmsBlockKey(block, index))) })
2403
- ] });
2404
- }
2405
- function ContactFormSection({ section }) {
2406
- const fields = orderedBlocks(section.blocks);
2407
- const submitText = settingString(section.settings, "submitText") || "Enviar";
2408
- return /* @__PURE__ */ jsxs("section", { className: "container mx-auto px-4 py-12", children: [
2409
- /* @__PURE__ */ jsx(SectionHeading, { section }),
2410
- /* @__PURE__ */ jsxs("form", { className: "mx-auto grid max-w-2xl gap-3", children: [
2411
- (fields.length > 0 ? fields : defaultContactFields()).map(
2412
- (field, index) => /* @__PURE__ */ jsx(ContactField, { field }, getCmsBlockKey(field, index))
2413
- ),
2414
- /* @__PURE__ */ jsx("button", { className: "h-10 rounded-md bg-neutral-950 px-4 text-sm font-medium text-white", children: submitText })
2415
- ] })
2416
- ] });
2417
- }
2418
- function ContactField({ field }) {
2419
- const type = settingString(field.settings, "type") || "text";
2420
- const label = settingString(field.settings, "label");
2421
- const placeholder = settingString(field.settings, "placeholder");
2422
- const name = settingString(field.settings, "name");
2423
- const className = "h-10 rounded-md border px-3 text-sm";
2424
- if (type === "textarea") {
2425
- return /* @__PURE__ */ jsx(
2426
- "textarea",
2427
- {
2428
- name,
2429
- "aria-label": label || placeholder,
2430
- className: "min-h-32 rounded-md border px-3 py-2 text-sm",
2431
- placeholder: placeholder || label
2432
- }
2433
- );
2434
- }
2435
- if (type === "select") {
2436
- const rawOptions = field.settings?.options;
2437
- const options = Array.isArray(rawOptions) ? rawOptions.filter((item) => typeof item === "string") : settingString(field.settings, "options").split("\n").map((item) => item.trim()).filter(Boolean);
2438
- return /* @__PURE__ */ jsxs("select", { name, "aria-label": label, className, children: [
2439
- /* @__PURE__ */ jsx("option", { value: "", children: placeholder || label }),
2440
- options.map((option) => /* @__PURE__ */ jsx("option", { value: option, children: option }, option))
2441
- ] });
2442
- }
2443
- return /* @__PURE__ */ jsx(
2444
- "input",
2445
- {
2446
- name,
2447
- type,
2448
- "aria-label": label || placeholder,
2449
- className,
2450
- placeholder: placeholder || label
2451
- }
2452
- );
2453
- }
2454
- function defaultContactFields() {
2455
- return [
2456
- {
2457
- type: "field",
2458
- order: 1,
2459
- settings: { name: "fullName", type: "text", label: "Nombre" }
2460
- },
2461
- {
2462
- type: "field",
2463
- order: 2,
2464
- settings: { name: "email", type: "email", label: "Email" }
2465
- },
2466
- {
2467
- type: "field",
2468
- order: 3,
2469
- settings: { name: "message", type: "textarea", label: "Mensaje" }
2470
- }
2471
- ];
2472
- }
2473
- function UnknownSection({ section }) {
2474
- return /* @__PURE__ */ jsx("section", { className: "container mx-auto px-4 py-8", children: /* @__PURE__ */ jsxs("div", { className: "rounded border border-dashed p-4 text-sm text-neutral-500", children: [
2475
- 'Seccion tipo "',
2476
- section.type,
2477
- '" pendiente de renderer.'
2478
- ] }) });
2479
- }
2480
- function AnnouncementBarSection({
2481
- section,
2482
- linkComponent: LinkComponent
2483
- }) {
2484
- const text = settingContent(section.settings, "text") || sectionTitleContent(section);
2485
- const linkText = settingContent(section.settings, "linkText");
2486
- const href = storefrontHref(settingString(section.settings, "linkUrl"));
2487
- if (!text) {
2488
- return null;
2489
- }
2490
- return /* @__PURE__ */ jsx("section", { className: "bg-neutral-950 px-4 py-2 text-white", children: /* @__PURE__ */ jsxs("div", { className: "container mx-auto flex flex-wrap items-center justify-center gap-2 text-center text-sm", children: [
2491
- /* @__PURE__ */ jsx("span", { children: text }),
2492
- linkText && href !== "#" ? /* @__PURE__ */ jsx(
2493
- LinkComponent,
2494
- {
2495
- href,
2496
- className: "font-medium underline underline-offset-4",
2497
- children: linkText
2498
- }
2499
- ) : null
2500
- ] }) });
2501
- }
2502
- function HeroSection({
2503
- section,
2504
- linkComponent: LinkComponent
2505
- }) {
2506
- const slides = orderedBlocks(section.blocks);
2507
- const fallbackSlide = {
2508
- id: `${section.id ?? "section"}-fallback`,
2509
- type: "slide",
2510
- order: 1,
2511
- settings: section.settings ?? {}
2512
- };
2513
- const visibleSlides = slides.length > 0 ? slides : [fallbackSlide];
2514
- return /* @__PURE__ */ jsx("section", { className: "bg-neutral-950 text-white", children: /* @__PURE__ */ jsx("div", { className: "flex snap-x overflow-x-auto", children: visibleSlides.map((slide, index) => {
2515
- const settings = slide.settings ?? {};
2516
- const imageUrl = settingString(settings, "imageUrl") || settingString(section.settings, "imageUrl") || DEFAULT_CMS_IMAGE_URL;
2517
- const title = settingContent(settings, "title") || settingContent(section.settings, "title") || sectionTitleContent(section);
2518
- const subtitle = settingContent(settings, "subtitle") || settingContent(section.settings, "subtitle");
2519
- const ctaText = settingContent(settings, "ctaText") || settingContent(section.settings, "ctaText");
2520
- const ctaUrl = settingString(settings, "ctaUrl") || settingString(section.settings, "ctaUrl");
2521
- const href = storefrontHref(ctaUrl);
2522
- return /* @__PURE__ */ jsxs(
2523
- "article",
2524
- {
2525
- className: "relative min-h-[520px] w-full shrink-0 snap-start overflow-hidden",
2526
- children: [
2527
- /* @__PURE__ */ jsx(
2528
- CmsImage,
2529
- {
2530
- src: imageUrl,
2531
- alt: "",
2532
- className: "absolute inset-0 h-full w-full object-cover opacity-75"
2533
- }
2534
- ),
2535
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-r from-black/70 via-black/35 to-transparent" }),
2536
- /* @__PURE__ */ jsx("div", { className: "container relative z-10 mx-auto flex min-h-[520px] items-center px-4", children: /* @__PURE__ */ jsxs("div", { className: "max-w-2xl py-16", children: [
2537
- /* @__PURE__ */ jsx("h1", { className: "text-4xl font-semibold tracking-tight md:text-6xl", children: title }),
2538
- subtitle ? /* @__PURE__ */ jsx("p", { className: "mt-4 max-w-xl text-base text-white/85 md:text-lg", children: subtitle }) : null,
2539
- ctaText && href !== "#" ? /* @__PURE__ */ jsx(
2540
- LinkComponent,
2541
- {
2542
- href,
2543
- className: "mt-8 inline-flex h-10 items-center rounded-md bg-white px-5 text-sm font-medium text-neutral-950 transition hover:bg-white/90",
2544
- children: ctaText
2545
- }
2546
- ) : null
2547
- ] }) })
2548
- ]
2549
- },
2550
- getCmsBlockKey(slide, index)
2551
- );
2552
- }) }) });
2553
- }
2554
- function ProductsSection({
2555
- section,
2556
- products,
2557
- carousel,
2558
- linkComponent,
2559
- currency,
2560
- preview
2561
- }) {
2562
- const placeholders = preview && products.length === 0;
2563
- const count = Math.min(
2564
- productPreviewCount(section, carousel),
2565
- carousel ? 5 : 8
2566
- );
2567
- return /* @__PURE__ */ jsxs("section", { className: carousel ? "py-12" : "container mx-auto px-4 py-12", children: [
2568
- carousel ? /* @__PURE__ */ jsx("div", { className: "container mx-auto px-4", children: /* @__PURE__ */ jsx(SectionHeading, { section }) }) : /* @__PURE__ */ jsx(SectionHeading, { section }),
2569
- /* @__PURE__ */ jsx("div", { className: carousel ? "container mx-auto overflow-x-auto px-4" : "", children: /* @__PURE__ */ jsx(
2570
- "div",
2571
- {
2572
- className: carousel ? "flex min-w-full gap-4 pb-2" : "grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4",
2573
- children: placeholders ? Array.from({ length: count }).map((_, index) => /* @__PURE__ */ jsx(ProductPlaceholder, { carousel }, index)) : products.map((product) => /* @__PURE__ */ jsx(
2574
- ProductCard,
2575
- {
2576
- product,
2577
- carousel,
2578
- linkComponent,
2579
- currency
2580
- },
2581
- product.id
2582
- ))
2583
- }
2584
- ) }),
2585
- !placeholders && products.length === 0 ? /* @__PURE__ */ jsx(EmptyState, { children: "No hay productos para mostrar." }) : null
2586
- ] });
2587
- }
2588
- function CategoryGridSection({
2589
- section,
2590
- collections,
2591
- linkComponent: LinkComponent,
2592
- preview
2593
- }) {
2594
- const blockItems = orderedBlocks(section.blocks).map((block) => {
2595
- const settings = block.settings ?? {};
2596
- const name = settingContent(settings, "name") || settingContent(settings, "title");
2597
- const url = settingString(settings, "url") || settingString(settings, "linkUrl");
2598
- const imageUrl = settingString(settings, "imageUrl");
2599
- if (!name) {
2600
- return null;
2601
- }
2602
- return {
2603
- id: getCmsBlockKey(block, block.order),
2604
- name,
2605
- href: storefrontHref(url || "/collections"),
2606
- imageUrl: imageUrl || DEFAULT_CMS_IMAGE_URL
2607
- };
2608
- }).filter(Boolean);
2609
- const collectionItems = collections.map((collection) => ({
2610
- id: collection.id,
2611
- name: collection.name,
2612
- href: `/store/collections/${collection.slug}`,
2613
- imageUrl: collection.imageUrl || DEFAULT_CMS_IMAGE_URL
2614
- }));
2615
- const previewItems = preview ? createPreviewCollections(section) : [];
2616
- const items = blockItems.length > 0 ? blockItems : collectionItems.length > 0 ? collectionItems : previewItems;
2617
- return /* @__PURE__ */ jsxs("section", { className: "container mx-auto px-4 py-12", children: [
2618
- /* @__PURE__ */ jsx(SectionHeading, { section }),
2619
- items.length > 0 ? /* @__PURE__ */ jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: items.map((item) => /* @__PURE__ */ jsxs(
2620
- LinkComponent,
2621
- {
2622
- href: item.href,
2623
- className: "group overflow-hidden rounded-lg border bg-white",
2624
- children: [
2625
- /* @__PURE__ */ jsx("div", { className: "aspect-[4/3] overflow-hidden bg-neutral-100", children: /* @__PURE__ */ jsx(
2626
- CmsImage,
2627
- {
2628
- src: item.imageUrl,
2629
- alt: "",
2630
- className: "h-full w-full object-cover transition duration-300 group-hover:scale-105"
2631
- }
2632
- ) }),
2633
- /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx("h3", { className: "text-base font-medium text-neutral-950", children: item.name }) })
2634
- ]
2635
- },
2636
- item.id
2637
- )) }) : /* @__PURE__ */ jsx(EmptyState, { children: "No hay categorias para mostrar." })
2638
- ] });
2639
- }
2640
- function PromoCardsSection({
2641
- section,
2642
- linkComponent: LinkComponent
2643
- }) {
2644
- const cards = orderedBlocks(section.blocks);
2645
- return /* @__PURE__ */ jsxs("section", { className: "container mx-auto px-4 py-12", children: [
2646
- /* @__PURE__ */ jsx(SectionHeading, { section }),
2647
- /* @__PURE__ */ jsx("div", { className: "grid gap-4 md:grid-cols-2", children: cards.map((card, index) => {
2648
- const settings = card.settings ?? {};
2649
- const title = settingContent(settings, "title");
2650
- const subtitle = settingContent(settings, "subtitle");
2651
- const imageUrl = settingString(settings, "imageUrl") || DEFAULT_CMS_IMAGE_URL;
2652
- const ctaText = settingContent(settings, "ctaText");
2653
- const ctaUrl = storefrontHref(
2654
- settingString(settings, "ctaUrl") || settingString(settings, "url")
2655
- );
2656
- return /* @__PURE__ */ jsxs(
2657
- LinkComponent,
2658
- {
2659
- href: ctaUrl,
2660
- className: "group relative min-h-[260px] overflow-hidden rounded-lg bg-neutral-900 text-white",
2661
- children: [
2662
- /* @__PURE__ */ jsx(
2663
- CmsImage,
2664
- {
2665
- src: imageUrl,
2666
- alt: "",
2667
- className: "absolute inset-0 h-full w-full object-cover opacity-75 transition duration-300 group-hover:scale-105"
2668
- }
2669
- ),
2670
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/35" }),
2671
- /* @__PURE__ */ jsxs("div", { className: "relative z-10 flex min-h-[260px] flex-col justify-end p-6", children: [
2672
- /* @__PURE__ */ jsx("h3", { className: "text-2xl font-semibold", children: title }),
2673
- subtitle ? /* @__PURE__ */ jsx("p", { className: "mt-2 text-white/85", children: subtitle }) : null,
2674
- ctaText ? /* @__PURE__ */ jsx("span", { className: "mt-4 text-sm font-medium", children: ctaText }) : null
2675
- ] })
2676
- ]
2677
- },
2678
- getCmsBlockKey(card, index)
2679
- );
2680
- }) })
2681
- ] });
2682
- }
2683
- function LogoSliderSection({
2684
- section,
2685
- linkComponent: LinkComponent
2686
- }) {
2687
- return /* @__PURE__ */ jsxs("section", { className: "container mx-auto px-4 py-10", children: [
2688
- /* @__PURE__ */ jsx(SectionHeading, { section }),
2689
- /* @__PURE__ */ jsx("div", { className: "flex gap-4 overflow-x-auto", children: orderedBlocks(section.blocks).map((block, index) => {
2690
- const settings = block.settings ?? {};
2691
- const imageUrl = settingString(settings, "imageUrl") || DEFAULT_CMS_IMAGE_URL;
2692
- const alt = settingString(settings, "alt") || "Logo";
2693
- const href = storefrontHref(settingString(settings, "linkUrl"));
2694
- const logo = /* @__PURE__ */ jsx("div", { className: "flex h-24 w-40 shrink-0 items-center justify-center rounded-lg border bg-white p-4", children: /* @__PURE__ */ jsx(
2695
- CmsImage,
2696
- {
2697
- src: imageUrl,
2698
- alt,
2699
- className: "max-h-full max-w-full object-contain"
2700
- }
2701
- ) });
2702
- return href !== "#" ? /* @__PURE__ */ jsx(LinkComponent, { href, children: logo }, getCmsBlockKey(block, index)) : /* @__PURE__ */ jsx("div", { children: logo }, getCmsBlockKey(block, index));
2703
- }) })
2704
- ] });
2705
- }
2706
- function ProductCard({
2707
- product,
2708
- carousel,
2709
- linkComponent: LinkComponent,
2710
- currency
2711
- }) {
2712
- const onSale = product.compareAtPrice != null && product.compareAtPrice > product.price;
2713
- return /* @__PURE__ */ jsxs(
2714
- LinkComponent,
2715
- {
2716
- href: `/product/${product.slug}`,
2717
- className: carousel ? "group w-[220px] shrink-0 sm:w-[250px] md:w-[280px]" : "group",
2718
- children: [
2719
- /* @__PURE__ */ jsx("div", { className: "aspect-square overflow-hidden rounded-lg border border-neutral-200 bg-neutral-100 transition-all duration-300 group-hover:border-neutral-300", children: /* @__PURE__ */ jsx(
2720
- CmsImage,
2721
- {
2722
- src: product.imageUrl || DEFAULT_CMS_IMAGE_URL,
2723
- alt: product.name,
2724
- className: "h-full w-full object-cover object-center transition-transform duration-500 group-hover:scale-105"
2725
- }
2726
- ) }),
2727
- /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-col", children: [
2728
- /* @__PURE__ */ jsx("h3", { className: "line-clamp-2 text-sm font-medium text-neutral-950", children: product.name }),
2729
- /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-2", children: [
2730
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-neutral-950", children: formatCurrency(product.price, currency) }),
2731
- onSale ? /* @__PURE__ */ jsx("span", { className: "text-sm text-neutral-500 line-through", children: formatCurrency(product.compareAtPrice ?? 0, currency) }) : null
2732
- ] })
2733
- ] })
2734
- ]
2735
- }
2736
- );
2737
- }
2738
- function ProductPlaceholder({ carousel }) {
2739
- return /* @__PURE__ */ jsxs(
2740
- "div",
2741
- {
2742
- className: carousel ? "w-[220px] shrink-0 sm:w-[250px] md:w-[280px]" : "",
2743
- children: [
2744
- /* @__PURE__ */ jsx("div", { className: "aspect-square rounded-lg bg-neutral-100" }),
2745
- /* @__PURE__ */ jsx("div", { className: "mt-4 h-3 w-3/4 rounded bg-neutral-200" }),
2746
- /* @__PURE__ */ jsx("div", { className: "mt-2 h-3 w-1/2 rounded bg-neutral-100" })
2747
- ]
2748
- }
2749
- );
2750
- }
2751
- function productPreviewCount(section, carousel) {
2752
- const configuredBlocks = orderedBlocks(section.blocks).length;
2753
- if (configuredBlocks > 0) {
2754
- return configuredBlocks;
2755
- }
2756
- return settingNumber(section.settings, "limit", carousel ? 5 : 8);
2757
- }
2758
- function createPreviewCollections(section) {
2759
- const count = Math.min(settingNumber(section.settings, "limit", 6), 6);
2760
- return Array.from({ length: count }, (_, index) => ({
2761
- id: `preview-collection-${index + 1}`,
2762
- name: `Categoria ${index + 1}`,
2763
- href: "/store/collections/all",
2764
- imageUrl: DEFAULT_CMS_IMAGE_URL
2765
- }));
2766
- }
2767
- function LayoutSection({ section, renderSections }) {
2768
- const settings = section.settings ?? {};
2769
- const paddingY = settingString(settings, "paddingY") || "medium";
2770
- const maxWidth = settingString(settings, "maxWidth") || "container";
2771
- const background = settingString(settings, "background") || "default";
2772
- return /* @__PURE__ */ jsx(
2773
- "section",
2774
- {
2775
- className: `${layoutBackground(background)} ${layoutPadding(paddingY)}`,
2776
- children: /* @__PURE__ */ jsx("div", { className: `mx-auto px-4 ${layoutMaxWidth(maxWidth)}`, children: renderSections(layoutChildren(settings, "content")) })
2777
- }
2778
- );
2779
- }
2780
- function LayoutGrid({ section, renderSections }) {
2781
- const settings = section.settings ?? {};
2782
- const columnCount = Math.min(
2783
- Math.max(Math.round(settingNumber(settings, "columnCount", 2)), 1),
2784
- 6
2785
- );
2786
- return /* @__PURE__ */ jsx(
2787
- "div",
2788
- {
2789
- className: `grid ${layoutGap(settingString(settings, "gap"))}`,
2790
- style: {
2791
- gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))`
2792
- },
2793
- children: renderSections(layoutChildren(settings, "content"))
2794
- }
2795
- );
2796
- }
2797
- function LayoutFlex({ section, renderSections }) {
2798
- const settings = section.settings ?? {};
2799
- return /* @__PURE__ */ jsx(
2800
- "div",
2801
- {
2802
- className: [
2803
- "flex",
2804
- settingString(settings, "direction") === "column" ? "flex-col" : "flex-col md:flex-row",
2805
- settingString(settings, "wrap") === "nowrap" ? "flex-nowrap" : "flex-wrap",
2806
- layoutGap(settingString(settings, "gap")),
2807
- layoutAlign(settingString(settings, "align")),
2808
- layoutJustify(settingString(settings, "justify"))
2809
- ].join(" "),
2810
- children: renderSections(layoutChildren(settings, "content"))
2811
- }
2812
- );
2813
- }
2814
- function LayoutSpace({ section }) {
2815
- const settings = section.settings ?? {};
2816
- const size = settingString(settings, "size") || "24px";
2817
- const direction = settingString(settings, "direction") || "vertical";
2818
- const isHorizontal = direction === "horizontal";
2819
- const isBoth = direction === "both";
2820
- return /* @__PURE__ */ jsx(
2821
- "div",
2822
- {
2823
- "aria-hidden": "true",
2824
- style: {
2825
- display: "block",
2826
- width: isHorizontal || isBoth ? size : "100%",
2827
- height: isHorizontal ? "100%" : size
2828
- }
2829
- }
2830
- );
2831
- }
2832
- function CmsSectionsRenderer({
2833
- sections,
2834
- sectionData,
2835
- linkComponent,
2836
- currency = "PEN",
2837
- preview = false,
2838
- wrap = true
2839
- }) {
2840
- const LinkComponent = linkComponent ?? DefaultLink;
2841
- const sortedSections = [...sections].sort((a, b) => a.order - b.order);
2842
- const content = /* @__PURE__ */ jsx(Fragment, { children: sortedSections.map((section, index) => {
2843
- const sectionKey = getCmsSectionKey(section, index);
2844
- return /* @__PURE__ */ jsx(
2845
- CmsSection,
2846
- {
2847
- section,
2848
- data: sectionData?.[sectionKey],
2849
- linkComponent: LinkComponent,
2850
- currency,
2851
- preview
2852
- },
2853
- sectionKey
2854
- );
2855
- }) });
2856
- return wrap ? /* @__PURE__ */ jsx("div", { className: "relative", children: content }) : content;
2857
- }
2858
- function CmsSection({
2859
- section,
2860
- data,
2861
- linkComponent,
2862
- currency,
2863
- preview
2864
- }) {
2865
- const type = canonicalSectionType(section.type);
2866
- const renderSections = (sections) => /* @__PURE__ */ jsx(
2867
- CmsSectionsRenderer,
2868
- {
2869
- sections,
2870
- linkComponent,
2871
- currency,
2872
- preview,
2873
- wrap: false
2874
- }
2875
- );
2876
- if (type === "layout-section") {
2877
- return /* @__PURE__ */ jsx(
2878
- LayoutSection,
2879
- {
2880
- section,
2881
- linkComponent,
2882
- currency,
2883
- preview,
2884
- renderSections
2885
- }
2886
- );
2887
- }
2888
- if (type === "layout-grid") {
2889
- return /* @__PURE__ */ jsx(
2890
- LayoutGrid,
2891
- {
2892
- section,
2893
- linkComponent,
2894
- currency,
2895
- preview,
2896
- renderSections
2897
- }
2898
- );
2899
- }
2900
- if (type === "layout-flex") {
2901
- return /* @__PURE__ */ jsx(
2902
- LayoutFlex,
2903
- {
2904
- section,
2905
- linkComponent,
2906
- currency,
2907
- preview,
2908
- renderSections
2909
- }
2910
- );
2911
- }
2912
- if (type === "layout-space") {
2913
- return /* @__PURE__ */ jsx(
2914
- LayoutSpace,
2915
- {
2916
- section,
2917
- linkComponent,
2918
- currency,
2919
- preview,
2920
- renderSections
2921
- }
2922
- );
2923
- }
2924
- if (type === "hero") {
2925
- return /* @__PURE__ */ jsx(HeroSection, { section, linkComponent });
2926
- }
2927
- if (type === "announcement-bar") {
2928
- return /* @__PURE__ */ jsx(AnnouncementBarSection, { section, linkComponent });
2929
- }
2930
- if (type === "product-list" || type === "product-carousel") {
2931
- return /* @__PURE__ */ jsx(
2932
- ProductsSection,
2933
- {
2934
- section,
2935
- products: data?.products ?? [],
2936
- carousel: type === "product-carousel",
2937
- linkComponent,
2938
- currency,
2939
- preview
2940
- }
2941
- );
2942
- }
2943
- if (type === "category-grid" || type === "collection-list") {
2944
- return /* @__PURE__ */ jsx(
2945
- CategoryGridSection,
2946
- {
2947
- section,
2948
- collections: data?.collections ?? [],
2949
- linkComponent,
2950
- preview
2951
- }
2952
- );
2953
- }
2954
- if (type === "promo-cards") {
2955
- return /* @__PURE__ */ jsx(PromoCardsSection, { section, linkComponent });
2956
- }
2957
- if (type === "rich-text" || type === "seo-text") {
2958
- return /* @__PURE__ */ jsx(RichTextSection, { section });
2959
- }
2960
- if (type === "custom-html") {
2961
- return /* @__PURE__ */ jsx(CustomHtmlSection, { section });
2962
- }
2963
- if (type === "floating-block") {
2964
- return /* @__PURE__ */ jsx(FloatingBlockSection, { section, linkComponent });
2965
- }
2966
- if (type === "faq") {
2967
- return /* @__PURE__ */ jsx(FaqSection, { section });
2968
- }
2969
- if (type === "newsletter") {
2970
- return /* @__PURE__ */ jsx(NewsletterSection, { section });
2971
- }
2972
- if (type === "trust-badges" || type === "widget-row") {
2973
- return /* @__PURE__ */ jsx(IconRowSection, { section, linkComponent });
2974
- }
2975
- if (type === "logo-slider") {
2976
- return /* @__PURE__ */ jsx(LogoSliderSection, { section, linkComponent });
2977
- }
2978
- if (type === "testimonials") {
2979
- return /* @__PURE__ */ jsx(TestimonialsSection, { section });
2980
- }
2981
- if (type === "stats") {
2982
- return /* @__PURE__ */ jsx(StatsSection, { section });
2983
- }
2984
- if (type === "timeline") {
2985
- return /* @__PURE__ */ jsx(TimelineSection, { section });
2986
- }
2987
- if (type === "contact-form") {
2988
- return /* @__PURE__ */ jsx(ContactFormSection, { section });
2989
- }
2990
- return /* @__PURE__ */ jsx(UnknownSection, { section });
2991
- }
2992
2441
  function buildOptionGroups(variants) {
2993
2442
  const map = /* @__PURE__ */ new Map();
2994
2443
  for (const v of variants) {
@@ -3097,88 +2546,6 @@ function ProductVariantSelector({
3097
2546
  })
3098
2547
  ] });
3099
2548
  }
3100
- function SafeThemeInjector({ theme, className }) {
3101
- try {
3102
- if (!theme || typeof theme !== "object") {
3103
- console.warn("ThemeInjector: Invalid theme provided");
3104
- return null;
3105
- }
3106
- if (!theme.colors || typeof theme.colors !== "object") {
3107
- console.warn("ThemeInjector: Theme colors are required");
3108
- return null;
3109
- }
3110
- const generateSafeCSSVariables = () => {
3111
- const cssRules = [":root {"];
3112
- const toKebabCase = (input) => input.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/_/g, "-").toLowerCase();
3113
- const sanitizeCSSValue = (value) => {
3114
- if (typeof value !== "string") return null;
3115
- const trimmed = value.trim();
3116
- if (!trimmed) return null;
3117
- const isValidCSSValue = /^[a-zA-Z0-9\s,()#.-]+$/.test(trimmed);
3118
- return isValidCSSValue ? trimmed : null;
3119
- };
3120
- if (theme.colors && typeof theme.colors === "object") {
3121
- Object.entries(theme.colors).forEach(([key, value]) => {
3122
- const sanitizedValue = sanitizeCSSValue(value);
3123
- if (sanitizedValue) {
3124
- cssRules.push(` --color-${key}: ${sanitizedValue};`);
3125
- cssRules.push(` --theme-${key}: ${sanitizedValue};`);
3126
- cssRules.push(` --${key}: ${sanitizedValue};`);
3127
- cssRules.push(` --${toKebabCase(key)}: ${sanitizedValue};`);
3128
- }
3129
- });
3130
- }
3131
- if (theme.fonts && typeof theme.fonts === "object") {
3132
- Object.entries(theme.fonts).forEach(([key, value]) => {
3133
- const sanitizedValue = sanitizeCSSValue(value);
3134
- if (sanitizedValue) {
3135
- cssRules.push(` --font-${key}: ${sanitizedValue};`);
3136
- }
3137
- });
3138
- }
3139
- if (theme.spacing && typeof theme.spacing === "object") {
3140
- Object.entries(theme.spacing).forEach(([key, value]) => {
3141
- const sanitizedValue = sanitizeCSSValue(value);
3142
- if (sanitizedValue) {
3143
- cssRules.push(` --spacing-${key}: ${sanitizedValue};`);
3144
- }
3145
- });
3146
- }
3147
- if (theme.borderRadius && typeof theme.borderRadius === "object") {
3148
- Object.entries(theme.borderRadius).forEach(([key, value]) => {
3149
- const sanitizedValue = sanitizeCSSValue(value);
3150
- if (sanitizedValue) {
3151
- cssRules.push(` --radius-${key}: ${sanitizedValue};`);
3152
- }
3153
- });
3154
- }
3155
- if (theme.shadows && typeof theme.shadows === "object") {
3156
- Object.entries(theme.shadows).forEach(([key, value]) => {
3157
- const sanitizedValue = sanitizeCSSValue(value);
3158
- if (sanitizedValue) {
3159
- cssRules.push(` --shadow-${key}: ${sanitizedValue};`);
3160
- }
3161
- });
3162
- }
3163
- cssRules.push("}");
3164
- return cssRules.join("\n");
3165
- };
3166
- const cssVariables = generateSafeCSSVariables();
3167
- return /* @__PURE__ */ jsx(
3168
- "style",
3169
- {
3170
- dangerouslySetInnerHTML: { __html: cssVariables },
3171
- "data-theme-injector": theme.id,
3172
- "data-theme-name": theme.name,
3173
- className,
3174
- suppressHydrationWarning: true
3175
- }
3176
- );
3177
- } catch (error) {
3178
- console.error("ThemeInjector: Error generating theme styles", error);
3179
- return null;
3180
- }
3181
- }
3182
2549
  function isRenderableCmsPage(p) {
3183
2550
  if (!p.status) return true;
3184
2551
  return p.status === "published";
@@ -3194,6 +2561,6 @@ function findStorefrontCmsPageBySlug(settings, slug) {
3194
2561
  return parsed.success ? parsed.data : null;
3195
2562
  }
3196
2563
 
3197
- export { CartAddressesRequestSchema, CartBuyerRequestSchema, CartCheckoutPaymentActionSchema, CartCheckoutPaymentSchema, CartCheckoutReadResponseSchema, CartCheckoutRequestSchema, CartCheckoutResponseSchema, CartCouponRequestSchema, CartCreateRequestSchema, CartItemModifierRequestSchema, CartItemRequestSchema, CartPaymentMethodSchema, CartPaymentMethodsResponseSchema, CartPaymentReceiptResponseSchema, CartResponseBundleItemSchema, CartResponseItemSchema, CartResponseSchema, CartShippingMethodPutRequestSchema, CmsSectionsRenderer, DEFAULT_CMS_IMAGE_URL, ProductSchema, ProductVariantSchema, ProductVariantSelector, ProductsFiltersSchema, ProductsResponseSchema, QueryProvider, STOREFRONT_API_PATH_PREFIX, STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME, STOREFRONT_ECOMIQ_OAUTH_COOKIE_PATH, SafeThemeInjector, ShippingOptionGroupSchema, ShippingOptionsResponseSchema, ShippingRateSchema, StorefrontAuthProvider, StorefrontBundleItemSchema, StorefrontCheckoutSettingsSchema, StorefrontCollectionDetailSchema, StorefrontCollectionSchema, StorefrontCollectionsResponseSchema, StorefrontPageDetailSchema, StorefrontPageListItemSchema, StorefrontPriceTierSchema, StorefrontProductDetailSchema, StorefrontProductSchema, StorefrontProductsParamsSchema, StorefrontProductsResponseSchema, StorefrontSettingsLegacyFlatSchema, StorefrontSettingsSchema, StorefrontStoreSchema, apiClient, canonicalSectionType, cartService, collectionService, countryCurrency, customerOrderStatusTone, ecomiqOAuthPassword, ecomiqOAuthPasswordClient, fetchStorefrontGeoDistricts, fetchStorefrontGeoProvinces, findStorefrontCmsPageBySlug, formatCurrency, formatCustomerOrderStatus, formatOrderDate, formatOrderDateTime, getCmsSectionKey, loadStorefrontGeoDepartments, normalizeStorefrontSettingsPayload, pageService, productService, productSortValue, resolveIneiCodesFromLabels, sanitizeHtml, storeService, storefrontAccessTokenNeedsRefresh, storefrontFaviconUrl, storefrontHref, storefrontOgImageUrl, storefrontSessionEndsSoon, storefrontStoreRecord, toGeoItems, useCart, useCartAddresses, useCartCreate, useCartGet, useCollections, useConfig, usePages, useProducts, useStore, useStorefrontAuthClient, useStorefrontGeoInei, useStorefrontSession, useUser };
2564
+ export { CartAddressesRequestSchema, CartBuyerRequestSchema, CartCheckoutPaymentActionSchema, CartCheckoutPaymentSchema, CartCheckoutReadResponseSchema, CartCheckoutRequestSchema, CartCheckoutResponseSchema, CartCouponRequestSchema, CartCreateRequestSchema, CartItemModifierRequestSchema, CartItemRequestSchema, CartPaymentMethodSchema, CartPaymentMethodsResponseSchema, CartPaymentReceiptResponseSchema, CartResponseBundleItemSchema, CartResponseItemSchema, CartResponseSchema, CartShippingMethodPutRequestSchema, EcomiqProvider, ProductSchema, ProductVariantSchema, ProductVariantSelector, ProductsFiltersSchema, ProductsResponseSchema, QueryProvider, STOREFRONT_API_PATH_PREFIX, STOREFRONT_ECOMIQ_OAUTH_COOKIE_NAME, STOREFRONT_ECOMIQ_OAUTH_COOKIE_PATH, ShippingOptionGroupSchema, ShippingOptionsResponseSchema, ShippingRateSchema, StorefrontAuthProvider, StorefrontBundleItemSchema, StorefrontCheckoutSettingsSchema, StorefrontCollectionDetailSchema, StorefrontCollectionSchema, StorefrontCollectionsResponseSchema, StorefrontPageDetailSchema, StorefrontPageListItemSchema, StorefrontPriceTierSchema, StorefrontProductDetailSchema, StorefrontProductSchema, StorefrontProductsParamsSchema, StorefrontProductsResponseSchema, StorefrontSettingsLegacyFlatSchema, StorefrontSettingsSchema, StorefrontStoreSchema, apiClient, cartService, collectionService, countryCurrency, customerOrderStatusTone, ecomiqOAuthPassword, ecomiqOAuthPasswordClient, fetchStorefrontGeoDistricts, fetchStorefrontGeoProvinces, findStorefrontCmsPageBySlug, formatCurrency, formatCustomerOrderStatus, formatOrderDate, formatOrderDateTime, loadStorefrontGeoDepartments, normalizeStorefrontSettingsPayload, pageService, productService, resolveIneiCodesFromLabels, storeService, storefrontAccessTokenNeedsRefresh, storefrontFaviconUrl, storefrontOgImageUrl, storefrontSessionEndsSoon, storefrontStoreRecord, toGeoItems, useCart, useCartAddresses, useCartCreate, useCartGet, useCollections, useConfig, usePages, useProducts, useStore, useStorefrontAuthClient, useStorefrontGeoInei, useStorefrontSession, useUser };
3198
2565
  //# sourceMappingURL=react.js.map
3199
2566
  //# sourceMappingURL=react.js.map