@nuskin/react-search-sdk 1.0.0-trying-again.1 → 1.0.0-trying-again.2
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 +199 -213
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +196 -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);
|
|
@@ -281,15 +353,9 @@ function createSearchService(options = {}) {
|
|
|
281
353
|
return catalogRequestConfigPromise;
|
|
282
354
|
}
|
|
283
355
|
const service = {
|
|
284
|
-
async getSearchChromeCopy() {
|
|
285
|
-
return {
|
|
286
|
-
placeholder: searchPlaceholder || DEFAULT_SEARCH_PLACEHOLDER,
|
|
287
|
-
inputAriaLabel: inputAriaLabel || DEFAULT_INPUT_ARIA_LABEL
|
|
288
|
-
};
|
|
289
|
-
},
|
|
290
356
|
async fetchSuggestions(searchTerm) {
|
|
291
357
|
const trimmedSearchTerm = String(searchTerm ?? "").trim();
|
|
292
|
-
if (!trimmedSearchTerm || !fetchImpl) {
|
|
358
|
+
if (!trimmedSearchTerm || trimmedSearchTerm.length < minimumSearchLength || !fetchImpl) {
|
|
293
359
|
return {
|
|
294
360
|
suggestions: [],
|
|
295
361
|
didYouMean: [],
|
|
@@ -314,7 +380,8 @@ function createSearchService(options = {}) {
|
|
|
314
380
|
const requestUrls = [`${suggestionsUrl}?${queryParams.toString()}`];
|
|
315
381
|
const responsePayload = await fetchJsonFromCandidates(
|
|
316
382
|
fetchImpl,
|
|
317
|
-
requestUrls
|
|
383
|
+
requestUrls,
|
|
384
|
+
resolveCustomerTypeHeaders(getCustomerType)
|
|
318
385
|
);
|
|
319
386
|
const suggestionsField = Array.isArray(responsePayload?.suggestions) ? responsePayload?.suggestions : [];
|
|
320
387
|
const productField = Array.isArray(responsePayload?.product) ? responsePayload?.product : null;
|
|
@@ -346,33 +413,6 @@ function createSearchService(options = {}) {
|
|
|
346
413
|
return stripLocalePrefix(targetPath, localeParts);
|
|
347
414
|
},
|
|
348
415
|
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
416
|
const optionHref = resolveOptionHref(option, localeParts);
|
|
377
417
|
if (optionHref) {
|
|
378
418
|
return stripLocalePrefix(optionHref, localeParts);
|
|
@@ -399,6 +439,35 @@ function createSearchService(options = {}) {
|
|
|
399
439
|
return service;
|
|
400
440
|
}
|
|
401
441
|
|
|
442
|
+
// src/services/marketConfig.ts
|
|
443
|
+
var fetchMarketConfig = async ({ country }) => {
|
|
444
|
+
const countryCode = String(country ?? "").trim().toUpperCase() || "US";
|
|
445
|
+
const configuration = await getConfiguration([EQUINOX_MARKETS_MAP], {
|
|
446
|
+
country: countryCode,
|
|
447
|
+
...getEnvironmentCode() ? { environment: getEnvironmentCode() } : {},
|
|
448
|
+
clientId: DEFAULT_EQUINOX_CLIENT_ID,
|
|
449
|
+
shoppingContext: STOREFRONT_SHOPPING_CONTEXT
|
|
450
|
+
});
|
|
451
|
+
return configuration?.[EQUINOX_MARKETS_MAP] ?? null;
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
// src/utils/gtmConstants.ts
|
|
455
|
+
var SEARCH_GTM_EVENTS = {
|
|
456
|
+
CHAT_ENTRY_POINT: "Begin_chat",
|
|
457
|
+
PRODUCT_SEARCH: "ProductSearch"};
|
|
458
|
+
var SEARCH_GTM_SEARCH_TYPES = {
|
|
459
|
+
SEMANTIC: "semantic search"};
|
|
460
|
+
var SEARCH_GTM_USER_STATUS = {
|
|
461
|
+
GUEST: "guest",
|
|
462
|
+
LOGGED_IN: "logged_in"
|
|
463
|
+
};
|
|
464
|
+
var GTM_FALLBACK_NA = "NA";
|
|
465
|
+
|
|
466
|
+
// src/utils/navigationTarget.ts
|
|
467
|
+
function toNavigationTarget(path) {
|
|
468
|
+
return /^https?:\/\//i.test(path) ? { type: "external", url: path } : { type: "internal", path };
|
|
469
|
+
}
|
|
470
|
+
|
|
402
471
|
// src/utils/catalogHelpers.ts
|
|
403
472
|
var CART_DISABLED_PRODUCT_STATUSES = /* @__PURE__ */ new Set([
|
|
404
473
|
"discontinued",
|
|
@@ -414,9 +483,6 @@ var CART_DISABLED_PRODUCT_STATUSES = /* @__PURE__ */ new Set([
|
|
|
414
483
|
function normalizeProductStatusValue(value) {
|
|
415
484
|
return String(value ?? "").trim().toLowerCase().replace(/\s+/g, "");
|
|
416
485
|
}
|
|
417
|
-
function isSellableProductStatus(productStatus) {
|
|
418
|
-
return normalizeProductStatusValue(productStatus) === "sellable";
|
|
419
|
-
}
|
|
420
486
|
function resolveSkuStatusValues(suggestionOption) {
|
|
421
487
|
return [
|
|
422
488
|
suggestionOption["productStatus"],
|
|
@@ -661,14 +727,6 @@ function getVisibleSuggestions(opts) {
|
|
|
661
727
|
}
|
|
662
728
|
return opts.suggestions;
|
|
663
729
|
}
|
|
664
|
-
function getSeeMoreResultsPayload(query, totalResultsCount, suggestions) {
|
|
665
|
-
return {
|
|
666
|
-
query,
|
|
667
|
-
source: "autocomplete-footer",
|
|
668
|
-
totalResultsCount,
|
|
669
|
-
visibleResultsCount: suggestions.length
|
|
670
|
-
};
|
|
671
|
-
}
|
|
672
730
|
|
|
673
731
|
// src/hooks/useSearchSuggestions.ts
|
|
674
732
|
function normalizeSuggestionsResponse(response) {
|
|
@@ -826,26 +884,6 @@ function useSearchSuggestions({
|
|
|
826
884
|
};
|
|
827
885
|
}
|
|
828
886
|
|
|
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
887
|
// src/utils/commonUtils.ts
|
|
850
888
|
var IS_BROWSER = typeof window !== "undefined";
|
|
851
889
|
function toEventString(value, fallback = " ") {
|
|
@@ -853,84 +891,24 @@ function toEventString(value, fallback = " ") {
|
|
|
853
891
|
const str = String(value).trim();
|
|
854
892
|
return str.length > 0 ? str : fallback;
|
|
855
893
|
}
|
|
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
894
|
|
|
884
895
|
// 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
896
|
function resolveUserId(explicit) {
|
|
907
|
-
return toEventString(explicit
|
|
897
|
+
return toEventString(explicit, GTM_FALLBACK_NA);
|
|
908
898
|
}
|
|
909
899
|
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
900
|
return {
|
|
916
901
|
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
|
-
),
|
|
902
|
+
// TODO: COMX-3277 puts `page_type` in every event but defines no values. Send `NA` until
|
|
903
|
+
// the data team says what it should hold (perhaps the page path).
|
|
904
|
+
page_type: GTM_FALLBACK_NA,
|
|
905
|
+
country_code: toEventString(ctx.countryCode, GTM_FALLBACK_NA),
|
|
906
|
+
language: toEventString(ctx.language, GTM_FALLBACK_NA),
|
|
929
907
|
user_status: toEventString(
|
|
930
|
-
|
|
908
|
+
ctx.userStatus ?? SEARCH_GTM_USER_STATUS.GUEST,
|
|
931
909
|
SEARCH_GTM_USER_STATUS.GUEST
|
|
932
910
|
),
|
|
933
|
-
account_type: toEventString(accountType, GTM_FALLBACK_NA)
|
|
911
|
+
account_type: toEventString(ctx.accountType, GTM_FALLBACK_NA)
|
|
934
912
|
};
|
|
935
913
|
}
|
|
936
914
|
function serializeProductResults(productResultsData, productResults) {
|
|
@@ -963,15 +941,6 @@ function trackChatEntryPoint(ctx) {
|
|
|
963
941
|
...baseEventPayload(ctx)
|
|
964
942
|
});
|
|
965
943
|
}
|
|
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
944
|
function trackProductSearch(input) {
|
|
976
945
|
pushGtmEvent({
|
|
977
946
|
event: SEARCH_GTM_EVENTS.PRODUCT_SEARCH,
|
|
@@ -984,14 +953,6 @@ function trackProductSearch(input) {
|
|
|
984
953
|
)
|
|
985
954
|
});
|
|
986
955
|
}
|
|
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
956
|
|
|
996
957
|
// src/utils/nuiSearchGate.ts
|
|
997
958
|
var NUI_SEARCH_FLAG = "enableNuiSearch";
|
|
@@ -1148,7 +1109,7 @@ function uniqueRecentSearches(queries) {
|
|
|
1148
1109
|
return true;
|
|
1149
1110
|
});
|
|
1150
1111
|
}
|
|
1151
|
-
function
|
|
1112
|
+
function CommerceSearchView({
|
|
1152
1113
|
isOpen,
|
|
1153
1114
|
onClose,
|
|
1154
1115
|
service,
|
|
@@ -1156,9 +1117,7 @@ function ProductSearch({
|
|
|
1156
1117
|
isAuthenticated,
|
|
1157
1118
|
agent,
|
|
1158
1119
|
logo,
|
|
1159
|
-
|
|
1160
|
-
fallbackImageUrl,
|
|
1161
|
-
copy,
|
|
1120
|
+
minimumSearchLength = MINIMUM_SEARCH_CHAR_LENGTH,
|
|
1162
1121
|
gtmContext
|
|
1163
1122
|
}) {
|
|
1164
1123
|
const [flag, setFlag] = useState(void 0);
|
|
@@ -1182,7 +1141,7 @@ function ProductSearch({
|
|
|
1182
1141
|
suggestions,
|
|
1183
1142
|
updateQuery
|
|
1184
1143
|
} = search;
|
|
1185
|
-
const enabled = isNuiSearchEnabled({ isAuthenticated, flag });
|
|
1144
|
+
const enabled = agent !== void 0 && isNuiSearchEnabled({ isAuthenticated, flag });
|
|
1186
1145
|
const items = getVisibleSuggestions({
|
|
1187
1146
|
didYouMean,
|
|
1188
1147
|
suggestions
|
|
@@ -1213,9 +1172,7 @@ function ProductSearch({
|
|
|
1213
1172
|
}, [isOpen, clearQuery]);
|
|
1214
1173
|
const navigateTo = useCallback(
|
|
1215
1174
|
(path) => {
|
|
1216
|
-
if (!path
|
|
1217
|
-
return;
|
|
1218
|
-
}
|
|
1175
|
+
if (!path) return;
|
|
1219
1176
|
navigate(path);
|
|
1220
1177
|
close();
|
|
1221
1178
|
},
|
|
@@ -1270,6 +1227,10 @@ function ProductSearch({
|
|
|
1270
1227
|
(value) => {
|
|
1271
1228
|
const term = value.trim();
|
|
1272
1229
|
if (!term) return;
|
|
1230
|
+
if (term.length < minimumSearchLength) {
|
|
1231
|
+
runSearch(term);
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1273
1234
|
const route = decide(term);
|
|
1274
1235
|
if (route === "wait") {
|
|
1275
1236
|
setPendingTerm(term);
|
|
@@ -1277,7 +1238,7 @@ function ProductSearch({
|
|
|
1277
1238
|
}
|
|
1278
1239
|
act(term, route);
|
|
1279
1240
|
},
|
|
1280
|
-
[act, decide]
|
|
1241
|
+
[act, decide, minimumSearchLength, runSearch]
|
|
1281
1242
|
);
|
|
1282
1243
|
const latest = useRef({ act, decide });
|
|
1283
1244
|
latest.current = { act, decide };
|
|
@@ -1356,9 +1317,6 @@ function ProductSearch({
|
|
|
1356
1317
|
isOpen,
|
|
1357
1318
|
onClose: close,
|
|
1358
1319
|
logo,
|
|
1359
|
-
...cancelLabel === void 0 ? {} : { cancelLabel },
|
|
1360
|
-
...fallbackImageUrl === void 0 ? {} : { fallbackImageUrl },
|
|
1361
|
-
...copy === void 0 ? {} : { copy },
|
|
1362
1320
|
input: {
|
|
1363
1321
|
value: query,
|
|
1364
1322
|
onChange: updateQuery,
|
|
@@ -1380,7 +1338,7 @@ function ProductSearch({
|
|
|
1380
1338
|
onSelect: handleRecentSelect,
|
|
1381
1339
|
onClear: handleClearRecent
|
|
1382
1340
|
},
|
|
1383
|
-
agentPanel: handoff === null ? void 0 : /* @__PURE__ */ jsx(
|
|
1341
|
+
agentPanel: handoff === null || agent === void 0 ? void 0 : /* @__PURE__ */ jsx(
|
|
1384
1342
|
NuiAgentPanel,
|
|
1385
1343
|
{
|
|
1386
1344
|
agent,
|
|
@@ -1397,7 +1355,69 @@ function ProductSearch({
|
|
|
1397
1355
|
}
|
|
1398
1356
|
);
|
|
1399
1357
|
}
|
|
1358
|
+
var GUEST = "guest";
|
|
1359
|
+
function CommerceSearch({
|
|
1360
|
+
isOpen,
|
|
1361
|
+
onClose,
|
|
1362
|
+
navigate,
|
|
1363
|
+
customer,
|
|
1364
|
+
country,
|
|
1365
|
+
language,
|
|
1366
|
+
logo
|
|
1367
|
+
}) {
|
|
1368
|
+
const [hasOpened, setHasOpened] = useState(false);
|
|
1369
|
+
useEffect(() => {
|
|
1370
|
+
if (isOpen) setHasOpened(true);
|
|
1371
|
+
}, [isOpen]);
|
|
1372
|
+
const { minimumSearchLength, agent } = useCommerceSearchConfig({
|
|
1373
|
+
country,
|
|
1374
|
+
language,
|
|
1375
|
+
enabled: hasOpened
|
|
1376
|
+
});
|
|
1377
|
+
const customerTypeRef = useRef(GUEST);
|
|
1378
|
+
customerTypeRef.current = customer.isAuthenticated ? customer.accountType ?? GUEST : GUEST;
|
|
1379
|
+
const service = useMemo(
|
|
1380
|
+
() => createSearchService({
|
|
1381
|
+
country,
|
|
1382
|
+
language,
|
|
1383
|
+
locale: `${country.toUpperCase()}-${language.toLowerCase()}`,
|
|
1384
|
+
getMarketConfig: fetchMarketConfig,
|
|
1385
|
+
minimumSearchLength,
|
|
1386
|
+
getCustomerType: () => customerTypeRef.current
|
|
1387
|
+
}),
|
|
1388
|
+
[country, language, minimumSearchLength]
|
|
1389
|
+
);
|
|
1390
|
+
const navigateToPath = useCallback(
|
|
1391
|
+
(path) => navigate(toNavigationTarget(path)),
|
|
1392
|
+
[navigate]
|
|
1393
|
+
);
|
|
1394
|
+
const { isAuthenticated, accountType, userId } = customer;
|
|
1395
|
+
const gtmContext = useMemo(
|
|
1396
|
+
() => ({
|
|
1397
|
+
countryCode: country,
|
|
1398
|
+
language,
|
|
1399
|
+
userStatus: isAuthenticated ? SEARCH_GTM_USER_STATUS.LOGGED_IN : SEARCH_GTM_USER_STATUS.GUEST,
|
|
1400
|
+
...isAuthenticated && accountType ? { accountType } : {},
|
|
1401
|
+
...isAuthenticated && userId ? { userId } : {}
|
|
1402
|
+
}),
|
|
1403
|
+
[country, language, isAuthenticated, accountType, userId]
|
|
1404
|
+
);
|
|
1405
|
+
return /* @__PURE__ */ jsx(
|
|
1406
|
+
CommerceSearchView,
|
|
1407
|
+
{
|
|
1408
|
+
isOpen,
|
|
1409
|
+
onClose,
|
|
1410
|
+
service,
|
|
1411
|
+
navigate: navigateToPath,
|
|
1412
|
+
isAuthenticated,
|
|
1413
|
+
...agent ? { agent } : {},
|
|
1414
|
+
logo,
|
|
1415
|
+
minimumSearchLength,
|
|
1416
|
+
gtmContext
|
|
1417
|
+
}
|
|
1418
|
+
);
|
|
1419
|
+
}
|
|
1400
1420
|
|
|
1401
|
-
export {
|
|
1421
|
+
export { CommerceSearch };
|
|
1402
1422
|
//# sourceMappingURL=index.mjs.map
|
|
1403
1423
|
//# sourceMappingURL=index.mjs.map
|