ublo-lib 1.31.29 → 1.31.30

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.
@@ -24,7 +24,6 @@ export default function useTunnel({
24
24
  lang,
25
25
  breadcrumb
26
26
  } = useUbloContext();
27
- const [started, setStared] = React.useState(false);
28
27
  const {
29
28
  path: esfPath
30
29
  } = multipleVillages ? breadcrumb?.next : breadcrumb;
@@ -33,7 +32,6 @@ export default function useTunnel({
33
32
  React.useEffect(() => {
34
33
  if (enableCustomOffers && cmsMode !== "editing" || !enableCustomOffers) {
35
34
  const startTunnel = async () => {
36
- setStared(true);
37
35
  await loadWidgetMseM(integration);
38
36
  const categoryCode = window.sessionStorage.getItem("categoryCode") || undefined;
39
37
  window.MseM?.onLoad(() => {
@@ -51,11 +49,9 @@ export default function useTunnel({
51
49
  });
52
50
  });
53
51
  };
54
- if (!started && (enableCustomOffers && customOffers !== undefined || !enableCustomOffers)) {
55
- startTunnel();
56
- }
52
+ startTunnel();
57
53
  }
58
- }, [channel, cmsMode, customOffers, enableCustomOffers, esfUrl, groundedTo, integration, started, widgetLang]);
54
+ }, [channel, cmsMode, customOffers, enableCustomOffers, esfUrl, groundedTo, integration, widgetLang]);
59
55
  }
60
56
  async function loadWidgetMseM(integration) {
61
57
  const source = integration ? "https://widget-integration.msem.tech/static/js/widget-msem.js" : "https://widget.msem.tech/static/js/widget-msem.js";
@@ -0,0 +1,3 @@
1
+ import { Script } from "./script";
2
+ import Tunnel from "./tunnel";
3
+ export { Script, Tunnel };
@@ -0,0 +1,14 @@
1
+ import NextScript from "next/script";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ export function Script({
4
+ msemUrl
5
+ }) {
6
+ const setLoaded = () => {
7
+ window.MseMLoaded = true;
8
+ };
9
+ return _jsx(NextScript, {
10
+ src: `${msemUrl}/static/js/widget-msem.js`,
11
+ onLoad: setLoaded,
12
+ defer: true
13
+ });
14
+ }
@@ -0,0 +1,21 @@
1
+ import * as React from "react";
2
+ import * as Utils from "./utils";
3
+ import * as Plausible from "../plausible";
4
+ export default React.memo(Tunnel);
5
+ function Tunnel({
6
+ options,
7
+ presets,
8
+ children
9
+ }) {
10
+ const patchedOptions = React.useMemo(() => ({
11
+ ...options,
12
+ analytics: (...args) => {
13
+ options?.analytics?.apply(null, args);
14
+ Plausible.callback.apply(null, args);
15
+ }
16
+ }), [options]);
17
+ React.useEffect(() => {
18
+ Utils.loadWidget("tunnel", patchedOptions, presets);
19
+ }, [patchedOptions, presets]);
20
+ return children;
21
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ export function loadWidget(widget, options = {}, presets = {}) {
2
+ if (window.MseMLoaded) {
3
+ window.MseM?.onLoad(() => window.requestAnimationFrame(() => window.MseM[widget](options, presets)));
4
+ } else {
5
+ setTimeout(() => {
6
+ const isGroundedTo = ("groundedTo" in options);
7
+ if (isGroundedTo) {
8
+ const selector = options.groundedTo;
9
+ const widgetStillHasTarget = document.querySelector(selector);
10
+ if (!widgetStillHasTarget) return;
11
+ }
12
+ loadWidget(widget, options, presets);
13
+ }, 200);
14
+ }
15
+ }
@@ -0,0 +1,29 @@
1
+ import * as React from "react";
2
+ import getConfig from "next/config";
3
+ import load from "../services/load";
4
+ import sendGoal from "../services/send-goal";
5
+ const {
6
+ publicRuntimeConfig
7
+ } = getConfig();
8
+ const {
9
+ plausibleDomain
10
+ } = publicRuntimeConfig;
11
+ export default function useGoal(goal, props, revenue, overridenDomain) {
12
+ const [loaded] = usePlausible(overridenDomain);
13
+ React.useEffect(() => {
14
+ if (!loaded || !window.plausible) return;
15
+ const defaultProps = {
16
+ path: document.location.pathname
17
+ };
18
+ sendGoal(goal, props || defaultProps, revenue);
19
+ }, [goal, loaded, props]);
20
+ }
21
+ function usePlausible(overridenDomain) {
22
+ const [loaded, setLoaded] = React.useState(false);
23
+ React.useEffect(() => {
24
+ if (!overridenDomain && !plausibleDomain) return;
25
+ load();
26
+ setLoaded(true);
27
+ }, [overridenDomain]);
28
+ return [loaded, setLoaded];
29
+ }
@@ -0,0 +1,7 @@
1
+ import Script from "./plausible";
2
+ import * as Callback from "./services/callback";
3
+ const callback = Callback.MseM;
4
+ export { default as load } from "./services/load";
5
+ export { default as sendGoal } from "./services/send-goal";
6
+ export { default as useGoal } from "./hooks/use-plausible";
7
+ export { callback, Script };
@@ -0,0 +1,26 @@
1
+ import * as React from "react";
2
+ import Script from "next/script";
3
+ import getConfig from "next/config";
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ const {
6
+ publicRuntimeConfig
7
+ } = getConfig();
8
+ const {
9
+ plausibleDomain
10
+ } = publicRuntimeConfig;
11
+ const DEFAULT_SOURCE = "https://plausible.io/js/script.revenue.file-downloads.outbound-links.js";
12
+ export default function PlausibleScript({
13
+ lang,
14
+ source = DEFAULT_SOURCE
15
+ }) {
16
+ const hasI18n = typeof plausibleDomain === "object";
17
+ if (hasI18n && !lang) {
18
+ console.warn("PlausibleScript: the lang props is mandatory if you want to use a specific domain for each lang");
19
+ }
20
+ const domain = hasI18n && lang ? plausibleDomain[lang] : plausibleDomain;
21
+ if (!domain) return null;
22
+ return _jsx(Script, {
23
+ "data-domain": domain,
24
+ src: source
25
+ });
26
+ }
@@ -0,0 +1,201 @@
1
+ import sendGoal from "./send-goal";
2
+ const EVENT_NAMES = {
3
+ view_item: "MseM: View item",
4
+ add_to_cart: "MseM: Add to cart",
5
+ remove_from_cart: "MseM: Remove from cart",
6
+ checkout: "MseM: Begin checkout",
7
+ add_payment_info: "MseM: Checkout process",
8
+ purchase: "MseM: Payment success",
9
+ payment_failure: "MseM: Payment failure"
10
+ };
11
+ export function MseM({
12
+ event,
13
+ payment_type: paymentType,
14
+ execcode,
15
+ items = [],
16
+ orderId,
17
+ cartId,
18
+ currency = "EUR"
19
+ }) {
20
+ const hoteId = getBusinessProvider();
21
+ const stay = getStay();
22
+ const amount = items.reduce((acc, item) => {
23
+ return acc + item.gtmData.price * item.gtmData.quantity;
24
+ }, 0);
25
+ const revenue = {
26
+ currency,
27
+ amount
28
+ };
29
+ let name = EVENT_NAMES[event];
30
+ const firstProductProps = {
31
+ Name: items[0]?.gtmData.item_name,
32
+ Brand: items[0]?.gtmData.item_brand,
33
+ Kind: items[0]?.gtmData.item_category,
34
+ Activity: items[0]?.gtmData.item_category2,
35
+ Code: items[0]?.gtmData.item_category3,
36
+ Product: items[0]?.gtmData.item_variant
37
+ };
38
+ switch (event) {
39
+ case "view_item":
40
+ {
41
+ const formatedItems = formatPeekPerformancesItem(items);
42
+ const rawData = JSON.stringify({
43
+ products: formatedItems,
44
+ hoteId,
45
+ stay
46
+ });
47
+ sendGoal(name, {
48
+ ...firstProductProps,
49
+ stayFrom: stay?.from,
50
+ rawData
51
+ });
52
+ break;
53
+ }
54
+ case "add_to_cart":
55
+ {
56
+ const formatedItems = formatPeekPerformancesItem(items);
57
+ const rawData = JSON.stringify({
58
+ products: formatedItems,
59
+ hoteId,
60
+ stay
61
+ });
62
+ sendGoal(name, {
63
+ ...firstProductProps,
64
+ stayFrom: stay?.from,
65
+ rawData
66
+ }, revenue);
67
+ break;
68
+ }
69
+ case "remove_from_cart":
70
+ {
71
+ const formatedItems = formatPeekPerformancesItem(items);
72
+ const rawData = JSON.stringify({
73
+ products: formatedItems,
74
+ hoteId,
75
+ stay
76
+ });
77
+ sendGoal(name, {
78
+ ...firstProductProps,
79
+ stayFrom: stay?.from,
80
+ rawData
81
+ }, revenue);
82
+ break;
83
+ }
84
+ case "checkout":
85
+ {
86
+ const formatedItems = formatPeekPerformancesItem(items);
87
+ const rawData = JSON.stringify({
88
+ products: formatedItems,
89
+ hoteId,
90
+ stay
91
+ });
92
+ sendGoal(name, {
93
+ cartId,
94
+ stayFrom: stay?.from,
95
+ rawData
96
+ }, revenue);
97
+ break;
98
+ }
99
+ case "add_payment_info":
100
+ {
101
+ const formatedItems = formatPeekPerformancesItem(items);
102
+ const rawData = JSON.stringify({
103
+ products: formatedItems,
104
+ hoteId,
105
+ stay,
106
+ paymentMethod: paymentType
107
+ });
108
+ sendGoal(name, {
109
+ cartId,
110
+ "Payment type": paymentType,
111
+ stayFrom: stay?.from,
112
+ rawData
113
+ }, revenue);
114
+ break;
115
+ }
116
+ case "purchase":
117
+ {
118
+ const isFailure = execcode !== "0000";
119
+ const formatedItems = formatPeekPerformancesItem(items);
120
+ const attempts = cartId && getPurchaseAttempts()[cartId] || 0;
121
+ const rawData = JSON.stringify({
122
+ products: formatedItems,
123
+ hoteId,
124
+ stay,
125
+ attempts,
126
+ paymentMethod: paymentType,
127
+ execCode: execcode
128
+ });
129
+ if (isFailure) {
130
+ name = EVENT_NAMES.payment_failure;
131
+ sendGoal(name, {
132
+ cartId,
133
+ orderId,
134
+ Code: execcode,
135
+ stayFrom: stay?.from,
136
+ rawData
137
+ }, revenue);
138
+ if (cartId) {
139
+ setPurchaseAttempts(cartId, attempts + 1);
140
+ }
141
+ } else {
142
+ sendGoal(name, {
143
+ cartId,
144
+ orderId,
145
+ Code: execcode,
146
+ stayFrom: stay?.from,
147
+ rawData
148
+ }, revenue);
149
+ }
150
+ break;
151
+ }
152
+ }
153
+ }
154
+ const PURCHASE_ATTEMPTS_STORAGE_KEY = "purchase_attempts";
155
+ function getPurchaseAttempts() {
156
+ try {
157
+ const storedAttempts = window.localStorage.getItem(PURCHASE_ATTEMPTS_STORAGE_KEY);
158
+ return storedAttempts !== null ? JSON.parse(storedAttempts) : {};
159
+ } catch (e) {
160
+ return {};
161
+ }
162
+ }
163
+ function setPurchaseAttempts(cartId, attempts) {
164
+ const purchaseAttempts = getPurchaseAttempts();
165
+ window.localStorage.setItem(PURCHASE_ATTEMPTS_STORAGE_KEY, JSON.stringify({
166
+ ...purchaseAttempts,
167
+ [cartId]: attempts
168
+ }));
169
+ }
170
+ function formatPeekPerformancesItem(items) {
171
+ if (!items || !items.length) return;
172
+ return items.map(({
173
+ gtmData
174
+ }) => {
175
+ return {
176
+ category: gtmData.item_category,
177
+ subCategory: gtmData.item_category2,
178
+ merchant: gtmData.item_brand,
179
+ price: gtmData.price
180
+ };
181
+ });
182
+ }
183
+ function getStay() {
184
+ const stay = window.sessionStorage.getItem("stay");
185
+ if (stay) {
186
+ return JSON.parse(stay);
187
+ }
188
+ }
189
+ function getBusinessProvider() {
190
+ const businessProvider = window.localStorage.getItem("businessProvider");
191
+ if (businessProvider) {
192
+ try {
193
+ const {
194
+ id
195
+ } = JSON.parse(businessProvider);
196
+ if (id !== -1) {
197
+ return id;
198
+ }
199
+ } catch (e) {}
200
+ }
201
+ }
@@ -0,0 +1,5 @@
1
+ export default function load() {
2
+ window.plausible = window.plausible || function () {
3
+ (window.plausible.q = window.plausible.q || []).push(arguments);
4
+ };
5
+ }
@@ -0,0 +1,8 @@
1
+ import load from "./load";
2
+ export default function sendGoal(goal, props, revenue) {
3
+ load();
4
+ window.plausible(goal, {
5
+ props,
6
+ revenue
7
+ });
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ublo-lib",
3
- "version": "1.31.29",
3
+ "version": "1.31.30",
4
4
  "peerDependencies": {
5
5
  "dt-design-system": "^3.8.3",
6
6
  "leaflet": "^1.9.1",