@nuskin/react-search-sdk 1.0.0-trying-again.1 → 1.0.0-trying-again.3
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/README.md +59 -8
- package/dist/index.d.mts +43 -635
- package/dist/index.d.ts +43 -635
- package/dist/index.js +206 -213
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +203 -176
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { lazy, useState, useRef,
|
|
1
|
+
import { lazy, useState, useEffect, useRef, useMemo, useCallback, Suspense, Component } from 'react';
|
|
2
|
+
import configurationSdk from '@nuskin/configuration-sdk';
|
|
2
3
|
import { SearchModal } from '@nuskin/react-search-components';
|
|
3
4
|
import { jsx } from 'react/jsx-runtime';
|
|
4
5
|
|
|
6
|
+
// src/components/CommerceSearch/CommerceSearch.tsx
|
|
7
|
+
var { getConfiguration, getEnvironmentCode } = configurationSdk;
|
|
8
|
+
|
|
5
9
|
// src/constants.ts
|
|
6
10
|
var STOREFRONT_SHOPPING_CONTEXT = "storefront";
|
|
7
11
|
var CATALOG_SUGGESTIONS_PATH = "/storefront/catalogs/search/suggestions";
|
|
@@ -11,13 +15,77 @@ var DEFAULT_SUGGESTION_PAGE = 1;
|
|
|
11
15
|
var DEFAULT_SUGGESTION_SIZE = 6;
|
|
12
16
|
var DEFAULT_SEARCH_PATH = "/search";
|
|
13
17
|
var DEBOUNCE_MS = 220;
|
|
18
|
+
var MINIMUM_SEARCH_CHAR_LENGTH = 2;
|
|
14
19
|
var MAX_VISIBLE_SUGGESTIONS = 6;
|
|
15
|
-
var
|
|
16
|
-
var
|
|
20
|
+
var EQUINOX_MARKETS_MAP = "Equinox_Markets";
|
|
21
|
+
var DEFAULT_EQUINOX_CLIENT_ID = "63056848d7532f9923f3d08cb48c423b";
|
|
22
|
+
|
|
23
|
+
// src/config/commerceSearchConfig.ts
|
|
24
|
+
var COMMERCE_SEARCH_CONFIG_DEFAULTS = Object.freeze({
|
|
25
|
+
minimumSearchLength: MINIMUM_SEARCH_CHAR_LENGTH
|
|
26
|
+
});
|
|
27
|
+
var TEST_ENVIRONMENT_VALUES = {
|
|
28
|
+
agent: {
|
|
29
|
+
appKey: "pk_commerce_product_advisor_624aea4305b09240e8c8f41d0f6527b2",
|
|
30
|
+
apiBaseUrl: "https://nui.tst.nuskin.ai/"
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
function nonEmptyString(value) {
|
|
34
|
+
return typeof value === "string" ? value.trim() : "";
|
|
35
|
+
}
|
|
36
|
+
function normalizeCommerceSearchConfig(raw, { language } = {}) {
|
|
37
|
+
const minimumSearchLength = Number(raw?.minimumSearchLength);
|
|
38
|
+
const appKey = nonEmptyString(raw?.agent?.appKey);
|
|
39
|
+
const apiBaseUrl = nonEmptyString(raw?.agent?.apiBaseUrl);
|
|
40
|
+
return {
|
|
41
|
+
minimumSearchLength: Number.isInteger(minimumSearchLength) && minimumSearchLength >= 1 ? minimumSearchLength : COMMERCE_SEARCH_CONFIG_DEFAULTS.minimumSearchLength,
|
|
42
|
+
...appKey && apiBaseUrl ? {
|
|
43
|
+
agent: {
|
|
44
|
+
appKey,
|
|
45
|
+
apiBaseUrl,
|
|
46
|
+
...language ? { language } : {}
|
|
47
|
+
}
|
|
48
|
+
} : {}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
async function fetchCommerceSearchConfig({
|
|
52
|
+
language
|
|
53
|
+
} = {}) {
|
|
54
|
+
const raw = getEnvironmentCode() === "test" ? TEST_ENVIRONMENT_VALUES : {};
|
|
55
|
+
return normalizeCommerceSearchConfig(raw, language ? { language } : {});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/hooks/useCommerceSearchConfig.ts
|
|
59
|
+
function useCommerceSearchConfig({
|
|
60
|
+
country,
|
|
61
|
+
language,
|
|
62
|
+
enabled
|
|
63
|
+
}) {
|
|
64
|
+
const [config, setConfig] = useState(
|
|
65
|
+
COMMERCE_SEARCH_CONFIG_DEFAULTS
|
|
66
|
+
);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (!enabled) return void 0;
|
|
69
|
+
let isStale = false;
|
|
70
|
+
fetchCommerceSearchConfig({
|
|
71
|
+
...country ? { country } : {},
|
|
72
|
+
...language ? { language } : {}
|
|
73
|
+
}).then((next) => {
|
|
74
|
+
if (!isStale) setConfig(next);
|
|
75
|
+
}).catch((error) => {
|
|
76
|
+
console.warn(
|
|
77
|
+
"[search] Could not load the product search configuration:",
|
|
78
|
+
error
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
return () => {
|
|
82
|
+
isStale = true;
|
|
83
|
+
};
|
|
84
|
+
}, [enabled, country, language]);
|
|
85
|
+
return config;
|
|
86
|
+
}
|
|
17
87
|
|
|
18
88
|
// src/services/SearchApiService.ts
|
|
19
|
-
var DEFAULT_SEARCH_PLACEHOLDER = TRIGGER_PLACEHOLDER;
|
|
20
|
-
var DEFAULT_INPUT_ARIA_LABEL = SEARCH_PLACEHOLDER;
|
|
21
89
|
function canUseStorage(storage) {
|
|
22
90
|
return Boolean(storage) && typeof storage.getItem === "function";
|
|
23
91
|
}
|
|
@@ -36,7 +104,7 @@ function normalizeLocaleParts({
|
|
|
36
104
|
country,
|
|
37
105
|
language,
|
|
38
106
|
locale
|
|
39
|
-
}
|
|
107
|
+
}) {
|
|
40
108
|
const normalizedCountry = String(country ?? "").trim().toUpperCase();
|
|
41
109
|
const normalizedLanguage = String(language ?? "").trim().toLowerCase();
|
|
42
110
|
const normalizedLocale = String(locale ?? "").trim() || "UNKNOWN";
|
|
@@ -227,14 +295,18 @@ function resolveOptionHref(option, localeParts) {
|
|
|
227
295
|
}
|
|
228
296
|
return "";
|
|
229
297
|
}
|
|
230
|
-
|
|
298
|
+
function resolveCustomerTypeHeaders(getCustomerType) {
|
|
299
|
+
const customerType = getCustomerType?.()?.trim();
|
|
300
|
+
return customerType ? { "X-Customer-Type": customerType } : void 0;
|
|
301
|
+
}
|
|
302
|
+
async function fetchJsonFromCandidates(fetchImpl, requestUrls, requestHeaders = {}) {
|
|
231
303
|
let lastError;
|
|
232
304
|
for (const requestUrl of requestUrls) {
|
|
233
305
|
try {
|
|
234
306
|
const response = await fetchImpl(requestUrl, {
|
|
235
307
|
method: "GET",
|
|
236
308
|
credentials: "include",
|
|
237
|
-
headers: { Accept: "application/json" }
|
|
309
|
+
headers: { Accept: "application/json", ...requestHeaders }
|
|
238
310
|
});
|
|
239
311
|
if (!response.ok) {
|
|
240
312
|
lastError = new Error(
|
|
@@ -259,9 +331,9 @@ function createSearchService(options = {}) {
|
|
|
259
331
|
country,
|
|
260
332
|
language,
|
|
261
333
|
locale,
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
334
|
+
getMarketConfig,
|
|
335
|
+
getCustomerType,
|
|
336
|
+
minimumSearchLength = MINIMUM_SEARCH_CHAR_LENGTH
|
|
265
337
|
} = options;
|
|
266
338
|
const fetchImpl = fetchImplOption !== void 0 ? fetchImplOption : typeof fetch === "function" ? fetch.bind(globalThis) : null;
|
|
267
339
|
const locationLike = getBrowserLocation(providedLocation);
|
|
@@ -276,20 +348,21 @@ function createSearchService(options = {}) {
|
|
|
276
348
|
locationLike,
|
|
277
349
|
country: localeParts.country,
|
|
278
350
|
getMarketConfig
|
|
351
|
+
}).catch((error) => {
|
|
352
|
+
catalogRequestConfigPromise = null;
|
|
353
|
+
console.warn(
|
|
354
|
+
"[search] Could not load the market configuration for the suggestions:",
|
|
355
|
+
error
|
|
356
|
+
);
|
|
357
|
+
throw error;
|
|
279
358
|
});
|
|
280
359
|
}
|
|
281
360
|
return catalogRequestConfigPromise;
|
|
282
361
|
}
|
|
283
362
|
const service = {
|
|
284
|
-
async getSearchChromeCopy() {
|
|
285
|
-
return {
|
|
286
|
-
placeholder: searchPlaceholder || DEFAULT_SEARCH_PLACEHOLDER,
|
|
287
|
-
inputAriaLabel: inputAriaLabel || DEFAULT_INPUT_ARIA_LABEL
|
|
288
|
-
};
|
|
289
|
-
},
|
|
290
363
|
async fetchSuggestions(searchTerm) {
|
|
291
364
|
const trimmedSearchTerm = String(searchTerm ?? "").trim();
|
|
292
|
-
if (!trimmedSearchTerm || !fetchImpl) {
|
|
365
|
+
if (!trimmedSearchTerm || trimmedSearchTerm.length < minimumSearchLength || !fetchImpl) {
|
|
293
366
|
return {
|
|
294
367
|
suggestions: [],
|
|
295
368
|
didYouMean: [],
|
|
@@ -314,7 +387,8 @@ function createSearchService(options = {}) {
|
|
|
314
387
|
const requestUrls = [`${suggestionsUrl}?${queryParams.toString()}`];
|
|
315
388
|
const responsePayload = await fetchJsonFromCandidates(
|
|
316
389
|
fetchImpl,
|
|
317
|
-
requestUrls
|
|
390
|
+
requestUrls,
|
|
391
|
+
resolveCustomerTypeHeaders(getCustomerType)
|
|
318
392
|
);
|
|
319
393
|
const suggestionsField = Array.isArray(responsePayload?.suggestions) ? responsePayload?.suggestions : [];
|
|
320
394
|
const productField = Array.isArray(responsePayload?.product) ? responsePayload?.product : null;
|
|
@@ -346,33 +420,6 @@ function createSearchService(options = {}) {
|
|
|
346
420
|
return stripLocalePrefix(targetPath, localeParts);
|
|
347
421
|
},
|
|
348
422
|
activateSuggestionAction(option) {
|
|
349
|
-
if (options.onSuggestionAction) {
|
|
350
|
-
const result = options.onSuggestionAction(option);
|
|
351
|
-
if (result instanceof Promise) {
|
|
352
|
-
result.then((handled) => {
|
|
353
|
-
if (!handled) {
|
|
354
|
-
const optionHref2 = resolveOptionHref(
|
|
355
|
-
option,
|
|
356
|
-
localeParts
|
|
357
|
-
);
|
|
358
|
-
if (!optionHref2) {
|
|
359
|
-
const optionQuery2 = option?.value ?? option?.label ?? option?.identifier ?? "";
|
|
360
|
-
service.submitProductSearch(
|
|
361
|
-
String(optionQuery2)
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}).catch((error) => {
|
|
366
|
-
console.error(
|
|
367
|
-
"Error in onSuggestionAction:",
|
|
368
|
-
error
|
|
369
|
-
);
|
|
370
|
-
});
|
|
371
|
-
return "action-pending";
|
|
372
|
-
} else if (result === true) {
|
|
373
|
-
return "action-handled";
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
423
|
const optionHref = resolveOptionHref(option, localeParts);
|
|
377
424
|
if (optionHref) {
|
|
378
425
|
return stripLocalePrefix(optionHref, localeParts);
|
|
@@ -399,6 +446,35 @@ function createSearchService(options = {}) {
|
|
|
399
446
|
return service;
|
|
400
447
|
}
|
|
401
448
|
|
|
449
|
+
// src/services/marketConfig.ts
|
|
450
|
+
var fetchMarketConfig = async ({ country }) => {
|
|
451
|
+
const countryCode = String(country ?? "").trim().toUpperCase() || "US";
|
|
452
|
+
const configuration = await getConfiguration([EQUINOX_MARKETS_MAP], {
|
|
453
|
+
country: countryCode,
|
|
454
|
+
...getEnvironmentCode() ? { environment: getEnvironmentCode() } : {},
|
|
455
|
+
clientId: DEFAULT_EQUINOX_CLIENT_ID,
|
|
456
|
+
shoppingContext: STOREFRONT_SHOPPING_CONTEXT
|
|
457
|
+
});
|
|
458
|
+
return configuration?.[EQUINOX_MARKETS_MAP] ?? null;
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
// src/utils/gtmConstants.ts
|
|
462
|
+
var SEARCH_GTM_EVENTS = {
|
|
463
|
+
CHAT_ENTRY_POINT: "Begin_chat",
|
|
464
|
+
PRODUCT_SEARCH: "ProductSearch"};
|
|
465
|
+
var SEARCH_GTM_SEARCH_TYPES = {
|
|
466
|
+
SEMANTIC: "semantic search"};
|
|
467
|
+
var SEARCH_GTM_USER_STATUS = {
|
|
468
|
+
GUEST: "guest",
|
|
469
|
+
LOGGED_IN: "logged_in"
|
|
470
|
+
};
|
|
471
|
+
var GTM_FALLBACK_NA = "NA";
|
|
472
|
+
|
|
473
|
+
// src/utils/navigationTarget.ts
|
|
474
|
+
function toNavigationTarget(path) {
|
|
475
|
+
return /^https?:\/\//i.test(path) ? { type: "external", url: path } : { type: "internal", path };
|
|
476
|
+
}
|
|
477
|
+
|
|
402
478
|
// src/utils/catalogHelpers.ts
|
|
403
479
|
var CART_DISABLED_PRODUCT_STATUSES = /* @__PURE__ */ new Set([
|
|
404
480
|
"discontinued",
|
|
@@ -414,9 +490,6 @@ var CART_DISABLED_PRODUCT_STATUSES = /* @__PURE__ */ new Set([
|
|
|
414
490
|
function normalizeProductStatusValue(value) {
|
|
415
491
|
return String(value ?? "").trim().toLowerCase().replace(/\s+/g, "");
|
|
416
492
|
}
|
|
417
|
-
function isSellableProductStatus(productStatus) {
|
|
418
|
-
return normalizeProductStatusValue(productStatus) === "sellable";
|
|
419
|
-
}
|
|
420
493
|
function resolveSkuStatusValues(suggestionOption) {
|
|
421
494
|
return [
|
|
422
495
|
suggestionOption["productStatus"],
|
|
@@ -661,14 +734,6 @@ function getVisibleSuggestions(opts) {
|
|
|
661
734
|
}
|
|
662
735
|
return opts.suggestions;
|
|
663
736
|
}
|
|
664
|
-
function getSeeMoreResultsPayload(query, totalResultsCount, suggestions) {
|
|
665
|
-
return {
|
|
666
|
-
query,
|
|
667
|
-
source: "autocomplete-footer",
|
|
668
|
-
totalResultsCount,
|
|
669
|
-
visibleResultsCount: suggestions.length
|
|
670
|
-
};
|
|
671
|
-
}
|
|
672
737
|
|
|
673
738
|
// src/hooks/useSearchSuggestions.ts
|
|
674
739
|
function normalizeSuggestionsResponse(response) {
|
|
@@ -826,26 +891,6 @@ function useSearchSuggestions({
|
|
|
826
891
|
};
|
|
827
892
|
}
|
|
828
893
|
|
|
829
|
-
// src/utils/gtmConstants.ts
|
|
830
|
-
var SEARCH_GTM_EVENTS = {
|
|
831
|
-
CHAT_ENTRY_POINT: "Begin_chat",
|
|
832
|
-
SEARCH_TYPE: "Search_Type",
|
|
833
|
-
PRODUCT_SEARCH: "ProductSearch",
|
|
834
|
-
ERROR_POPUP: "Error_popup"
|
|
835
|
-
};
|
|
836
|
-
var SEARCH_GTM_SEARCH_TYPES = {
|
|
837
|
-
SEMANTIC: "semantic search",
|
|
838
|
-
AI_AGENT: "AI agent"
|
|
839
|
-
};
|
|
840
|
-
var SEARCH_GTM_USER_STATUS = {
|
|
841
|
-
GUEST: "guest",
|
|
842
|
-
LOGGED_IN: "logged_in"
|
|
843
|
-
};
|
|
844
|
-
var IS_AUTHENTICATED_KEY = "IsAuthenticated";
|
|
845
|
-
var ACCOUNT_TYPE_KEY = "accountType";
|
|
846
|
-
var NUSKIN_ACCOUNT_DATA_KEY = "nuskin.account.data";
|
|
847
|
-
var GTM_FALLBACK_NA = "NA";
|
|
848
|
-
|
|
849
894
|
// src/utils/commonUtils.ts
|
|
850
895
|
var IS_BROWSER = typeof window !== "undefined";
|
|
851
896
|
function toEventString(value, fallback = " ") {
|
|
@@ -853,84 +898,24 @@ function toEventString(value, fallback = " ") {
|
|
|
853
898
|
const str = String(value).trim();
|
|
854
899
|
return str.length > 0 ? str : fallback;
|
|
855
900
|
}
|
|
856
|
-
function getLocaleFromUrl(pathname) {
|
|
857
|
-
const path = pathname ?? (IS_BROWSER ? window.location.pathname : "");
|
|
858
|
-
const [country, language] = path.split("/").filter(Boolean);
|
|
859
|
-
if (!/^[a-z]{2}$/i.test(country ?? "") || !/^[a-z]{2}$/i.test(language ?? "")) {
|
|
860
|
-
return {};
|
|
861
|
-
}
|
|
862
|
-
return {
|
|
863
|
-
countryCode: country.toUpperCase(),
|
|
864
|
-
language: language.toLowerCase()
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
function safeParse(raw) {
|
|
868
|
-
try {
|
|
869
|
-
return JSON.parse(raw);
|
|
870
|
-
} catch {
|
|
871
|
-
return raw;
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
function getLocalStorage(key) {
|
|
875
|
-
if (!IS_BROWSER) return void 0;
|
|
876
|
-
try {
|
|
877
|
-
const raw = window.localStorage.getItem(key);
|
|
878
|
-
return raw === null ? void 0 : safeParse(raw);
|
|
879
|
-
} catch {
|
|
880
|
-
return void 0;
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
901
|
|
|
884
902
|
// src/utils/gtmTracking.ts
|
|
885
|
-
function readUserStatusFromStorage() {
|
|
886
|
-
const value = getLocalStorage(IS_AUTHENTICATED_KEY);
|
|
887
|
-
if (value === void 0) return void 0;
|
|
888
|
-
if (value === SEARCH_GTM_USER_STATUS.GUEST || value === SEARCH_GTM_USER_STATUS.LOGGED_IN) {
|
|
889
|
-
return value;
|
|
890
|
-
}
|
|
891
|
-
const isAuthenticated = value === true || typeof value === "string" && ["true", "1", "yes", "y"].includes(value.toLowerCase().trim());
|
|
892
|
-
return isAuthenticated ? SEARCH_GTM_USER_STATUS.LOGGED_IN : SEARCH_GTM_USER_STATUS.GUEST;
|
|
893
|
-
}
|
|
894
|
-
function readAccountTypeFromStorage() {
|
|
895
|
-
const value = getLocalStorage(ACCOUNT_TYPE_KEY);
|
|
896
|
-
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
897
|
-
}
|
|
898
|
-
function readUserIdFromStorage() {
|
|
899
|
-
const raw = getLocalStorage(NUSKIN_ACCOUNT_DATA_KEY);
|
|
900
|
-
if (!raw || typeof raw !== "object") return void 0;
|
|
901
|
-
const user = raw.user;
|
|
902
|
-
if (!user || typeof user !== "object") return void 0;
|
|
903
|
-
const id = user.id;
|
|
904
|
-
return typeof id === "string" && id.trim().length > 0 ? id : void 0;
|
|
905
|
-
}
|
|
906
903
|
function resolveUserId(explicit) {
|
|
907
|
-
return toEventString(explicit
|
|
904
|
+
return toEventString(explicit, GTM_FALLBACK_NA);
|
|
908
905
|
}
|
|
909
906
|
function baseEventPayload(ctx) {
|
|
910
|
-
const urlLocale = getLocaleFromUrl();
|
|
911
|
-
const userStatus = ctx.userStatus ?? readUserStatusFromStorage();
|
|
912
|
-
const accountType = ctx.accountType ?? readAccountTypeFromStorage();
|
|
913
|
-
const resolvedUserStatus = userStatus ?? SEARCH_GTM_USER_STATUS.GUEST;
|
|
914
|
-
const documentTitle = IS_BROWSER && typeof document?.title === "string" ? document.title : void 0;
|
|
915
907
|
return {
|
|
916
908
|
Chat_ID: toEventString(ctx.chatId, GTM_FALLBACK_NA),
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
),
|
|
921
|
-
|
|
922
|
-
ctx.countryCode ?? urlLocale.countryCode,
|
|
923
|
-
GTM_FALLBACK_NA
|
|
924
|
-
),
|
|
925
|
-
language: toEventString(
|
|
926
|
-
ctx.language ?? urlLocale.language,
|
|
927
|
-
GTM_FALLBACK_NA
|
|
928
|
-
),
|
|
909
|
+
// TODO: COMX-3277 puts `page_type` in every event but defines no values. Send `NA` until
|
|
910
|
+
// the data team says what it should hold (perhaps the page path).
|
|
911
|
+
page_type: GTM_FALLBACK_NA,
|
|
912
|
+
country_code: toEventString(ctx.countryCode, GTM_FALLBACK_NA),
|
|
913
|
+
language: toEventString(ctx.language, GTM_FALLBACK_NA),
|
|
929
914
|
user_status: toEventString(
|
|
930
|
-
|
|
915
|
+
ctx.userStatus ?? SEARCH_GTM_USER_STATUS.GUEST,
|
|
931
916
|
SEARCH_GTM_USER_STATUS.GUEST
|
|
932
917
|
),
|
|
933
|
-
account_type: toEventString(accountType, GTM_FALLBACK_NA)
|
|
918
|
+
account_type: toEventString(ctx.accountType, GTM_FALLBACK_NA)
|
|
934
919
|
};
|
|
935
920
|
}
|
|
936
921
|
function serializeProductResults(productResultsData, productResults) {
|
|
@@ -963,15 +948,6 @@ function trackChatEntryPoint(ctx) {
|
|
|
963
948
|
...baseEventPayload(ctx)
|
|
964
949
|
});
|
|
965
950
|
}
|
|
966
|
-
function trackSearchType(input) {
|
|
967
|
-
pushGtmEvent({
|
|
968
|
-
event: SEARCH_GTM_EVENTS.SEARCH_TYPE,
|
|
969
|
-
...baseEventPayload(input),
|
|
970
|
-
id: resolveUserId(input.userId),
|
|
971
|
-
type: input.searchType ?? SEARCH_GTM_SEARCH_TYPES.SEMANTIC,
|
|
972
|
-
search_response: toEventString(input.searchResponse, GTM_FALLBACK_NA)
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
951
|
function trackProductSearch(input) {
|
|
976
952
|
pushGtmEvent({
|
|
977
953
|
event: SEARCH_GTM_EVENTS.PRODUCT_SEARCH,
|
|
@@ -984,14 +960,6 @@ function trackProductSearch(input) {
|
|
|
984
960
|
)
|
|
985
961
|
});
|
|
986
962
|
}
|
|
987
|
-
function trackErrorPopup(input) {
|
|
988
|
-
pushGtmEvent({
|
|
989
|
-
event: SEARCH_GTM_EVENTS.ERROR_POPUP,
|
|
990
|
-
...baseEventPayload(input),
|
|
991
|
-
id: resolveUserId(input.userId),
|
|
992
|
-
search_type: input.searchType ?? SEARCH_GTM_SEARCH_TYPES.SEMANTIC
|
|
993
|
-
});
|
|
994
|
-
}
|
|
995
963
|
|
|
996
964
|
// src/utils/nuiSearchGate.ts
|
|
997
965
|
var NUI_SEARCH_FLAG = "enableNuiSearch";
|
|
@@ -1148,7 +1116,7 @@ function uniqueRecentSearches(queries) {
|
|
|
1148
1116
|
return true;
|
|
1149
1117
|
});
|
|
1150
1118
|
}
|
|
1151
|
-
function
|
|
1119
|
+
function CommerceSearchView({
|
|
1152
1120
|
isOpen,
|
|
1153
1121
|
onClose,
|
|
1154
1122
|
service,
|
|
@@ -1156,9 +1124,7 @@ function ProductSearch({
|
|
|
1156
1124
|
isAuthenticated,
|
|
1157
1125
|
agent,
|
|
1158
1126
|
logo,
|
|
1159
|
-
|
|
1160
|
-
fallbackImageUrl,
|
|
1161
|
-
copy,
|
|
1127
|
+
minimumSearchLength = MINIMUM_SEARCH_CHAR_LENGTH,
|
|
1162
1128
|
gtmContext
|
|
1163
1129
|
}) {
|
|
1164
1130
|
const [flag, setFlag] = useState(void 0);
|
|
@@ -1182,7 +1148,7 @@ function ProductSearch({
|
|
|
1182
1148
|
suggestions,
|
|
1183
1149
|
updateQuery
|
|
1184
1150
|
} = search;
|
|
1185
|
-
const enabled = isNuiSearchEnabled({ isAuthenticated, flag });
|
|
1151
|
+
const enabled = agent !== void 0 && isNuiSearchEnabled({ isAuthenticated, flag });
|
|
1186
1152
|
const items = getVisibleSuggestions({
|
|
1187
1153
|
didYouMean,
|
|
1188
1154
|
suggestions
|
|
@@ -1213,9 +1179,7 @@ function ProductSearch({
|
|
|
1213
1179
|
}, [isOpen, clearQuery]);
|
|
1214
1180
|
const navigateTo = useCallback(
|
|
1215
1181
|
(path) => {
|
|
1216
|
-
if (!path
|
|
1217
|
-
return;
|
|
1218
|
-
}
|
|
1182
|
+
if (!path) return;
|
|
1219
1183
|
navigate(path);
|
|
1220
1184
|
close();
|
|
1221
1185
|
},
|
|
@@ -1270,6 +1234,10 @@ function ProductSearch({
|
|
|
1270
1234
|
(value) => {
|
|
1271
1235
|
const term = value.trim();
|
|
1272
1236
|
if (!term) return;
|
|
1237
|
+
if (term.length < minimumSearchLength) {
|
|
1238
|
+
runSearch(term);
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1273
1241
|
const route = decide(term);
|
|
1274
1242
|
if (route === "wait") {
|
|
1275
1243
|
setPendingTerm(term);
|
|
@@ -1277,7 +1245,7 @@ function ProductSearch({
|
|
|
1277
1245
|
}
|
|
1278
1246
|
act(term, route);
|
|
1279
1247
|
},
|
|
1280
|
-
[act, decide]
|
|
1248
|
+
[act, decide, minimumSearchLength, runSearch]
|
|
1281
1249
|
);
|
|
1282
1250
|
const latest = useRef({ act, decide });
|
|
1283
1251
|
latest.current = { act, decide };
|
|
@@ -1356,9 +1324,6 @@ function ProductSearch({
|
|
|
1356
1324
|
isOpen,
|
|
1357
1325
|
onClose: close,
|
|
1358
1326
|
logo,
|
|
1359
|
-
...cancelLabel === void 0 ? {} : { cancelLabel },
|
|
1360
|
-
...fallbackImageUrl === void 0 ? {} : { fallbackImageUrl },
|
|
1361
|
-
...copy === void 0 ? {} : { copy },
|
|
1362
1327
|
input: {
|
|
1363
1328
|
value: query,
|
|
1364
1329
|
onChange: updateQuery,
|
|
@@ -1380,7 +1345,7 @@ function ProductSearch({
|
|
|
1380
1345
|
onSelect: handleRecentSelect,
|
|
1381
1346
|
onClear: handleClearRecent
|
|
1382
1347
|
},
|
|
1383
|
-
agentPanel: handoff === null ? void 0 : /* @__PURE__ */ jsx(
|
|
1348
|
+
agentPanel: handoff === null || agent === void 0 ? void 0 : /* @__PURE__ */ jsx(
|
|
1384
1349
|
NuiAgentPanel,
|
|
1385
1350
|
{
|
|
1386
1351
|
agent,
|
|
@@ -1397,7 +1362,69 @@ function ProductSearch({
|
|
|
1397
1362
|
}
|
|
1398
1363
|
);
|
|
1399
1364
|
}
|
|
1365
|
+
var GUEST = "guest";
|
|
1366
|
+
function CommerceSearch({
|
|
1367
|
+
isOpen,
|
|
1368
|
+
onClose,
|
|
1369
|
+
navigate,
|
|
1370
|
+
customer,
|
|
1371
|
+
country,
|
|
1372
|
+
language,
|
|
1373
|
+
logo
|
|
1374
|
+
}) {
|
|
1375
|
+
const [hasOpened, setHasOpened] = useState(false);
|
|
1376
|
+
useEffect(() => {
|
|
1377
|
+
if (isOpen) setHasOpened(true);
|
|
1378
|
+
}, [isOpen]);
|
|
1379
|
+
const { minimumSearchLength, agent } = useCommerceSearchConfig({
|
|
1380
|
+
country,
|
|
1381
|
+
language,
|
|
1382
|
+
enabled: hasOpened
|
|
1383
|
+
});
|
|
1384
|
+
const customerTypeRef = useRef(GUEST);
|
|
1385
|
+
customerTypeRef.current = customer.isAuthenticated ? customer.accountType ?? GUEST : GUEST;
|
|
1386
|
+
const service = useMemo(
|
|
1387
|
+
() => createSearchService({
|
|
1388
|
+
country,
|
|
1389
|
+
language,
|
|
1390
|
+
locale: `${country.toUpperCase()}-${language.toLowerCase()}`,
|
|
1391
|
+
getMarketConfig: fetchMarketConfig,
|
|
1392
|
+
minimumSearchLength,
|
|
1393
|
+
getCustomerType: () => customerTypeRef.current
|
|
1394
|
+
}),
|
|
1395
|
+
[country, language, minimumSearchLength]
|
|
1396
|
+
);
|
|
1397
|
+
const navigateToPath = useCallback(
|
|
1398
|
+
(path) => navigate(toNavigationTarget(path)),
|
|
1399
|
+
[navigate]
|
|
1400
|
+
);
|
|
1401
|
+
const { isAuthenticated, accountType, userId } = customer;
|
|
1402
|
+
const gtmContext = useMemo(
|
|
1403
|
+
() => ({
|
|
1404
|
+
countryCode: country,
|
|
1405
|
+
language,
|
|
1406
|
+
userStatus: isAuthenticated ? SEARCH_GTM_USER_STATUS.LOGGED_IN : SEARCH_GTM_USER_STATUS.GUEST,
|
|
1407
|
+
...isAuthenticated && accountType ? { accountType } : {},
|
|
1408
|
+
...isAuthenticated && userId ? { userId } : {}
|
|
1409
|
+
}),
|
|
1410
|
+
[country, language, isAuthenticated, accountType, userId]
|
|
1411
|
+
);
|
|
1412
|
+
return /* @__PURE__ */ jsx(
|
|
1413
|
+
CommerceSearchView,
|
|
1414
|
+
{
|
|
1415
|
+
isOpen,
|
|
1416
|
+
onClose,
|
|
1417
|
+
service,
|
|
1418
|
+
navigate: navigateToPath,
|
|
1419
|
+
isAuthenticated,
|
|
1420
|
+
...agent ? { agent } : {},
|
|
1421
|
+
logo,
|
|
1422
|
+
minimumSearchLength,
|
|
1423
|
+
gtmContext
|
|
1424
|
+
}
|
|
1425
|
+
);
|
|
1426
|
+
}
|
|
1400
1427
|
|
|
1401
|
-
export {
|
|
1428
|
+
export { CommerceSearch };
|
|
1402
1429
|
//# sourceMappingURL=index.mjs.map
|
|
1403
1430
|
//# sourceMappingURL=index.mjs.map
|