@seekora-ai/ui-sdk-react 0.2.7 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/RichQuerySuggestions.d.ts +4 -0
- package/dist/components/RichQuerySuggestions.d.ts.map +1 -1
- package/dist/components/RichQuerySuggestions.js +3 -1
- package/dist/components/suggestions/SuggestionSearchBar.d.ts +4 -0
- package/dist/components/suggestions/SuggestionSearchBar.d.ts.map +1 -1
- package/dist/components/suggestions/SuggestionSearchBar.js +6 -2
- package/dist/components/suggestions-primitives/SearchInput.d.ts +5 -1
- package/dist/components/suggestions-primitives/SearchInput.d.ts.map +1 -1
- package/dist/components/suggestions-primitives/SearchInput.js +5 -2
- package/dist/hooks/useQuerySuggestionsEnhanced.d.ts +4 -0
- package/dist/hooks/useQuerySuggestionsEnhanced.d.ts.map +1 -1
- package/dist/hooks/useQuerySuggestionsEnhanced.js +35 -9
- package/dist/index.umd.js +1 -1
- package/dist/src/index.d.ts +17 -1
- package/dist/src/index.esm.js +49 -14
- package/dist/src/index.esm.js.map +1 -1
- package/dist/src/index.js +49 -14
- package/dist/src/index.js.map +1 -1
- package/package.json +3 -3
package/dist/src/index.d.ts
CHANGED
|
@@ -1074,6 +1074,10 @@ interface RichQuerySuggestionsProps extends QuerySuggestionsEventHandlers {
|
|
|
1074
1074
|
debounceMs?: number;
|
|
1075
1075
|
/** Include dropdown recommendations from API */
|
|
1076
1076
|
includeDropdownRecommendations?: boolean;
|
|
1077
|
+
/** When false, omit product hits list from dropdown (default true) */
|
|
1078
|
+
includeDropdownProductList?: boolean;
|
|
1079
|
+
/** When false, omit filtered_tabs from dropdown (default true) */
|
|
1080
|
+
includeFilteredTabs?: boolean;
|
|
1077
1081
|
/** Include categories in suggestions */
|
|
1078
1082
|
includeCategories?: boolean;
|
|
1079
1083
|
/** Max categories per suggestion */
|
|
@@ -1346,6 +1350,10 @@ interface UseQuerySuggestionsEnhancedOptions {
|
|
|
1346
1350
|
minQueryLength?: number;
|
|
1347
1351
|
/** Include dropdown recommendations (trending, products, etc.) */
|
|
1348
1352
|
includeDropdownRecommendations?: boolean;
|
|
1353
|
+
/** When false, omit product hits list from dropdown (default true) */
|
|
1354
|
+
includeDropdownProductList?: boolean;
|
|
1355
|
+
/** When false, omit filtered_tabs from dropdown extensions (default true) */
|
|
1356
|
+
includeFilteredTabs?: boolean;
|
|
1349
1357
|
/** Include categories in suggestions */
|
|
1350
1358
|
includeCategories?: boolean;
|
|
1351
1359
|
/** Include facets in suggestions */
|
|
@@ -1518,13 +1526,17 @@ interface SearchInputProps {
|
|
|
1518
1526
|
placeholder?: string;
|
|
1519
1527
|
autoFocus?: boolean;
|
|
1520
1528
|
showClearButton?: boolean;
|
|
1529
|
+
/** When false, blur does not close the dropdown (e.g. for overlay mode). Default true. */
|
|
1530
|
+
closeOnBlur?: boolean;
|
|
1531
|
+
/** Optional icon (e.g. magnifying glass) rendered to the left of the input */
|
|
1532
|
+
leftIcon?: React__default.ReactNode;
|
|
1521
1533
|
className?: string;
|
|
1522
1534
|
style?: React__default.CSSProperties;
|
|
1523
1535
|
inputClassName?: string;
|
|
1524
1536
|
inputStyle?: React__default.CSSProperties;
|
|
1525
1537
|
ariaLabel?: string;
|
|
1526
1538
|
}
|
|
1527
|
-
declare function SearchInput({ placeholder, autoFocus, showClearButton, className, style, inputClassName, inputStyle, ariaLabel, }: SearchInputProps): React__default.JSX.Element;
|
|
1539
|
+
declare function SearchInput({ placeholder, autoFocus, showClearButton, closeOnBlur, leftIcon, className, style, inputClassName, inputStyle, ariaLabel, }: SearchInputProps): React__default.JSX.Element;
|
|
1528
1540
|
|
|
1529
1541
|
/**
|
|
1530
1542
|
* DropdownPanel – floating panel for suggestions (primitive)
|
|
@@ -2640,6 +2652,10 @@ interface SuggestionSearchBarProps {
|
|
|
2640
2652
|
debounceMs?: number;
|
|
2641
2653
|
/** Include dropdown recommendations (products, tabs, trending) */
|
|
2642
2654
|
includeDropdownRecommendations?: boolean;
|
|
2655
|
+
/** When false, omit product hits list from dropdown (default true) */
|
|
2656
|
+
includeDropdownProductList?: boolean;
|
|
2657
|
+
/** When false, omit filtered_tabs from dropdown (default true) */
|
|
2658
|
+
includeFilteredTabs?: boolean;
|
|
2643
2659
|
/** Include categories per suggestion */
|
|
2644
2660
|
includeCategories?: boolean;
|
|
2645
2661
|
/** Filtered tabs configuration */
|
package/dist/src/index.esm.js
CHANGED
|
@@ -4534,15 +4534,16 @@ function parseHighlight(highlighted) {
|
|
|
4534
4534
|
.replace(/__\/ais-highlight__/g, '</mark>');
|
|
4535
4535
|
}
|
|
4536
4536
|
function transformProduct(raw) {
|
|
4537
|
+
const meta = raw.metadata || {};
|
|
4537
4538
|
return {
|
|
4538
4539
|
id: raw.id || raw.objectID,
|
|
4539
4540
|
objectID: raw.objectID || raw.id,
|
|
4540
|
-
title: raw.title || raw.name || raw.productName,
|
|
4541
|
-
name: raw.name || raw.title,
|
|
4542
|
-
image: raw.image || raw.imageUrl ||
|
|
4543
|
-
price: raw.price
|
|
4544
|
-
currency: raw.currency ||
|
|
4545
|
-
url: raw.url || raw.productId ||
|
|
4541
|
+
title: raw.title || raw.name || raw.productName || meta.name || meta.productName || '',
|
|
4542
|
+
name: raw.name || raw.title || meta.name || meta.productName || '',
|
|
4543
|
+
image: raw.image || raw.imageUrl || meta.image || meta.image_url || meta.images?.[0] || '',
|
|
4544
|
+
price: raw.price ?? raw.sellPrice ?? meta.sellPrice ?? meta.price,
|
|
4545
|
+
currency: raw.currency || meta.currency || '',
|
|
4546
|
+
url: raw.url || raw.productId || meta.url || meta.productId || '',
|
|
4546
4547
|
clicks: raw.clicks,
|
|
4547
4548
|
conversions: raw.conversions,
|
|
4548
4549
|
revenue: raw.revenue,
|
|
@@ -4564,7 +4565,7 @@ function transformFilteredTab(raw) {
|
|
|
4564
4565
|
// Main Hook
|
|
4565
4566
|
// ============================================================================
|
|
4566
4567
|
function useQuerySuggestionsEnhanced(options) {
|
|
4567
|
-
const { client, query, enabled = true, debounceMs = 200, maxSuggestions = 10, minQueryLength = 1, includeDropdownRecommendations = false, includeCategories = true, includeFacets = false, maxCategories = 3, maxFacets = 5, filteredTabs, minPopularity, timeRange, disableTypoTolerance, analyticsTags, enableRecentSearches = true, maxRecentSearches = MAX_RECENT_SEARCHES_DEFAULT, recentSearchesKey = RECENT_SEARCHES_DEFAULT_KEY, onSuggestionsLoaded, onError, } = options;
|
|
4568
|
+
const { client, query, enabled = true, debounceMs = 200, maxSuggestions = 10, minQueryLength = 1, includeDropdownRecommendations = false, includeDropdownProductList = true, includeFilteredTabs = true, includeCategories = true, includeFacets = false, maxCategories = 3, maxFacets = 5, filteredTabs, minPopularity, timeRange, disableTypoTolerance, analyticsTags, enableRecentSearches = true, maxRecentSearches = MAX_RECENT_SEARCHES_DEFAULT, recentSearchesKey = RECENT_SEARCHES_DEFAULT_KEY, onSuggestionsLoaded, onError, } = options;
|
|
4568
4569
|
// State
|
|
4569
4570
|
const [suggestions, setSuggestions] = useState([]);
|
|
4570
4571
|
const [loading, setLoading] = useState(false);
|
|
@@ -4592,7 +4593,10 @@ function useQuerySuggestionsEnhanced(options) {
|
|
|
4592
4593
|
}, [enableRecentSearches, recentSearchesKey, maxRecentSearches]);
|
|
4593
4594
|
// Fetch suggestions
|
|
4594
4595
|
const fetchSuggestions = useCallback(async (searchQuery) => {
|
|
4595
|
-
if (!client
|
|
4596
|
+
if (!client)
|
|
4597
|
+
return;
|
|
4598
|
+
// When minQueryLength is 0, allow empty query so overlay can show default/trending recommendations on open
|
|
4599
|
+
if (!searchQuery.trim() && minQueryLength > 0) {
|
|
4596
4600
|
setSuggestions([]);
|
|
4597
4601
|
setDropdownRecommendations(null);
|
|
4598
4602
|
return;
|
|
@@ -4608,6 +4612,8 @@ function useQuerySuggestionsEnhanced(options) {
|
|
|
4608
4612
|
const response = await client.getSuggestions?.(searchQuery, {
|
|
4609
4613
|
hitsPerPage: maxSuggestions,
|
|
4610
4614
|
include_dropdown_recommendations: includeDropdownRecommendations || (filteredTabs && filteredTabs.length > 0),
|
|
4615
|
+
include_dropdown_product_list: includeDropdownProductList,
|
|
4616
|
+
include_filtered_tabs: includeFilteredTabs,
|
|
4611
4617
|
include_categories: includeCategories,
|
|
4612
4618
|
include_facets: includeFacets,
|
|
4613
4619
|
max_categories: maxCategories,
|
|
@@ -4627,12 +4633,17 @@ function useQuerySuggestionsEnhanced(options) {
|
|
|
4627
4633
|
setSuggestions(transformedSuggestions);
|
|
4628
4634
|
// Extract dropdown recommendations from extensions
|
|
4629
4635
|
const extensions = (response.extensions || {});
|
|
4636
|
+
const rawResults = response.results;
|
|
4637
|
+
const secondResultHits = Array.isArray(rawResults?.[1]?.hits) ? rawResults[1].hits : [];
|
|
4638
|
+
// Multi-index response: results[0]=suggestions, results[1]=product hits; expose results[1].hits as product_hits for fallback when extensions have no products
|
|
4639
|
+
const productHits = secondResultHits.length > 0 ? secondResultHits.map((h) => transformProduct(h)) : [];
|
|
4630
4640
|
const recommendations = {
|
|
4631
4641
|
trending_searches: Array.isArray(extensions.trending_searches) ? extensions.trending_searches : [],
|
|
4632
4642
|
top_searches: Array.isArray(extensions.top_searches) ? extensions.top_searches : [],
|
|
4633
4643
|
related_searches: Array.isArray(extensions.related_searches) ? extensions.related_searches : [],
|
|
4634
4644
|
trending_products: Array.isArray(extensions.trending_products) ? extensions.trending_products.map(transformProduct) : [],
|
|
4635
4645
|
item_recommendations: Array.isArray(extensions.item_recommendations) ? extensions.item_recommendations.map(transformProduct) : [],
|
|
4646
|
+
product_hits: productHits.length > 0 ? productHits : undefined,
|
|
4636
4647
|
popular_brands: Array.isArray(extensions.popular_brands) ? extensions.popular_brands : [],
|
|
4637
4648
|
filtered_tabs: Array.isArray(extensions.filtered_tabs) ? extensions.filtered_tabs.map(transformFilteredTab) : [],
|
|
4638
4649
|
processing_time_ms: typeof extensions.processing_time_ms === 'number' ? extensions.processing_time_ms : undefined,
|
|
@@ -4692,8 +4703,11 @@ function useQuerySuggestionsEnhanced(options) {
|
|
|
4692
4703
|
}
|
|
4693
4704
|
}, [
|
|
4694
4705
|
client,
|
|
4706
|
+
minQueryLength,
|
|
4695
4707
|
maxSuggestions,
|
|
4696
4708
|
includeDropdownRecommendations,
|
|
4709
|
+
includeDropdownProductList,
|
|
4710
|
+
includeFilteredTabs,
|
|
4697
4711
|
includeCategories,
|
|
4698
4712
|
includeFacets,
|
|
4699
4713
|
maxCategories,
|
|
@@ -4768,7 +4782,19 @@ function useQuerySuggestionsEnhanced(options) {
|
|
|
4768
4782
|
const relatedSearches = dropdownRecommendations?.related_searches || [];
|
|
4769
4783
|
const popularBrands = dropdownRecommendations?.popular_brands || [];
|
|
4770
4784
|
const filteredTabsResult = dropdownRecommendations?.filtered_tabs || [];
|
|
4771
|
-
|
|
4785
|
+
// Use trending_products, then item_recommendations, then first filtered_tab's products, then results[1].hits (product_hits) so grid shows for any API shape
|
|
4786
|
+
const trendingProducts = useMemo(() => {
|
|
4787
|
+
const fromTrending = dropdownRecommendations?.trending_products;
|
|
4788
|
+
if (fromTrending && fromTrending.length > 0)
|
|
4789
|
+
return fromTrending;
|
|
4790
|
+
const fromItemRecs = dropdownRecommendations?.item_recommendations;
|
|
4791
|
+
if (fromItemRecs && fromItemRecs.length > 0)
|
|
4792
|
+
return fromItemRecs;
|
|
4793
|
+
const firstTab = dropdownRecommendations?.filtered_tabs?.[0];
|
|
4794
|
+
if (firstTab?.products && firstTab.products.length > 0)
|
|
4795
|
+
return firstTab.products;
|
|
4796
|
+
return dropdownRecommendations?.product_hits ?? [];
|
|
4797
|
+
}, [dropdownRecommendations?.trending_products, dropdownRecommendations?.item_recommendations, dropdownRecommendations?.filtered_tabs, dropdownRecommendations?.product_hits]);
|
|
4772
4798
|
const hasContent = useMemo(() => {
|
|
4773
4799
|
return (suggestions.length > 0 ||
|
|
4774
4800
|
recentSearches.length > 0 ||
|
|
@@ -5451,7 +5477,7 @@ const CloseIcon = () => (React.createElement("svg", { viewBox: "0 0 20 20", fill
|
|
|
5451
5477
|
// Component
|
|
5452
5478
|
// ============================================================================
|
|
5453
5479
|
const RichQuerySuggestions = forwardRef(function RichQuerySuggestions(props, ref) {
|
|
5454
|
-
const { query, isOpen = true, sections = DEFAULT_SECTIONS, maxSuggestionsPerSection = 8, minQueryLength = 0, debounceMs = 200, includeDropdownRecommendations = true, includeCategories = true, maxCategories = 3, showCounts = true, showCategoryCounts = true, showSectionHeaders = true, classNames = {}, style, renderSuggestion, renderCategory, renderTrendingItem, renderRecentItem, header, footer, width = '100%', maxHeight = '480px', zIndex = 1000, ariaLabel = 'Search suggestions', analyticsTags, onSuggestionSelect, onCategoryClick, onRecentSearchClick, onRecentSearchRemove, onViewAllClick, onOpen, onClose, } = props;
|
|
5480
|
+
const { query, isOpen = true, sections = DEFAULT_SECTIONS, maxSuggestionsPerSection = 8, minQueryLength = 0, debounceMs = 200, includeDropdownRecommendations = true, includeDropdownProductList = true, includeFilteredTabs = true, includeCategories = true, maxCategories = 3, showCounts = true, showCategoryCounts = true, showSectionHeaders = true, classNames = {}, style, renderSuggestion, renderCategory, renderTrendingItem, renderRecentItem, header, footer, width = '100%', maxHeight = '480px', zIndex = 1000, ariaLabel = 'Search suggestions', analyticsTags, onSuggestionSelect, onCategoryClick, onRecentSearchClick, onRecentSearchRemove, onViewAllClick, onOpen, onClose, } = props;
|
|
5455
5481
|
const { client } = useSearchContext();
|
|
5456
5482
|
const containerRef = useRef(null);
|
|
5457
5483
|
const [activeIndex, setActiveIndex] = useState(-1);
|
|
@@ -5465,6 +5491,8 @@ const RichQuerySuggestions = forwardRef(function RichQuerySuggestions(props, ref
|
|
|
5465
5491
|
maxSuggestions: maxSuggestionsPerSection,
|
|
5466
5492
|
minQueryLength,
|
|
5467
5493
|
includeDropdownRecommendations,
|
|
5494
|
+
includeDropdownProductList,
|
|
5495
|
+
includeFilteredTabs,
|
|
5468
5496
|
includeCategories,
|
|
5469
5497
|
maxCategories,
|
|
5470
5498
|
analyticsTags,
|
|
@@ -6969,15 +6997,17 @@ const inputStyles = {
|
|
|
6969
6997
|
color: 'var(--seekora-text-primary, #111827)',
|
|
6970
6998
|
fontFamily: 'inherit',
|
|
6971
6999
|
};
|
|
6972
|
-
function SearchInput({ placeholder = 'Search...', autoFocus = false, showClearButton = true, className, style, inputClassName, inputStyle, ariaLabel = 'Search', }) {
|
|
7000
|
+
function SearchInput({ placeholder = 'Search...', autoFocus = false, showClearButton = true, closeOnBlur = true, leftIcon, className, style, inputClassName, inputStyle, ariaLabel = 'Search', }) {
|
|
6973
7001
|
const { query, setQuery, isOpen, setIsOpen, navigateNext, navigatePrev, selectActive, close, } = useSuggestionsContext();
|
|
6974
7002
|
const inputRef = useRef(null);
|
|
6975
7003
|
const handleFocus = useCallback(() => {
|
|
6976
7004
|
setIsOpen(true);
|
|
6977
7005
|
}, [setIsOpen]);
|
|
6978
7006
|
const handleBlur = useCallback(() => {
|
|
7007
|
+
if (!closeOnBlur)
|
|
7008
|
+
return;
|
|
6979
7009
|
setTimeout(() => close(), 200);
|
|
6980
|
-
}, [close]);
|
|
7010
|
+
}, [close, closeOnBlur]);
|
|
6981
7011
|
const handleChange = useCallback((e) => {
|
|
6982
7012
|
setQuery(e.target.value);
|
|
6983
7013
|
}, [setQuery]);
|
|
@@ -7010,6 +7040,7 @@ function SearchInput({ placeholder = 'Search...', autoFocus = false, showClearBu
|
|
|
7010
7040
|
}, [setQuery]);
|
|
7011
7041
|
return (React.createElement("div", { className: clsx('seekora-suggestions-search-input-wrapper', className), style: { ...defaultStyles, ...style } },
|
|
7012
7042
|
React.createElement("div", { className: "seekora-suggestions-input-wrapper", style: inputWrapperStyles },
|
|
7043
|
+
leftIcon ? (React.createElement("span", { className: "seekora-suggestions-input-left-icon", style: { display: 'flex', flexShrink: 0, color: 'var(--seekora-text-secondary, #6b7280)' } }, leftIcon)) : null,
|
|
7013
7044
|
React.createElement("input", { ref: inputRef, type: "text", value: query, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, placeholder: placeholder, autoFocus: autoFocus, autoComplete: "off", autoCorrect: "off", autoCapitalize: "off", spellCheck: false, "aria-label": ariaLabel, "aria-expanded": isOpen, "aria-haspopup": "listbox", "aria-autocomplete": "list", role: "combobox", className: clsx('seekora-suggestions-input', inputClassName), style: { ...inputStyles, ...inputStyle } }),
|
|
7014
7045
|
showClearButton && query ? (React.createElement("button", { type: "button", onClick: handleClear, className: "seekora-suggestions-input-clear", "aria-label": "Clear search", style: {
|
|
7015
7046
|
padding: 4,
|
|
@@ -11765,7 +11796,7 @@ const createStyles = (isMobile) => ({
|
|
|
11765
11796
|
// Component
|
|
11766
11797
|
// ============================================================================
|
|
11767
11798
|
const SuggestionSearchBar = forwardRef(function SuggestionSearchBar(props, ref) {
|
|
11768
|
-
const { client, variant = 'amazon', autoMobileVariant = true, placeholder = 'Search...', defaultQuery = '', value, minQueryLength = 1, maxSuggestions = 8, debounceMs = 200, includeDropdownRecommendations = true, includeCategories = true, filteredTabs, analyticsTags, enableRecentSearches = true, maxRecentSearches = 10, showProducts = true, showTrendingOnEmpty = true, enableAnalytics = true, analyticsConfig, suggestionFields, productFields, theme, onSearch, onQueryChange, onSuggestionSelect, onProductClick, onCategoryClick, onTabChange, className, style, inputClassName, dropdownWidth, dropdownMaxHeight = '500px', zIndex = 1000, enableCache = true, cacheTtlMs = 30000, cacheMaxSize = 100, } = props;
|
|
11799
|
+
const { client, variant = 'amazon', autoMobileVariant = true, placeholder = 'Search...', defaultQuery = '', value, minQueryLength = 1, maxSuggestions = 8, debounceMs = 200, includeDropdownRecommendations = true, includeDropdownProductList = true, includeFilteredTabs = true, includeCategories = true, filteredTabs, analyticsTags, enableRecentSearches = true, maxRecentSearches = 10, showProducts = true, showTrendingOnEmpty = true, enableAnalytics = true, analyticsConfig, suggestionFields, productFields, theme, onSearch, onQueryChange, onSuggestionSelect, onProductClick, onCategoryClick, onTabChange, className, style, inputClassName, dropdownWidth, dropdownMaxHeight = '500px', zIndex = 1000, enableCache = true, cacheTtlMs = 30000, cacheMaxSize = 100, } = props;
|
|
11769
11800
|
// Theme: prop overrides context (SearchProvider theme)
|
|
11770
11801
|
const searchContext = useSearchContext();
|
|
11771
11802
|
const effectiveTheme = theme ?? searchContext.theme;
|
|
@@ -11848,6 +11879,8 @@ const SuggestionSearchBar = forwardRef(function SuggestionSearchBar(props, ref)
|
|
|
11848
11879
|
const cacheOptions = {
|
|
11849
11880
|
maxSuggestions,
|
|
11850
11881
|
includeDropdownRecommendations,
|
|
11882
|
+
includeDropdownProductList,
|
|
11883
|
+
includeFilteredTabs,
|
|
11851
11884
|
includeCategories,
|
|
11852
11885
|
filteredTabs: filteredTabs?.map(t => t.filter).join(','),
|
|
11853
11886
|
};
|
|
@@ -11868,6 +11901,8 @@ const SuggestionSearchBar = forwardRef(function SuggestionSearchBar(props, ref)
|
|
|
11868
11901
|
const response = await client.getSuggestions?.(searchQuery, {
|
|
11869
11902
|
hitsPerPage: maxSuggestions,
|
|
11870
11903
|
include_dropdown_recommendations: includeDropdownRecommendations,
|
|
11904
|
+
include_dropdown_product_list: includeDropdownProductList,
|
|
11905
|
+
include_filtered_tabs: includeFilteredTabs,
|
|
11871
11906
|
include_categories: includeCategories,
|
|
11872
11907
|
filtered_tabs: filteredTabs,
|
|
11873
11908
|
analytics_tags: analyticsTags,
|
|
@@ -11906,7 +11941,7 @@ const SuggestionSearchBar = forwardRef(function SuggestionSearchBar(props, ref)
|
|
|
11906
11941
|
finally {
|
|
11907
11942
|
setLoading(false);
|
|
11908
11943
|
}
|
|
11909
|
-
}, [client, minQueryLength, maxSuggestions, includeDropdownRecommendations, includeCategories, filteredTabs, analyticsTags, enableAnalytics, analytics, cache]);
|
|
11944
|
+
}, [client, minQueryLength, maxSuggestions, includeDropdownRecommendations, includeDropdownProductList, includeFilteredTabs, includeCategories, filteredTabs, analyticsTags, enableAnalytics, analytics, cache]);
|
|
11910
11945
|
// Parse API response - handles multiple response formats
|
|
11911
11946
|
const parseAndSetData = useCallback((response) => {
|
|
11912
11947
|
// Handle different response structures from the API/SDK
|