@ecomiq/storefront 2.1.4 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +150 -103
- package/dist/account-Dx4e3syi.js +258 -0
- package/dist/account-forms-AVk71ko7.js +39 -0
- package/dist/account-forms.d.ts +13 -0
- package/dist/account.d.ts +240 -0
- package/dist/address-defaults-BqjRhS82.js +14 -0
- package/dist/address-defaults.d.ts +11 -0
- package/dist/analytics/analytics-CG1Qagwl.js +148 -0
- package/dist/analytics/analytics.d.ts +1 -0
- package/dist/analytics/config-DJr-GRhs.js +62 -0
- package/dist/analytics/config.d.ts +22 -0
- package/dist/analytics/consent-B13rBpBs.js +57 -0
- package/dist/analytics/consent-banner-9QvRRy8v.js +239 -0
- package/dist/analytics/consent-banner.d.ts +20 -0
- package/dist/analytics/cookies-pLozllyB.js +100 -0
- package/dist/analytics/cookies.d.ts +6 -0
- package/dist/analytics/destinations-iECrlLIr.js +144 -0
- package/dist/analytics/events-Dt81tIp1.js +102 -0
- package/dist/analytics/events.d.ts +51 -0
- package/dist/analytics/tracker-p4yaoOyk.js +51 -0
- package/dist/api-cache-DsuIn5hX.js +159 -0
- package/dist/bank-accounts-DlEczQQ5.js +81 -0
- package/dist/bank-accounts.d.ts +4 -0
- package/dist/captcha-DAqaIx8m.js +117 -0
- package/dist/captcha.d.ts +34 -0
- package/dist/cart-D7DxZ2lD.js +30 -0
- package/dist/cart-actions-Bsub_FFG.js +116 -0
- package/dist/cart-actions.d.ts +15 -0
- package/dist/cart-drawer-B7PPsR69.js +22 -0
- package/dist/cart-drawer.d.ts +9 -0
- package/dist/cart-form-y9P1r_EX.js +81 -0
- package/dist/cart-form.d.ts +24 -0
- package/dist/cart-summary-ur2VWKr-.js +89 -0
- package/dist/cart-summary.d.ts +31 -0
- package/dist/cart.d.ts +4 -0
- package/dist/catalog-7gJ-l5hW.js +67 -0
- package/dist/catalog-hooks-B7ZP4wYY.js +312 -0
- package/dist/catalog-hooks.d.ts +111 -0
- package/dist/catalog.d.ts +5 -0
- package/dist/checkout-DVWSXANi.js +474 -0
- package/dist/checkout-form-CbOIdENC.js +131 -0
- package/dist/checkout-form.d.ts +20 -0
- package/dist/checkout.d.ts +86 -0
- package/dist/complaint-book-BvwLvfx0.js +117 -0
- package/dist/complaint-book.d.ts +62 -0
- package/dist/culqi-authentication-BGr20vAJ.js +204 -0
- package/dist/culqi-authentication.d.ts +15 -0
- package/dist/culqi-checkout-CTXpKgp_.js +55 -0
- package/dist/culqi-three-ds-HP3mfrvV.js +33 -0
- package/dist/culqi-three-ds.d.ts +29 -0
- package/dist/customer-avatar-CJXSDroK.js +12 -0
- package/dist/customer-avatar.d.ts +5 -0
- package/dist/customer-cookies-DHOgFAMV.js +45 -0
- package/dist/customer-csrf-C1oDX-Py.js +17 -0
- package/dist/customer-csrf.d.ts +3 -0
- package/dist/customer-document-fields-C1K-_DAD.js +70 -0
- package/dist/customer-document-fields.d.ts +9 -0
- package/dist/customer-login-form-C7AC6vXd.js +144 -0
- package/dist/customer-login-form.d.ts +17 -0
- package/dist/customer-registration-form-BEm_NEfP.js +93 -0
- package/dist/customer-registration-form.d.ts +8 -0
- package/dist/document-url-CGsAl5Tf.js +9 -0
- package/dist/documents-T1mzc_j8.js +38 -0
- package/dist/documents.d.ts +16 -0
- package/dist/entries/account.d.ts +11 -0
- package/dist/entries/account.js +10 -0
- package/dist/entries/analytics.d.ts +6 -0
- package/dist/entries/analytics.js +5 -0
- package/dist/entries/cart.d.ts +8 -0
- package/dist/entries/cart.js +7 -0
- package/dist/entries/checkout.d.ts +12 -0
- package/dist/entries/checkout.js +11 -0
- package/dist/entries/order.d.ts +11 -0
- package/dist/entries/order.js +11 -0
- package/dist/favicon-YpyhVJ9H.js +28 -0
- package/dist/favicon.d.ts +4 -0
- package/dist/form-BtQcbXlJ.js +18 -0
- package/dist/form-contracts-BNpHaTGJ.js +166 -0
- package/dist/form-contracts.d.ts +42 -0
- package/dist/form.d.ts +3 -0
- package/dist/hidden-CCWtOWKR.js +3 -0
- package/dist/hidden.d.ts +4 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +50 -0
- package/dist/invoice-fields-BG0HjL6T.js +103 -0
- package/dist/invoice-fields.d.ts +39 -0
- package/dist/links-kFxBZfdb.js +96 -0
- package/dist/links.d.ts +21 -0
- package/dist/mercadopago-checkout-DC7RXa8k.js +27 -0
- package/dist/mercadopago-dialog-UTQev0MG.js +180 -0
- package/dist/mercadopago-dialog.d.ts +21 -0
- package/dist/money-DtGOtDri.js +32 -0
- package/dist/money.d.ts +1 -0
- package/dist/optimistic-cart-BveVOHuh.js +53 -0
- package/dist/optimistic-cart.d.ts +16 -0
- package/dist/order-display-DTt5WBbc.js +112 -0
- package/dist/order-display.d.ts +20 -0
- package/dist/order-draft-DxV1Uhm3.js +38 -0
- package/dist/order-draft.d.ts +16 -0
- package/dist/order-pages-Dm6l5m0m.js +38 -0
- package/dist/order-pages.d.ts +12 -0
- package/dist/order-payment-continuation-D_d5PGA4.js +212 -0
- package/dist/order-payment-continuation.d.ts +10 -0
- package/dist/order-payment-in-review-x4gdLFHZ.js +65 -0
- package/dist/order-payment-in-review.d.ts +5 -0
- package/dist/order-status-BJXLJwxq.js +162 -0
- package/dist/order-status.d.ts +89 -0
- package/dist/order-view-9IlBg5AF.js +62 -0
- package/dist/order-view.d.ts +12 -0
- package/dist/page-action-Ctkf4xC6.js +7 -0
- package/dist/page-seo-a5FJl8x5.js +262 -0
- package/dist/page-seo.d.ts +34 -0
- package/dist/pages-Ca_Gt6mq.js +150 -0
- package/dist/pages.d.ts +45 -0
- package/dist/payment-dialog-frame-B-Q_xQ94.js +57 -0
- package/dist/payment-logo-BoPaGJc_.js +46 -0
- package/dist/payment-logo-svgs-By9lDTLK.js +20 -0
- package/dist/payment-logo.d.ts +11 -0
- package/dist/payment-logos-BYvdwYyJ.js +23 -0
- package/dist/payment-methods-B8ocTgFZ.js +73 -0
- package/dist/payment-methods.d.ts +58 -0
- package/dist/payment-return-5cjypwIw.js +7 -0
- package/dist/place-CmW4hBWY.js +13 -0
- package/dist/place.d.ts +4 -0
- package/dist/preview-BiIBif3C.js +427 -0
- package/dist/preview-address-Cf0sJ-9p.js +21 -0
- package/dist/preview-cart-Dg2CVktS.js +376 -0
- package/dist/product-preview-BspMAecJ.js +51 -0
- package/dist/product-preview.d.ts +5 -0
- package/dist/product-variants-BNDHvs1y.js +46 -0
- package/dist/product-variants.d.ts +12 -0
- package/dist/public-pages-XtwlaLwt.js +194 -0
- package/dist/public-pages.d.ts +67 -0
- package/dist/registration-CpDcv8ql.js +91 -0
- package/dist/registration.d.ts +12 -0
- package/dist/request-security-CRsRMgwj.js +76 -0
- package/dist/rich-text-M-Ju8RL4.js +9 -0
- package/dist/rich-text.d.ts +5 -0
- package/dist/route-text-DcJw2SsK.js +9 -0
- package/dist/route-text.d.ts +4 -0
- package/dist/section-preview-CmsMl3yu.js +83 -0
- package/dist/section-preview.d.ts +12 -0
- package/dist/sections/account-addresses.d.ts +18 -0
- package/dist/sections/account-addresses.js +375 -0
- package/dist/sections/account-order.d.ts +12 -0
- package/dist/sections/account-order.js +592 -0
- package/dist/sections/account-orders.d.ts +8 -0
- package/dist/sections/account-orders.js +359 -0
- package/dist/sections/account-profile.d.ts +16 -0
- package/dist/sections/account-profile.js +123 -0
- package/dist/sections/checkout.d.ts +24 -0
- package/dist/sections/checkout.js +963 -0
- package/dist/sections/complaint-book.d.ts +8 -0
- package/dist/sections/complaint-book.js +538 -0
- package/dist/sections/design-system.d.ts +1 -0
- package/dist/sections/design-system.js +310 -0
- package/dist/sections/draft-invoice.d.ts +20 -0
- package/dist/sections/draft-invoice.js +158 -0
- package/dist/sections/order-tracking.d.ts +19 -0
- package/dist/sections/order-tracking.js +141 -0
- package/dist/sections-CNUMWTF_.js +77 -0
- package/dist/sections.d.ts +19 -0
- package/dist/seo-GpDRhAAA.js +78 -0
- package/dist/session-CKvmFJyg.js +379 -0
- package/dist/session.d.ts +24 -0
- package/dist/settings-B0NO2A6Y.js +78 -0
- package/dist/settings.d.ts +51 -0
- package/dist/source-marker-DhqSkW7n.js +4 -0
- package/dist/sources-B-3JFJfb.js +46 -0
- package/dist/sources.d.ts +7 -0
- package/dist/store-8Q-_LFrQ.js +152 -0
- package/dist/store-contact--hY6CoFb.js +19 -0
- package/dist/store-contact.d.ts +6 -0
- package/dist/store.d.ts +17 -0
- package/dist/storefront-language-DrMjVbmk.js +29 -0
- package/dist/storefront-language.d.ts +14 -0
- package/dist/storefront-text-D25ae1qf.js +11 -0
- package/dist/storefront-text-en-ljjjSS4q.js +1030 -0
- package/dist/storefront-text-pt-BtHaJLcp.js +1030 -0
- package/dist/storefront-text.d.ts +4 -0
- package/dist/stripe-dialog-Ev9s3Z62.js +396 -0
- package/dist/stripe-dialog.d.ts +30 -0
- package/dist/telemetry-HuZXWBPi.js +114 -0
- package/dist/telemetry.d.ts +10 -0
- package/dist/templates-CAqoNyTW.js +40 -0
- package/dist/templates.d.ts +15 -0
- package/dist/urls-CpGQPxvf.js +71 -0
- package/dist/urls.d.ts +18 -0
- package/dist/use-checkout-CZcxXJXi.js +42 -0
- package/dist/use-checkout-payment-9R-zacrJ.js +80 -0
- package/dist/use-checkout-payment.d.ts +18 -0
- package/dist/use-checkout.d.ts +36 -0
- package/dist/use-culqi-checkout-CrjLAipU.js +109 -0
- package/dist/use-order-payment-BKIz_IO0.js +45 -0
- package/dist/use-order-payment.d.ts +18 -0
- package/dist/use-payment-token-CErx-tN-.js +105 -0
- package/dist/vite-payment-logos-kziu7wKb.js +27 -0
- package/dist/vite-payment-logos.d.ts +24 -0
- package/dist/vite-public-assets-DW2fgtVb.js +209 -0
- package/dist/vite-public-assets.d.ts +29 -0
- package/dist/vite-sections-DTBr0-Kg.js +464 -0
- package/dist/vite-sections.d.ts +21 -0
- package/dist/vite-theme-ui-BMO-CDi3.js +41 -0
- package/dist/vite-theme-ui.d.ts +10 -0
- package/dist/vite.d.ts +36 -0
- package/dist/vite.js +127 -0
- package/dist/voucher-payment-CVFDZ1L8.js +66 -0
- package/dist/worker-CNi-gzCu.js +86 -0
- package/dist/worker.d.ts +27 -0
- package/package.json +100 -76
- package/src/sections/account-addresses.tsx +215 -0
- package/src/sections/account-order.tsx +424 -0
- package/src/sections/account-orders.tsx +259 -0
- package/src/sections/account-profile.tsx +70 -0
- package/src/sections/checkout.tsx +586 -0
- package/src/sections/complaint-book.tsx +325 -0
- package/src/sections/design-system.tsx +146 -0
- package/src/sections/draft-invoice.tsx +105 -0
- package/src/sections/order-tracking.tsx +81 -0
- package/src/vite-client.d.ts +4 -0
- package/bin/ecomiq.mjs +0 -179
- package/public/design-bridge.js +0 -318
- package/src/api-proxy.ts +0 -194
- package/src/auth/create-storefront-auth.ts +0 -94
- package/src/auth/ecomiq-oauth-password-client.ts +0 -26
- package/src/auth/ecomiq-oauth-password-constants.ts +0 -24
- package/src/auth/ecomiq-oauth-password-plugin.ts +0 -294
- package/src/auth/ecomiq-oauth-password-types.ts +0 -24
- package/src/auth/ecomiq-storefront-sign-in.ts +0 -44
- package/src/auth/env.ts +0 -7
- package/src/auth/secure-cookies.ts +0 -23
- package/src/auth/storefront-auth-base-url.ts +0 -117
- package/src/auth/storefront-auth.ts +0 -7
- package/src/cart-session.ts +0 -239
- package/src/client.ts +0 -48
- package/src/codegen.mjs +0 -801
- package/src/components/account/customer-addresses-panel.tsx +0 -678
- package/src/components/account/customer-order-detail-panel.tsx +0 -285
- package/src/components/account/customer-orders-panel.tsx +0 -192
- package/src/components/account/customer-profile-panel.tsx +0 -379
- package/src/components/checkout/cart-sync.ts +0 -143
- package/src/components/checkout/checkout-contact-section.tsx +0 -76
- package/src/components/checkout/checkout-external-update-banner.tsx +0 -15
- package/src/components/checkout/checkout-form-controls.tsx +0 -139
- package/src/components/checkout/checkout-line-items.tsx +0 -43
- package/src/components/checkout/checkout-order-summary.tsx +0 -165
- package/src/components/checkout/checkout-payment-section.tsx +0 -212
- package/src/components/checkout/checkout-session-view.tsx +0 -564
- package/src/components/checkout/checkout-shipping-address-section.tsx +0 -400
- package/src/components/checkout/checkout-shipping-section.tsx +0 -98
- package/src/components/checkout/checkout-states.tsx +0 -73
- package/src/components/checkout/checkout-step-card.tsx +0 -101
- package/src/components/checkout/checkout-steps.ts +0 -111
- package/src/components/checkout/form-schema.ts +0 -281
- package/src/components/checkout/format.ts +0 -15
- package/src/components/checkout/index.ts +0 -5
- package/src/components/checkout/map-customer-to-checkout.ts +0 -188
- package/src/components/checkout/types.ts +0 -41
- package/src/components/checkout/use-checkout-customer-prefill.ts +0 -409
- package/src/components/checkout/use-checkout-geo.ts +0 -50
- package/src/components/checkout/use-checkout-session.ts +0 -640
- package/src/components/hero.tsx +0 -291
- package/src/config.d.ts +0 -94
- package/src/config.mjs +0 -146
- package/src/format-money.ts +0 -31
- package/src/health.ts +0 -90
- package/src/hooks/index.ts +0 -9
- package/src/hooks/recently-viewed.ts +0 -125
- package/src/index.ts +0 -349
- package/src/link.tsx +0 -2
- package/src/pages/account/account-page-skeleton.tsx +0 -69
- package/src/pages/account/account-page-view.tsx +0 -270
- package/src/pages/account/account-shell.tsx +0 -101
- package/src/pages/account/parse-account-route.ts +0 -36
- package/src/pages/account.tsx +0 -16
- package/src/pages/api.$.ts +0 -20
- package/src/pages/api.auth.$.ts +0 -16
- package/src/pages/checkout.$checkoutId.tsx +0 -60
- package/src/pages/checkout.tsx +0 -31
- package/src/pages/pages.$pageSlug.tsx +0 -74
- package/src/pages/thank-you.tsx +0 -53
- package/src/providers/auth.tsx +0 -96
- package/src/providers/cart.tsx +0 -275
- package/src/providers/ecomiq.ts +0 -137
- package/src/providers/index.ts +0 -26
- package/src/proxy-api.ts +0 -20
- package/src/public-config.ts +0 -24
- package/src/review-submission.ts +0 -89
- package/src/runtime/context.ts +0 -2
- package/src/runtime/default-layout.tsx +0 -64
- package/src/runtime/head.ts +0 -149
- package/src/runtime/page.tsx +0 -143
- package/src/runtime/postcss-browser-stub.mjs +0 -5
- package/src/server-config-store.ts +0 -35
- package/src/server.ts +0 -286
- package/src/styles.css +0 -76
- package/src/ui/badge.tsx +0 -32
- package/src/ui/button.tsx +0 -31
- package/src/ui/card.tsx +0 -31
- package/src/ui/carousel.tsx +0 -218
- package/src/ui/cn.ts +0 -6
- package/src/ui/index.ts +0 -8
- package/src/ui/separator.tsx +0 -6
- package/src/ui/skeleton.tsx +0 -6
- package/src/ui/storefront-error.tsx +0 -49
- package/src/utils.ts +0 -36
- package/src/vite-inline.mjs +0 -263
- package/templates/__root.tsx +0 -83
- package/templates/router.tsx +0 -19
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { consentPurposes, installConsent, onConsent, onConsentOpen, openConsent } from "./consent-B13rBpBs.js";
|
|
2
|
+
import { Link, useRouteLoaderData } from "react-router";
|
|
3
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
4
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
// src/analytics/consent-banner.tsx
|
|
6
|
+
const PURPOSES = ["analytics", "marketing"];
|
|
7
|
+
const REJECTED = {
|
|
8
|
+
analytics: false,
|
|
9
|
+
marketing: false
|
|
10
|
+
};
|
|
11
|
+
const ACCEPTED = {
|
|
12
|
+
analytics: true,
|
|
13
|
+
marketing: true
|
|
14
|
+
};
|
|
15
|
+
const COPY = {
|
|
16
|
+
es: {
|
|
17
|
+
label: "Cookies",
|
|
18
|
+
privacy: "Privacidad",
|
|
19
|
+
configure: "Configurar",
|
|
20
|
+
choose: "Elige qué aceptas. Las cookies necesarias para el carrito y tu sesión siempre están activas.",
|
|
21
|
+
accept: "Aceptar",
|
|
22
|
+
reject: "Rechazar",
|
|
23
|
+
save: "Guardar",
|
|
24
|
+
and: " y ",
|
|
25
|
+
others: "otros proveedores",
|
|
26
|
+
uses: {
|
|
27
|
+
analytics: "medir visitas",
|
|
28
|
+
marketing: "mostrarte publicidad"
|
|
29
|
+
},
|
|
30
|
+
options: {
|
|
31
|
+
analytics: {
|
|
32
|
+
name: "Medición",
|
|
33
|
+
use: "para contar visitas y compras"
|
|
34
|
+
},
|
|
35
|
+
marketing: {
|
|
36
|
+
name: "Publicidad",
|
|
37
|
+
use: "para medir campañas y mostrarte anuncios"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
notice: (providers, uses) => `Con tu permiso, usamos cookies de ${providers} para ${uses}. Los datos que recogen pueden tratarse fuera del país, por ejemplo en Estados Unidos. Puedes cambiar tu elección en «Cookies», al pie de la página.`
|
|
41
|
+
},
|
|
42
|
+
en: {
|
|
43
|
+
label: "Cookies",
|
|
44
|
+
privacy: "Privacy",
|
|
45
|
+
configure: "Customize",
|
|
46
|
+
choose: "Choose what you accept. Cookies needed for the cart and your session are always on.",
|
|
47
|
+
accept: "Accept",
|
|
48
|
+
reject: "Reject",
|
|
49
|
+
save: "Save",
|
|
50
|
+
and: " and ",
|
|
51
|
+
others: "other providers",
|
|
52
|
+
uses: {
|
|
53
|
+
analytics: "measure visits",
|
|
54
|
+
marketing: "show you ads"
|
|
55
|
+
},
|
|
56
|
+
options: {
|
|
57
|
+
analytics: {
|
|
58
|
+
name: "Measurement",
|
|
59
|
+
use: "to count visits and purchases"
|
|
60
|
+
},
|
|
61
|
+
marketing: {
|
|
62
|
+
name: "Advertising",
|
|
63
|
+
use: "to measure campaigns and show you ads"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
notice: (providers, uses) => `With your permission, we use cookies from ${providers} to ${uses}. The data they collect may be processed outside your country, for example in the United States. You can change your choice under “Cookies” at the bottom of the page.`
|
|
67
|
+
},
|
|
68
|
+
pt: {
|
|
69
|
+
label: "Cookies",
|
|
70
|
+
privacy: "Privacidade",
|
|
71
|
+
configure: "Configurar",
|
|
72
|
+
choose: "Escolha o que aceita. Os cookies necessários para o carrinho e a sua sessão estão sempre ativos.",
|
|
73
|
+
accept: "Aceitar",
|
|
74
|
+
reject: "Recusar",
|
|
75
|
+
save: "Salvar",
|
|
76
|
+
and: " e ",
|
|
77
|
+
others: "outros fornecedores",
|
|
78
|
+
uses: {
|
|
79
|
+
analytics: "medir visitas",
|
|
80
|
+
marketing: "mostrar publicidade"
|
|
81
|
+
},
|
|
82
|
+
options: {
|
|
83
|
+
analytics: {
|
|
84
|
+
name: "Medição",
|
|
85
|
+
use: "para contar visitas e compras"
|
|
86
|
+
},
|
|
87
|
+
marketing: {
|
|
88
|
+
name: "Publicidade",
|
|
89
|
+
use: "para medir campanhas e mostrar anúncios"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
notice: (providers, uses) => `Com a sua permissão, usamos cookies de ${providers} para ${uses}. Os dados que coletam podem ser tratados fora do país, por exemplo nos Estados Unidos. Você pode mudar sua escolha em “Cookies”, no rodapé da página.`
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
function consentCopy(language) {
|
|
96
|
+
return COPY[language.slice(0, 2).toLowerCase()] ?? COPY.es;
|
|
97
|
+
}
|
|
98
|
+
function useAnalyticsConfig() {
|
|
99
|
+
return useRouteLoaderData("root")?.analytics ?? null;
|
|
100
|
+
}
|
|
101
|
+
function providers(config, purpose) {
|
|
102
|
+
const generic = config.googleTagManager !== null || config.scripts !== null;
|
|
103
|
+
return {
|
|
104
|
+
google: purpose === "marketing" ? config.googleTagManager !== null : config.googleAnalytics !== null || config.googleTagManager !== null,
|
|
105
|
+
meta: purpose !== "analytics" && config.metaPixel !== null,
|
|
106
|
+
others: generic
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function providerNames(found, copy) {
|
|
110
|
+
const names = [];
|
|
111
|
+
if (found.google) names.push("Google");
|
|
112
|
+
if (found.meta) names.push("Meta");
|
|
113
|
+
if (found.others) names.push(copy.others);
|
|
114
|
+
const last = names.pop() ?? "";
|
|
115
|
+
if (names.length === 0) return last;
|
|
116
|
+
return `${names.join(", ")}${copy.and}${last}`;
|
|
117
|
+
}
|
|
118
|
+
function ConsentBanner({ className, classNames = {} }) {
|
|
119
|
+
const config = useAnalyticsConfig();
|
|
120
|
+
const version = config?.consentVersion ?? null;
|
|
121
|
+
const id = useId();
|
|
122
|
+
const [open, setOpen] = useState(false);
|
|
123
|
+
const [configuring, setConfiguring] = useState(false);
|
|
124
|
+
const [choice, setChoice] = useState(REJECTED);
|
|
125
|
+
const [focused, setFocused] = useState(0);
|
|
126
|
+
const banner = useRef(null);
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
if (config === null) return;
|
|
129
|
+
setOpen(installConsent(config).get() === null);
|
|
130
|
+
setConfiguring(false);
|
|
131
|
+
const stopChoice = onConsent(() => setOpen(false));
|
|
132
|
+
const stopOpen = onConsentOpen(() => {
|
|
133
|
+
setConfiguring(false);
|
|
134
|
+
setOpen(true);
|
|
135
|
+
setFocused((count) => count + 1);
|
|
136
|
+
});
|
|
137
|
+
return () => {
|
|
138
|
+
stopChoice();
|
|
139
|
+
stopOpen();
|
|
140
|
+
};
|
|
141
|
+
}, [version]);
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
if (focused > 0) banner.current?.focus();
|
|
144
|
+
}, [focused]);
|
|
145
|
+
if (config === null || !open) return null;
|
|
146
|
+
const copy = consentCopy(config.language);
|
|
147
|
+
const offered = consentPurposes(config);
|
|
148
|
+
const purposes = PURPOSES.filter((purpose) => offered[purpose]);
|
|
149
|
+
const choose = (consent) => installConsent(config).set(consent);
|
|
150
|
+
const configure = () => {
|
|
151
|
+
const current = installConsent(config).get();
|
|
152
|
+
setChoice(current === null ? REJECTED : {
|
|
153
|
+
analytics: current.analytics,
|
|
154
|
+
marketing: current.marketing
|
|
155
|
+
});
|
|
156
|
+
setConfiguring(true);
|
|
157
|
+
setFocused((count) => count + 1);
|
|
158
|
+
};
|
|
159
|
+
const privacy = config.privacy === null ? null : /* @__PURE__ */ jsxs(Fragment$1, { children: [" ", /* @__PURE__ */ jsx(Link, {
|
|
160
|
+
to: config.privacy,
|
|
161
|
+
className: classNames.link,
|
|
162
|
+
children: copy.privacy
|
|
163
|
+
})] });
|
|
164
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
165
|
+
ref: banner,
|
|
166
|
+
tabIndex: -1,
|
|
167
|
+
"aria-label": copy.label,
|
|
168
|
+
className,
|
|
169
|
+
children: [configuring ? /* @__PURE__ */ jsxs("div", {
|
|
170
|
+
className: classNames.options,
|
|
171
|
+
children: [/* @__PURE__ */ jsxs("p", {
|
|
172
|
+
className: classNames.text,
|
|
173
|
+
children: [copy.choose, privacy]
|
|
174
|
+
}), purposes.map((purpose) => /* @__PURE__ */ jsxs("p", {
|
|
175
|
+
className: classNames.option,
|
|
176
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
177
|
+
id: `${id}${purpose}`,
|
|
178
|
+
type: "checkbox",
|
|
179
|
+
checked: choice[purpose],
|
|
180
|
+
onChange: (event) => setChoice({
|
|
181
|
+
...choice,
|
|
182
|
+
[purpose]: event.currentTarget.checked
|
|
183
|
+
})
|
|
184
|
+
}), /* @__PURE__ */ jsxs("label", {
|
|
185
|
+
htmlFor: `${id}${purpose}`,
|
|
186
|
+
children: [
|
|
187
|
+
/* @__PURE__ */ jsx("strong", { children: copy.options[purpose].name }),
|
|
188
|
+
": ",
|
|
189
|
+
copy.options[purpose].use,
|
|
190
|
+
" (",
|
|
191
|
+
providerNames(providers(config, purpose), copy),
|
|
192
|
+
")."
|
|
193
|
+
]
|
|
194
|
+
})]
|
|
195
|
+
}, purpose))]
|
|
196
|
+
}) : /* @__PURE__ */ jsxs("p", {
|
|
197
|
+
className: classNames.text,
|
|
198
|
+
children: [
|
|
199
|
+
copy.notice(providerNames(providers(config, null), copy), purposes.map((purpose) => copy.uses[purpose]).join(copy.and)),
|
|
200
|
+
privacy,
|
|
201
|
+
purposes.length > 1 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [privacy === null ? " " : " · ", /* @__PURE__ */ jsx("button", {
|
|
202
|
+
type: "button",
|
|
203
|
+
className: classNames.configure ?? classNames.link,
|
|
204
|
+
onClick: configure,
|
|
205
|
+
children: copy.configure
|
|
206
|
+
})] }) : null
|
|
207
|
+
]
|
|
208
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
209
|
+
className: classNames.actions,
|
|
210
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
211
|
+
type: "button",
|
|
212
|
+
className: classNames.reject,
|
|
213
|
+
onClick: () => choose(REJECTED),
|
|
214
|
+
children: copy.reject
|
|
215
|
+
}), configuring ? /* @__PURE__ */ jsx("button", {
|
|
216
|
+
type: "button",
|
|
217
|
+
className: classNames.accept,
|
|
218
|
+
onClick: () => choose(choice),
|
|
219
|
+
children: copy.save
|
|
220
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
221
|
+
type: "button",
|
|
222
|
+
className: classNames.accept,
|
|
223
|
+
onClick: () => choose(ACCEPTED),
|
|
224
|
+
children: copy.accept
|
|
225
|
+
})]
|
|
226
|
+
})]
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function ConsentLink({ className, children }) {
|
|
230
|
+
const config = useAnalyticsConfig();
|
|
231
|
+
if (config === null) return null;
|
|
232
|
+
return /* @__PURE__ */ jsx("button", {
|
|
233
|
+
type: "button",
|
|
234
|
+
className,
|
|
235
|
+
onClick: openConsent,
|
|
236
|
+
children: children ?? consentCopy(config.language).label
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
export { ConsentBanner, ConsentLink };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
export type ConsentBannerProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
classNames?: {
|
|
5
|
+
text?: string;
|
|
6
|
+
link?: string;
|
|
7
|
+
configure?: string;
|
|
8
|
+
options?: string;
|
|
9
|
+
option?: string;
|
|
10
|
+
actions?: string;
|
|
11
|
+
accept?: string;
|
|
12
|
+
reject?: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export type ConsentLinkProps = {
|
|
16
|
+
className?: string;
|
|
17
|
+
children?: ReactNode;
|
|
18
|
+
};
|
|
19
|
+
export declare function ConsentBanner({ className, classNames }: ConsentBannerProps): import("react").JSX.Element | null;
|
|
20
|
+
export declare function ConsentLink({ className, children }: ConsentLinkProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { cartItem } from "./events-Dt81tIp1.js";
|
|
2
|
+
// src/analytics/cookies.ts
|
|
3
|
+
const CONSENT_COOKIE = "__Host-ecomiq-consent";
|
|
4
|
+
const PURCHASE_COOKIE = "__Host-ecomiq-purchase";
|
|
5
|
+
const CONSENT_MAX_AGE = 31536e3;
|
|
6
|
+
const PURCHASE_MAX_AGE = 600;
|
|
7
|
+
const PURCHASE_ITEMS = 20;
|
|
8
|
+
const PURCHASE_NAME_LENGTH = 60;
|
|
9
|
+
const PURCHASE_COOKIE_BYTES = 3800;
|
|
10
|
+
const CATEGORIES = ["analytics", "marketing"];
|
|
11
|
+
function cookieValue(cookies, name) {
|
|
12
|
+
for (const part of cookies.split(";")) {
|
|
13
|
+
const separator = part.indexOf("=");
|
|
14
|
+
if (separator > 0 && part.slice(0, separator).trim() === name) return part.slice(separator + 1).trim();
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
function grantedChoice(value) {
|
|
19
|
+
if (value === "none") return {
|
|
20
|
+
analytics: false,
|
|
21
|
+
marketing: false
|
|
22
|
+
};
|
|
23
|
+
const granted = value.split(".");
|
|
24
|
+
if (granted.some((category) => !CATEGORIES.some((known) => known === category))) return null;
|
|
25
|
+
return {
|
|
26
|
+
analytics: granted.includes("analytics"),
|
|
27
|
+
marketing: granted.includes("marketing")
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function readConsent(cookies) {
|
|
31
|
+
const value = cookieValue(cookies ?? "", CONSENT_COOKIE);
|
|
32
|
+
if (value === null) return null;
|
|
33
|
+
const [granted = "", version, date, ...rest] = value.split("|");
|
|
34
|
+
const choice = grantedChoice(granted);
|
|
35
|
+
if (choice === null || rest.length > 0 || !version || !date) return null;
|
|
36
|
+
return {
|
|
37
|
+
...choice,
|
|
38
|
+
version,
|
|
39
|
+
date
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function consentCookie(consent) {
|
|
43
|
+
const granted = CATEGORIES.filter((category) => consent[category]);
|
|
44
|
+
const choice = granted.length === 0 ? "none" : granted.join(".");
|
|
45
|
+
return `${CONSENT_COOKIE}=${choice}|${consent.version}|${consent.date}; Max-Age=${CONSENT_MAX_AGE}; Path=/; SameSite=Lax; Secure`;
|
|
46
|
+
}
|
|
47
|
+
function purchaseCookie(result) {
|
|
48
|
+
const { cart } = result;
|
|
49
|
+
const items = cart.items.slice(0, PURCHASE_ITEMS).map((item) => ({
|
|
50
|
+
...cartItem(item),
|
|
51
|
+
item_name: item.title.slice(0, PURCHASE_NAME_LENGTH)
|
|
52
|
+
}));
|
|
53
|
+
const purchase = {
|
|
54
|
+
orderId: result.orderId,
|
|
55
|
+
currency: cart.currencyCode,
|
|
56
|
+
value: cart.totals.total,
|
|
57
|
+
tax: cart.totals.taxTotal,
|
|
58
|
+
shipping: cart.totals.shippingTotal,
|
|
59
|
+
items
|
|
60
|
+
};
|
|
61
|
+
let value = encodeURIComponent(JSON.stringify(purchase));
|
|
62
|
+
while (value.length > PURCHASE_COOKIE_BYTES && purchase.items.length > 0) {
|
|
63
|
+
purchase.items.pop();
|
|
64
|
+
value = encodeURIComponent(JSON.stringify(purchase));
|
|
65
|
+
}
|
|
66
|
+
return `${PURCHASE_COOKIE}=${value}; Max-Age=${PURCHASE_MAX_AGE}; Path=/; SameSite=Lax; Secure`;
|
|
67
|
+
}
|
|
68
|
+
function expiredPurchaseCookie() {
|
|
69
|
+
return `${PURCHASE_COOKIE}=; Max-Age=0; Path=/; SameSite=Lax; Secure`;
|
|
70
|
+
}
|
|
71
|
+
function purchaseItem(value) {
|
|
72
|
+
if (typeof value !== "object" || value === null) return false;
|
|
73
|
+
const item = value;
|
|
74
|
+
return typeof item.item_id === "string" && typeof item.item_name === "string" && typeof item.price === "number";
|
|
75
|
+
}
|
|
76
|
+
function readPurchase(cookies) {
|
|
77
|
+
const value = cookieValue(cookies, PURCHASE_COOKIE);
|
|
78
|
+
if (value === null || value === "") return null;
|
|
79
|
+
try {
|
|
80
|
+
const purchase = JSON.parse(decodeURIComponent(value));
|
|
81
|
+
if (typeof purchase.orderId !== "string" || typeof purchase.currency !== "string") return null;
|
|
82
|
+
if (typeof purchase.value !== "number" || typeof purchase.tax !== "number" || typeof purchase.shipping !== "number") return null;
|
|
83
|
+
if (!Array.isArray(purchase.items) || !purchase.items.every(purchaseItem)) return null;
|
|
84
|
+
return purchase;
|
|
85
|
+
} catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const ANALYTICS_COOKIE = /^(_ga|_ga_[A-Za-z0-9]+|_gid|_gat(_.+)?)$/;
|
|
90
|
+
const MARKETING_COOKIE = /^(_fbp|_fbc|_gcl_[a-z]+)$/;
|
|
91
|
+
function revokedCookies(cookies, consent) {
|
|
92
|
+
return cookies.split(";").map((pair) => pair.split("=")[0]?.trim() ?? "").filter((name) => !consent.analytics && ANALYTICS_COOKIE.test(name) || !consent.marketing && MARKETING_COOKIE.test(name));
|
|
93
|
+
}
|
|
94
|
+
function cookieDomains(hostname) {
|
|
95
|
+
const parts = hostname.split(".");
|
|
96
|
+
const domains = [null];
|
|
97
|
+
for (let index = 0; index < parts.length - 1; index += 1) domains.push(`.${parts.slice(index).join(".")}`);
|
|
98
|
+
return domains;
|
|
99
|
+
}
|
|
100
|
+
export { CONSENT_COOKIE, PURCHASE_COOKIE, consentCookie, cookieDomains, expiredPurchaseCookie, purchaseCookie, readConsent, readPurchase, revokedCookies };
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// src/analytics/destinations.ts
|
|
2
|
+
const TOOLS = [
|
|
3
|
+
"googleAnalytics",
|
|
4
|
+
"googleTagManager",
|
|
5
|
+
"metaPixel",
|
|
6
|
+
"scripts"
|
|
7
|
+
];
|
|
8
|
+
const DENIED = {
|
|
9
|
+
ad_storage: "denied",
|
|
10
|
+
ad_user_data: "denied",
|
|
11
|
+
ad_personalization: "denied",
|
|
12
|
+
analytics_storage: "denied"
|
|
13
|
+
};
|
|
14
|
+
const META_EVENTS = {
|
|
15
|
+
page_view: "PageView",
|
|
16
|
+
search: "Search",
|
|
17
|
+
view_item: "ViewContent",
|
|
18
|
+
add_to_cart: "AddToCart",
|
|
19
|
+
begin_checkout: "InitiateCheckout",
|
|
20
|
+
purchase: "Purchase"
|
|
21
|
+
};
|
|
22
|
+
const loaded = /* @__PURE__ */ new Set();
|
|
23
|
+
function grant(value) {
|
|
24
|
+
return value ? "granted" : "denied";
|
|
25
|
+
}
|
|
26
|
+
function googleConsent(consent) {
|
|
27
|
+
return {
|
|
28
|
+
ad_storage: grant(consent.marketing),
|
|
29
|
+
ad_user_data: grant(consent.marketing),
|
|
30
|
+
ad_personalization: grant(consent.marketing),
|
|
31
|
+
analytics_storage: grant(consent.analytics)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function script(parent, source) {
|
|
35
|
+
const element = document.createElement("script");
|
|
36
|
+
if ("src" in source) {
|
|
37
|
+
element.async = true;
|
|
38
|
+
element.src = source.src;
|
|
39
|
+
} else element.text = source.text;
|
|
40
|
+
parent.appendChild(element);
|
|
41
|
+
}
|
|
42
|
+
function gtag() {
|
|
43
|
+
if (window.gtag) return window.gtag;
|
|
44
|
+
const layer = window.dataLayer ??= [];
|
|
45
|
+
window.gtag = function() {
|
|
46
|
+
layer.push(arguments);
|
|
47
|
+
};
|
|
48
|
+
window.gtag("consent", "default", DENIED);
|
|
49
|
+
return window.gtag;
|
|
50
|
+
}
|
|
51
|
+
function metaPixel() {
|
|
52
|
+
if (window.fbq) return window.fbq;
|
|
53
|
+
const pixel = function(...args) {
|
|
54
|
+
if (pixel.callMethod) pixel.callMethod.apply(pixel, args);
|
|
55
|
+
else pixel.queue.push(args);
|
|
56
|
+
};
|
|
57
|
+
pixel.push = pixel;
|
|
58
|
+
pixel.loaded = true;
|
|
59
|
+
pixel.version = "2.0";
|
|
60
|
+
pixel.queue = [];
|
|
61
|
+
window.fbq = pixel;
|
|
62
|
+
window._fbq = pixel;
|
|
63
|
+
script(document.head, { src: "https://connect.facebook.net/en_US/fbevents.js" });
|
|
64
|
+
return pixel;
|
|
65
|
+
}
|
|
66
|
+
function allowed(tool, consent) {
|
|
67
|
+
if (tool === "googleAnalytics") return consent.analytics;
|
|
68
|
+
if (tool === "metaPixel") return consent.marketing;
|
|
69
|
+
return consent.analytics && consent.marketing;
|
|
70
|
+
}
|
|
71
|
+
function withdraw(consent) {
|
|
72
|
+
if (window.gtag) window.gtag("consent", "update", googleConsent(consent));
|
|
73
|
+
if (loaded.has("metaPixel") && !consent.marketing) metaPixel()("consent", "revoke");
|
|
74
|
+
location.reload();
|
|
75
|
+
}
|
|
76
|
+
function load(settings, consent) {
|
|
77
|
+
if ([...loaded].some((tool) => !allowed(tool, consent))) return withdraw(consent);
|
|
78
|
+
const pending = TOOLS.filter((tool) => settings[tool] !== null && allowed(tool, consent) && !loaded.has(tool));
|
|
79
|
+
if (window.gtag || pending.includes("googleAnalytics") || pending.includes("googleTagManager")) gtag()("consent", "update", googleConsent(consent));
|
|
80
|
+
for (const tool of pending) loaded.add(tool);
|
|
81
|
+
if (settings.googleAnalytics !== null && pending.includes("googleAnalytics")) {
|
|
82
|
+
gtag()("js", /* @__PURE__ */ new Date());
|
|
83
|
+
gtag()("config", settings.googleAnalytics, { send_page_view: false });
|
|
84
|
+
script(document.head, { src: `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(settings.googleAnalytics)}` });
|
|
85
|
+
}
|
|
86
|
+
if (settings.googleTagManager !== null && pending.includes("googleTagManager")) {
|
|
87
|
+
(window.dataLayer ??= []).push({
|
|
88
|
+
"gtm.start": Date.now(),
|
|
89
|
+
event: "gtm.js"
|
|
90
|
+
});
|
|
91
|
+
script(document.head, { src: `https://www.googletagmanager.com/gtm.js?id=${encodeURIComponent(settings.googleTagManager)}` });
|
|
92
|
+
}
|
|
93
|
+
if (settings.metaPixel !== null && pending.includes("metaPixel")) metaPixel()("init", settings.metaPixel);
|
|
94
|
+
if (settings.scripts !== null && pending.includes("scripts")) {
|
|
95
|
+
if (settings.scripts.head !== null) script(document.head, { text: settings.scripts.head });
|
|
96
|
+
if (settings.scripts.bodyEnd !== null) script(document.body, { text: settings.scripts.bodyEnd });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function contents(params, currency) {
|
|
100
|
+
const { items } = params;
|
|
101
|
+
return {
|
|
102
|
+
content_type: "product",
|
|
103
|
+
content_ids: items.map((item) => item.item_id),
|
|
104
|
+
contents: items.map((item) => ({
|
|
105
|
+
id: item.item_id,
|
|
106
|
+
quantity: item.quantity ?? 1,
|
|
107
|
+
item_price: item.price
|
|
108
|
+
})),
|
|
109
|
+
num_items: items.reduce((sum, item) => sum + (item.quantity ?? 1), 0),
|
|
110
|
+
value: params.value,
|
|
111
|
+
currency: params.currency ?? currency
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function sendMeta(event, currency) {
|
|
115
|
+
const name = META_EVENTS[event.name];
|
|
116
|
+
if (name === void 0) return;
|
|
117
|
+
const pixel = metaPixel();
|
|
118
|
+
if (event.name === "page_view") pixel("track", name);
|
|
119
|
+
else if (event.name === "search") pixel("track", name, { search_string: event.params.search_term });
|
|
120
|
+
else if (event.name === "purchase") pixel("track", name, contents(event.params, currency), { eventID: event.params.transaction_id });
|
|
121
|
+
else if ("value" in event.params) pixel("track", name, contents(event.params, currency));
|
|
122
|
+
}
|
|
123
|
+
function send(settings, consent, event) {
|
|
124
|
+
const params = "items" in event.params ? {
|
|
125
|
+
currency: settings.currency,
|
|
126
|
+
...event.params
|
|
127
|
+
} : event.params;
|
|
128
|
+
if (loaded.has("googleAnalytics") && allowed("googleAnalytics", consent)) gtag()("event", event.name, params);
|
|
129
|
+
if (loaded.has("googleTagManager") && allowed("googleTagManager", consent)) {
|
|
130
|
+
const layer = window.dataLayer ??= [];
|
|
131
|
+
if ("items" in event.params) {
|
|
132
|
+
layer.push({ ecommerce: null });
|
|
133
|
+
layer.push({
|
|
134
|
+
event: event.name,
|
|
135
|
+
ecommerce: params
|
|
136
|
+
});
|
|
137
|
+
} else layer.push({
|
|
138
|
+
event: event.name,
|
|
139
|
+
...params
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
if (loaded.has("metaPixel") && allowed("metaPixel", consent)) sendMeta(event, settings.currency);
|
|
143
|
+
}
|
|
144
|
+
export { load, send };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// src/analytics/events.ts
|
|
2
|
+
const LIST_LIMIT = 24;
|
|
3
|
+
const SEARCH_LIST = {
|
|
4
|
+
id: "search",
|
|
5
|
+
name: "Búsqueda"
|
|
6
|
+
};
|
|
7
|
+
const CATALOG_LIST = {
|
|
8
|
+
id: "catalog",
|
|
9
|
+
name: "Catálogo"
|
|
10
|
+
};
|
|
11
|
+
function filled(value) {
|
|
12
|
+
const trimmed = value?.trim() ?? "";
|
|
13
|
+
if (trimmed === "") return void 0;
|
|
14
|
+
return trimmed;
|
|
15
|
+
}
|
|
16
|
+
function itemsValue(items) {
|
|
17
|
+
const total = items.reduce((sum, item) => sum + item.price * (item.quantity ?? 1), 0);
|
|
18
|
+
return Math.round(total * 100) / 100;
|
|
19
|
+
}
|
|
20
|
+
function productItem(product) {
|
|
21
|
+
return {
|
|
22
|
+
item_id: product.id,
|
|
23
|
+
item_name: product.name,
|
|
24
|
+
item_brand: filled(product.brand),
|
|
25
|
+
item_category: filled(product.category),
|
|
26
|
+
price: product.price
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function cartItem(item) {
|
|
30
|
+
return {
|
|
31
|
+
item_id: item.productId ?? item.variantId ?? item.id,
|
|
32
|
+
item_name: item.title,
|
|
33
|
+
item_variant: filled(item.variantLabel),
|
|
34
|
+
price: item.unitPrice,
|
|
35
|
+
quantity: item.quantity
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function listAnalytics(list, products) {
|
|
39
|
+
const items = products.slice(0, LIST_LIMIT).map((product, index) => ({
|
|
40
|
+
...productItem(product),
|
|
41
|
+
index
|
|
42
|
+
}));
|
|
43
|
+
return { events: [{
|
|
44
|
+
name: "view_item_list",
|
|
45
|
+
params: {
|
|
46
|
+
item_list_id: list.id,
|
|
47
|
+
item_list_name: list.name,
|
|
48
|
+
items
|
|
49
|
+
}
|
|
50
|
+
}] };
|
|
51
|
+
}
|
|
52
|
+
function productAnalytics(product) {
|
|
53
|
+
return { events: [{
|
|
54
|
+
name: "view_item",
|
|
55
|
+
params: {
|
|
56
|
+
value: product.price,
|
|
57
|
+
items: [productItem(product)]
|
|
58
|
+
}
|
|
59
|
+
}] };
|
|
60
|
+
}
|
|
61
|
+
function categoryAnalytics(category, products) {
|
|
62
|
+
return listAnalytics({
|
|
63
|
+
id: category.slug,
|
|
64
|
+
name: category.name
|
|
65
|
+
}, products);
|
|
66
|
+
}
|
|
67
|
+
function collectionAnalytics(collection, products) {
|
|
68
|
+
return listAnalytics({
|
|
69
|
+
id: collection.slug,
|
|
70
|
+
name: collection.name
|
|
71
|
+
}, products);
|
|
72
|
+
}
|
|
73
|
+
function catalogAnalytics(q, products) {
|
|
74
|
+
if (q === "") return listAnalytics(CATALOG_LIST, products);
|
|
75
|
+
const list = listAnalytics(SEARCH_LIST, products);
|
|
76
|
+
return { events: [{
|
|
77
|
+
name: "search",
|
|
78
|
+
params: { search_term: q }
|
|
79
|
+
}, ...list.events] };
|
|
80
|
+
}
|
|
81
|
+
function checkoutAnalytics(cart) {
|
|
82
|
+
const items = cart.items.map(cartItem);
|
|
83
|
+
return {
|
|
84
|
+
events: [{
|
|
85
|
+
name: "begin_checkout",
|
|
86
|
+
params: {
|
|
87
|
+
currency: cart.currencyCode,
|
|
88
|
+
value: itemsValue(items),
|
|
89
|
+
items
|
|
90
|
+
}
|
|
91
|
+
}],
|
|
92
|
+
once: `begin_checkout:${cart.id}`
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function orderAnalytics(order, paid) {
|
|
96
|
+
if (!paid) return { events: [] };
|
|
97
|
+
return {
|
|
98
|
+
events: [],
|
|
99
|
+
paid: order.id
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export { cartItem, catalogAnalytics, categoryAnalytics, checkoutAnalytics, collectionAnalytics, itemsValue, orderAnalytics, productAnalytics };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CategoryDetail, Collection, CustomerOrderDetail, ProductDetail, ProductSummary, StorefrontCart } from "@ecomiq/core";
|
|
2
|
+
export type AnalyticsItem = {
|
|
3
|
+
item_id: string;
|
|
4
|
+
item_name: string;
|
|
5
|
+
item_variant?: string;
|
|
6
|
+
item_brand?: string;
|
|
7
|
+
item_category?: string;
|
|
8
|
+
price: number;
|
|
9
|
+
quantity?: number;
|
|
10
|
+
index?: number;
|
|
11
|
+
};
|
|
12
|
+
export type CommerceParams = {
|
|
13
|
+
currency?: string;
|
|
14
|
+
value: number;
|
|
15
|
+
items: AnalyticsItem[];
|
|
16
|
+
};
|
|
17
|
+
export type AnalyticsEvent = {
|
|
18
|
+
name: "page_view";
|
|
19
|
+
params: {
|
|
20
|
+
page_location: string;
|
|
21
|
+
page_title: string;
|
|
22
|
+
};
|
|
23
|
+
} | {
|
|
24
|
+
name: "search";
|
|
25
|
+
params: {
|
|
26
|
+
search_term: string;
|
|
27
|
+
};
|
|
28
|
+
} | {
|
|
29
|
+
name: "view_item_list";
|
|
30
|
+
params: {
|
|
31
|
+
item_list_id: string;
|
|
32
|
+
item_list_name: string;
|
|
33
|
+
items: AnalyticsItem[];
|
|
34
|
+
};
|
|
35
|
+
} | {
|
|
36
|
+
name: "view_item" | "add_to_cart" | "remove_from_cart" | "begin_checkout";
|
|
37
|
+
params: CommerceParams;
|
|
38
|
+
} | {
|
|
39
|
+
name: "purchase";
|
|
40
|
+
params: CommerceParams & {
|
|
41
|
+
transaction_id: string;
|
|
42
|
+
tax: number;
|
|
43
|
+
shipping: number;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export type PageAnalytics = {
|
|
47
|
+
events: AnalyticsEvent[];
|
|
48
|
+
once?: string;
|
|
49
|
+
paid?: string;
|
|
50
|
+
};
|
|
51
|
+
export declare function catalogAnalytics(q: string, products: ProductSummary[]): PageAnalytics;
|