@jotul/jotul-widgets 1.2.0 → 1.2.1
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/JotulWidget.d.ts +2 -2
- package/dist/JotulWidget.js +6 -5
- package/dist/api.js +3 -0
- package/dist/components/FindDealerDrawerWidget.d.ts +3 -2
- package/dist/components/FindDealerDrawerWidget.js +8 -13
- package/dist/components/ProductPageWidget.d.ts +3 -2
- package/dist/components/ProductPageWidget.js +8 -13
- package/dist/components/product-page/DealerList.js +5 -7
- package/dist/types.d.ts +3 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +12 -0
- package/package.json +1 -1
package/dist/JotulWidget.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ import type { JotulWidgetProps } from './types';
|
|
|
4
4
|
export { DEFAULT_WIDGET_LOCALE_TAG, normalizeWidgetLocale, resolveWidgetUiLocale, } from './i18n/widgetStrings';
|
|
5
5
|
export type { JotulWidgetLocale } from './i18n/widgetStrings';
|
|
6
6
|
export { checkWidgetAuthorization, searchLocationSuggestions, searchDealersByCoordinates, searchDealersByPostalCode, };
|
|
7
|
-
export type { CheckWidgetAuthorizationOptions, DealerSearchResponse, JotulWidgetBorderStyling, JotulWidgetButtonStyling, JotulWidgetProps, WidgetTriggerRenderProps, JotulWidgetStyling, JotulWidgetType, WidgetAuthClientResponse, } from './types';
|
|
8
|
-
export declare function JotulWidget({ type, endpoint, className, productName, locale: localeProp, market: marketProp, brands, campaignSlug, styling, trigger, productPageTrigger, findDealerDrawerTrigger, }: JotulWidgetProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export type { CheckWidgetAuthorizationOptions, DealerSearchResponse, JotulWidgetBorderStyling, JotulWidgetButtonStyling, JotulWidgetProps, JotulWidgetScope, WidgetTriggerRenderProps, JotulWidgetStyling, JotulWidgetType, WidgetAuthClientResponse, } from './types';
|
|
8
|
+
export declare function JotulWidget({ type, endpoint, className, productName, locale: localeProp, market: marketProp, scope, brands, campaignSlug, styling, trigger, productPageTrigger, findDealerDrawerTrigger, }: JotulWidgetProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/JotulWidget.js
CHANGED
|
@@ -28,7 +28,7 @@ const MARKET_FALLBACK_CENTER = {
|
|
|
28
28
|
FI: [60.1699, 24.9384],
|
|
29
29
|
DE: [52.52, 13.405],
|
|
30
30
|
};
|
|
31
|
-
export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, productName, locale: localeProp, market: marketProp, brands, campaignSlug, styling, trigger, productPageTrigger, findDealerDrawerTrigger, }) {
|
|
31
|
+
export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, productName, locale: localeProp, market: marketProp, scope, brands, campaignSlug, styling, trigger, productPageTrigger, findDealerDrawerTrigger, }) {
|
|
32
32
|
const resolvedUiLocale = useMemo(() => resolveWidgetUiLocale(localeProp, marketProp), [localeProp, marketProp]);
|
|
33
33
|
const t = WIDGET_STRINGS[resolvedUiLocale];
|
|
34
34
|
const apiLocaleTag = useMemo(() => (localeProp?.trim() ? localeProp.trim() : DEFAULT_WIDGET_LOCALE_TAG), [localeProp]);
|
|
@@ -65,9 +65,10 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
|
|
|
65
65
|
endpoint,
|
|
66
66
|
locale: apiLocaleTag,
|
|
67
67
|
market: apiMarket,
|
|
68
|
+
scope,
|
|
68
69
|
brands,
|
|
69
70
|
campaignSlug: productPageCampaignSlug,
|
|
70
|
-
}), [apiLocaleTag, apiMarket, brands, endpoint, productPageCampaignSlug]);
|
|
71
|
+
}), [apiLocaleTag, apiMarket, brands, endpoint, productPageCampaignSlug, scope]);
|
|
71
72
|
const runDealerSearchByCoordinates = useCallback(async (latitude, longitude) => {
|
|
72
73
|
setLocationError(null);
|
|
73
74
|
setIsSearching(true);
|
|
@@ -80,7 +81,7 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
|
|
|
80
81
|
finally {
|
|
81
82
|
setIsSearching(false);
|
|
82
83
|
}
|
|
83
|
-
}, [dealerSearchOptions]);
|
|
84
|
+
}, [dealerSearchOptions, scope]);
|
|
84
85
|
const runFallbackDealerSearch = useCallback(() => {
|
|
85
86
|
const fallbackCenter = (apiMarket != null ? MARKET_FALLBACK_CENTER[apiMarket] : undefined) ??
|
|
86
87
|
MARKET_FALLBACK_CENTER.NO;
|
|
@@ -269,7 +270,7 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
|
|
|
269
270
|
return _jsx("div", { className: rootClass, children: getSafeWidgetErrorMessage(auth?.error, t) });
|
|
270
271
|
}
|
|
271
272
|
if (widgetType === 'productPage') {
|
|
272
|
-
return (_jsx("div", { className: rootClass, children: _jsx(ProductPageWidget, { t: t, buttonStyling: styling?.button, borderStyling: styling?.border, market: apiMarket, isSearching: isSearching, locationError: locationError, searchResult: searchResult?.ok === false
|
|
273
|
+
return (_jsx("div", { className: rootClass, children: _jsx(ProductPageWidget, { t: t, buttonStyling: styling?.button, borderStyling: styling?.border, market: apiMarket, scope: scope, isSearching: isSearching, locationError: locationError, searchResult: searchResult?.ok === false
|
|
273
274
|
? { ...searchResult, error: getSafeWidgetErrorMessage(searchResult.error, t) }
|
|
274
275
|
: searchResult, mapSearchResult: mapSearchResult?.ok === false
|
|
275
276
|
? { ...mapSearchResult, error: getSafeWidgetErrorMessage(mapSearchResult.error, t) }
|
|
@@ -349,7 +350,7 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, p
|
|
|
349
350
|
transform: isOpen ? 'translateX(0)' : 'translateX(100%)',
|
|
350
351
|
transition: 'transform 300ms ease-out',
|
|
351
352
|
willChange: 'transform',
|
|
352
|
-
}, "aria-hidden": !isOpen, children: drawerLoading ? (_jsxs("div", { className: "jwi-flex jwi-h-full jwi-w-full jwi-bg-white", children: [_jsx("div", { className: "jwi-flex jwi-h-full jwi-min-h-0 jwi-w-1/2 jwi-flex-col jwi-overflow-hidden", children: _jsxs("div", { className: "jwi-flex jwi-h-full jwi-min-h-0 jwi-w-full jwi-flex-col jwi-gap-3 jwi-overflow-hidden jwi-bg-white jwi-p-6", children: [_jsx("div", { className: "jwi-h-12 jwi-w-full jwi-animate-pulse jwi-rounded-[10px] jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-5 jwi-w-48 jwi-animate-pulse jwi-rounded-full jwi-bg-[#ece8df]" }), _jsxs("div", { className: "jwi-flex jwi-flex-col jwi-gap-4", children: [_jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {})] })] }) }), _jsx("div", { className: "jwi-h-full jwi-w-1/2 jwi-bg-[#e8eef1]" })] })) : (_jsx(FindDealerDrawerWidget, { t: t, buttonStyling: styling?.button, borderStyling: styling?.border, market: apiMarket, isSearching: isSearching, locationError: locationError, searchResult: searchResult?.ok === false
|
|
353
|
+
}, "aria-hidden": !isOpen, children: drawerLoading ? (_jsxs("div", { className: "jwi-flex jwi-h-full jwi-w-full jwi-bg-white", children: [_jsx("div", { className: "jwi-flex jwi-h-full jwi-min-h-0 jwi-w-1/2 jwi-flex-col jwi-overflow-hidden", children: _jsxs("div", { className: "jwi-flex jwi-h-full jwi-min-h-0 jwi-w-full jwi-flex-col jwi-gap-3 jwi-overflow-hidden jwi-bg-white jwi-p-6", children: [_jsx("div", { className: "jwi-h-12 jwi-w-full jwi-animate-pulse jwi-rounded-[10px] jwi-bg-[#ece8df]" }), _jsx("div", { className: "jwi-h-5 jwi-w-48 jwi-animate-pulse jwi-rounded-full jwi-bg-[#ece8df]" }), _jsxs("div", { className: "jwi-flex jwi-flex-col jwi-gap-4", children: [_jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {}), _jsx(DealerCardSkeleton, {})] })] }) }), _jsx("div", { className: "jwi-h-full jwi-w-1/2 jwi-bg-[#e8eef1]" })] })) : (_jsx(FindDealerDrawerWidget, { t: t, buttonStyling: styling?.button, borderStyling: styling?.border, market: apiMarket, scope: scope, isSearching: isSearching, locationError: locationError, searchResult: searchResult?.ok === false
|
|
353
354
|
? { ...searchResult, error: getSafeWidgetErrorMessage(searchResult.error, t) }
|
|
354
355
|
: searchResult, mapSearchResult: mapSearchResult?.ok === false
|
|
355
356
|
? { ...mapSearchResult, error: getSafeWidgetErrorMessage(mapSearchResult.error, t) }
|
package/dist/api.js
CHANGED
|
@@ -13,6 +13,9 @@ function appendLocaleAndMarket(params, options) {
|
|
|
13
13
|
params.set('market', upper);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
+
if (options?.scope === 'ildstedet') {
|
|
17
|
+
params.set('dealerScope', options.scope);
|
|
18
|
+
}
|
|
16
19
|
}
|
|
17
20
|
export async function checkWidgetAuthorization(options) {
|
|
18
21
|
const endpoint = options?.endpoint ?? '/api/jotul/widget';
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import 'leaflet/dist/leaflet.css';
|
|
2
2
|
import 'leaflet.markercluster/dist/MarkerCluster.css';
|
|
3
3
|
import type { WidgetStrings } from '../i18n/widgetStrings';
|
|
4
|
-
import type { DealerSearchResponse, InquiryFormValues, JotulWidgetBorderStyling, JotulWidgetButtonStyling, LocationSuggestion } from '../types';
|
|
4
|
+
import type { DealerSearchResponse, InquiryFormValues, JotulWidgetBorderStyling, JotulWidgetButtonStyling, JotulWidgetScope, LocationSuggestion } from '../types';
|
|
5
5
|
type FindDealerDrawerWidgetProps = {
|
|
6
6
|
t: WidgetStrings;
|
|
7
7
|
buttonStyling?: JotulWidgetButtonStyling;
|
|
8
8
|
borderStyling?: JotulWidgetBorderStyling;
|
|
9
9
|
market?: string;
|
|
10
|
+
scope?: JotulWidgetScope;
|
|
10
11
|
isSearching: boolean;
|
|
11
12
|
locationError: string | null;
|
|
12
13
|
searchResult: DealerSearchResponse | null;
|
|
@@ -35,5 +36,5 @@ type FindDealerDrawerWidgetProps = {
|
|
|
35
36
|
}) => void;
|
|
36
37
|
onClose: () => void;
|
|
37
38
|
};
|
|
38
|
-
export declare function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, market, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClose, }: FindDealerDrawerWidgetProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
export declare function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, market, scope, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClose, }: FindDealerDrawerWidgetProps): import("react/jsx-runtime").JSX.Element;
|
|
39
40
|
export {};
|
|
@@ -17,7 +17,9 @@ import { MARKER_CLUSTER_LINK_KM, MARKER_CLUSTER_MIN_GROUP, partitionDealersForMa
|
|
|
17
17
|
import { loadLeafletMarkerCluster } from '../utils/loadLeafletMarkerCluster';
|
|
18
18
|
import { markerClusterCountIconHtml } from '../utils/markerClusterIconHtml';
|
|
19
19
|
import { JOTUL_BRAND_PRIMARY_HEX } from '../constants';
|
|
20
|
+
import { isExclusiveDealer } from '../utils';
|
|
20
21
|
const OSM_MINIMAL_TILE_URL = 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png';
|
|
22
|
+
const EMPTY_DEALERS = [];
|
|
21
23
|
function mapPointsBoundsKey(points, defaultCenter) {
|
|
22
24
|
const body = points.length === 0
|
|
23
25
|
? ''
|
|
@@ -49,16 +51,7 @@ function getDealerMapPoint(dealer) {
|
|
|
49
51
|
const longitude = readNumber(dealer.longitude);
|
|
50
52
|
if (latitude == null || longitude == null)
|
|
51
53
|
return null;
|
|
52
|
-
const
|
|
53
|
-
const isExclusive = rawExclusive === true ||
|
|
54
|
-
rawExclusive === 1 ||
|
|
55
|
-
rawExclusive === '1' ||
|
|
56
|
-
rawExclusive === 'true' ||
|
|
57
|
-
rawExclusive === 'TRUE' ||
|
|
58
|
-
rawExclusive === 'yes' ||
|
|
59
|
-
rawExclusive === 'YES' ||
|
|
60
|
-
rawExclusive === 'y' ||
|
|
61
|
-
rawExclusive === 'Y';
|
|
54
|
+
const isExclusive = isExclusiveDealer(dealer);
|
|
62
55
|
return { dealerName: getDealerName(dealer), latitude, longitude, isExclusive };
|
|
63
56
|
}
|
|
64
57
|
function toAssetSrc(value) {
|
|
@@ -229,9 +222,11 @@ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, cluster
|
|
|
229
222
|
}, [map, pointsBoundsKey, clusterThemeKey]);
|
|
230
223
|
return null;
|
|
231
224
|
}
|
|
232
|
-
export function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, market, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClose, }) {
|
|
233
|
-
const
|
|
234
|
-
const
|
|
225
|
+
export function FindDealerDrawerWidget({ t, buttonStyling, borderStyling, market, scope, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClose, }) {
|
|
226
|
+
const rawDealers = (searchResult?.dealers ?? EMPTY_DEALERS);
|
|
227
|
+
const dealers = useMemo(() => (scope === 'ildstedet' ? rawDealers.filter(isExclusiveDealer) : rawDealers), [rawDealers, scope]);
|
|
228
|
+
const rawMapDealers = (mapSearchResult?.dealers ?? rawDealers);
|
|
229
|
+
const mapDealers = useMemo(() => (scope === 'ildstedet' ? rawMapDealers.filter(isExclusiveDealer) : rawMapDealers), [rawMapDealers, scope]);
|
|
235
230
|
const total = dealers.length;
|
|
236
231
|
const inquiryFormOpen = inquiryValues != null;
|
|
237
232
|
const [activeDealerName, setActiveDealerName] = useState(null);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import 'leaflet/dist/leaflet.css';
|
|
2
2
|
import 'leaflet.markercluster/dist/MarkerCluster.css';
|
|
3
3
|
import type { WidgetStrings } from '../i18n/widgetStrings';
|
|
4
|
-
import type { DealerSearchResponse, InquiryFormValues, JotulWidgetBorderStyling, JotulWidgetButtonStyling, LocationSuggestion } from '../types';
|
|
4
|
+
import type { DealerSearchResponse, InquiryFormValues, JotulWidgetBorderStyling, JotulWidgetButtonStyling, JotulWidgetScope, LocationSuggestion } from '../types';
|
|
5
5
|
type ProductPageWidgetProps = {
|
|
6
6
|
t: WidgetStrings;
|
|
7
7
|
buttonStyling?: JotulWidgetButtonStyling;
|
|
8
8
|
borderStyling?: JotulWidgetBorderStyling;
|
|
9
9
|
market?: string;
|
|
10
|
+
scope?: JotulWidgetScope;
|
|
10
11
|
isSearching: boolean;
|
|
11
12
|
locationError: string | null;
|
|
12
13
|
searchResult: DealerSearchResponse | null;
|
|
@@ -35,5 +36,5 @@ type ProductPageWidgetProps = {
|
|
|
35
36
|
}) => void;
|
|
36
37
|
onClosePopup?: () => void;
|
|
37
38
|
};
|
|
38
|
-
export declare function ProductPageWidget({ t, buttonStyling, borderStyling, market, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClosePopup, }: ProductPageWidgetProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
export declare function ProductPageWidget({ t, buttonStyling, borderStyling, market, scope, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClosePopup, }: ProductPageWidgetProps): import("react/jsx-runtime").JSX.Element;
|
|
39
40
|
export {};
|
|
@@ -18,7 +18,9 @@ import { MARKER_CLUSTER_LINK_KM, MARKER_CLUSTER_MIN_GROUP, partitionDealersForMa
|
|
|
18
18
|
import { loadLeafletMarkerCluster } from '../utils/loadLeafletMarkerCluster';
|
|
19
19
|
import { markerClusterCountIconHtml } from '../utils/markerClusterIconHtml';
|
|
20
20
|
import { JOTUL_BRAND_PRIMARY_HEX, R10 } from '../constants';
|
|
21
|
+
import { isExclusiveDealer } from '../utils';
|
|
21
22
|
const OSM_MINIMAL_TILE_URL = 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png';
|
|
23
|
+
const EMPTY_DEALERS = [];
|
|
22
24
|
function mapPointsBoundsKey(points, defaultCenter) {
|
|
23
25
|
const body = points.length === 0
|
|
24
26
|
? ''
|
|
@@ -52,16 +54,7 @@ function getDealerMapPoint(dealer) {
|
|
|
52
54
|
const longitude = readNumber(dealer.longitude);
|
|
53
55
|
if (latitude == null || longitude == null)
|
|
54
56
|
return null;
|
|
55
|
-
const
|
|
56
|
-
const isExclusive = rawExclusive === true ||
|
|
57
|
-
rawExclusive === 1 ||
|
|
58
|
-
rawExclusive === '1' ||
|
|
59
|
-
rawExclusive === 'true' ||
|
|
60
|
-
rawExclusive === 'TRUE' ||
|
|
61
|
-
rawExclusive === 'yes' ||
|
|
62
|
-
rawExclusive === 'YES' ||
|
|
63
|
-
rawExclusive === 'y' ||
|
|
64
|
-
rawExclusive === 'Y';
|
|
57
|
+
const isExclusive = isExclusiveDealer(dealer);
|
|
65
58
|
return {
|
|
66
59
|
dealer,
|
|
67
60
|
dealerName: getDealerName(dealer),
|
|
@@ -236,9 +229,11 @@ function ClusteredMapMarkers({ points, pointsBoundsKey, clusterThemeKey, cluster
|
|
|
236
229
|
}, [map, pointsBoundsKey, clusterThemeKey]);
|
|
237
230
|
return null;
|
|
238
231
|
}
|
|
239
|
-
export function ProductPageWidget({ t, buttonStyling, borderStyling, market, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClosePopup, }) {
|
|
240
|
-
const
|
|
241
|
-
const
|
|
232
|
+
export function ProductPageWidget({ t, buttonStyling, borderStyling, market, scope, isSearching, locationError, searchResult, mapSearchResult, inquiryValues, inquiryError, isInquirySubmitted, selectedDealerName, isManualSearchEnabled, query, suggestions, suggestionsOpen, isSuggestionsLoading, onQueryChange, onQuerySubmit, onSuggestionSelect, onDismissSuggestions, onInquiryClose, onInquirySubmit, onInquiryFieldChange, onStartInquiry, onMapDealerSelect, onClosePopup, }) {
|
|
233
|
+
const rawDealers = (searchResult?.dealers ?? EMPTY_DEALERS);
|
|
234
|
+
const dealers = useMemo(() => (scope === 'ildstedet' ? rawDealers.filter(isExclusiveDealer) : rawDealers), [rawDealers, scope]);
|
|
235
|
+
const rawMapDealers = (mapSearchResult?.dealers ?? rawDealers);
|
|
236
|
+
const mapDealers = useMemo(() => (scope === 'ildstedet' ? rawMapDealers.filter(isExclusiveDealer) : rawMapDealers), [rawMapDealers, scope]);
|
|
242
237
|
const total = dealers.length;
|
|
243
238
|
const inquiryFormOpen = inquiryValues != null;
|
|
244
239
|
const [activeDealerName, setActiveDealerName] = useState(null);
|
|
@@ -6,7 +6,7 @@ import { TelephoneIcon } from '../../icons/TelephoneIcon';
|
|
|
6
6
|
import { getWidgetPrimaryButtonPresentation } from '../../utils/widgetPrimaryButtonPresentation';
|
|
7
7
|
import exclusiveDealerBadge from '../../images/jotul-exclusive-dealer.png';
|
|
8
8
|
import ildstedetDealer from '../../images/ildstedet-dealer.svg';
|
|
9
|
-
import { asText, formatDistance, getDealerAddressLines, getDealerKey, getDealerName, } from '../../utils';
|
|
9
|
+
import { asText, formatDistance, getDealerAddressLines, getDealerKey, getDealerName, isExclusiveDealer, } from '../../utils';
|
|
10
10
|
export function DealerList({ dealers, total, selectedDealerName, activeDealerName = null, maxHeightClassName = 'jwi-max-h-[min(60vh,480px)]', fitAvailableHeight = false, autoScrollToActive = false, enableInternalScroll = true, headerRight, t, buttonStyling, borderStyling, market, onStartInquiry, onSelectDealer, }) {
|
|
11
11
|
const cardRefs = useRef({});
|
|
12
12
|
useEffect(() => {
|
|
@@ -17,7 +17,7 @@ export function DealerList({ dealers, total, selectedDealerName, activeDealerNam
|
|
|
17
17
|
return;
|
|
18
18
|
card.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
19
19
|
}, [activeDealerName, autoScrollToActive]);
|
|
20
|
-
const
|
|
20
|
+
const activeBorderColor = borderStyling?.borderColor?.trim();
|
|
21
21
|
const inquiryCta = getWidgetPrimaryButtonPresentation(buttonStyling, 'panel', {
|
|
22
22
|
extraClassName: 'jwi-w-full jwi-max-w-full jwi-shrink-0 jwi-justify-between jwi-gap-2 md:jwi-max-w-[220px]',
|
|
23
23
|
});
|
|
@@ -30,13 +30,11 @@ export function DealerList({ dealers, total, selectedDealerName, activeDealerNam
|
|
|
30
30
|
const dealerName = getDealerName(dealer, t.unknownDealer);
|
|
31
31
|
const isSelectedDealer = selectedDealerName === dealerName;
|
|
32
32
|
const isActiveDealer = activeDealerName === dealerName;
|
|
33
|
-
const isExclusive = dealer
|
|
34
|
-
dealer.exclusive === 1 ||
|
|
35
|
-
dealer.exclusive === '1';
|
|
33
|
+
const isExclusive = isExclusiveDealer(dealer);
|
|
36
34
|
return (_jsxs("div", { ref: (element) => {
|
|
37
35
|
cardRefs.current[dealerName] = element;
|
|
38
|
-
}, className: `jwi-w-full jwi-cursor-pointer ${R10} jwi-border jwi-bg-white jwi-p-4 jwi-shadow-[0_1px_2px_rgba(17,17,17,0.03)] ${isActiveDealer ? 'jwi-border-[#ef2b18]' : ''}`, style:
|
|
39
|
-
? { borderColor:
|
|
36
|
+
}, className: `jwi-w-full jwi-cursor-pointer ${R10} jwi-border jwi-bg-white jwi-p-4 jwi-shadow-[0_1px_2px_rgba(17,17,17,0.03)] ${isActiveDealer ? 'jwi-border-[#ef2b18]' : ''}`, style: isActiveDealer && activeBorderColor
|
|
37
|
+
? { borderColor: activeBorderColor }
|
|
40
38
|
: undefined, onClick: () => onSelectDealer?.(dealerName), children: [_jsxs("div", { className: "jwi-flex jwi-items-start jwi-justify-between jwi-gap-3", children: [_jsx("div", { className: "jwi-min-w-0 jwi-max-w-[calc(100%-5rem)] jwi-pr-1", children: _jsxs("div", { className: "jwi-flex jwi-items-center jwi-gap-2", children: [isExclusive && (() => {
|
|
41
39
|
const badgeImage = market === 'NO' ? ildstedetDealer : exclusiveDealerBadge;
|
|
42
40
|
const badgeAlt = market === 'NO' ? 'Ildstedet dealer' : 'Jotul exclusive dealer';
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
export type JotulWidgetType = 'productPage' | 'findDealerDrawer' | 'dealerFinder' | 'warrantyForm';
|
|
3
|
+
export type JotulWidgetScope = 'ildstedet';
|
|
3
4
|
export type WidgetAuthClientResponse = {
|
|
4
5
|
apiVersion?: string;
|
|
5
6
|
ok: boolean;
|
|
@@ -49,6 +50,7 @@ export type CheckWidgetAuthorizationOptions = {
|
|
|
49
50
|
locale?: string;
|
|
50
51
|
/** ISO 3166-1 alpha-2 market/country (e.g. `NO`, `SE`) sent to the API as `market`. */
|
|
51
52
|
market?: string;
|
|
53
|
+
scope?: JotulWidgetScope;
|
|
52
54
|
brands?: string[];
|
|
53
55
|
/** Optional Sanity campaign slug used to limit dealer results to campaign dealers. */
|
|
54
56
|
campaignSlug?: string;
|
|
@@ -82,6 +84,7 @@ export type JotulWidgetProps = {
|
|
|
82
84
|
locale?: string;
|
|
83
85
|
/** ISO 3166-1 alpha-2 market filter for dealers and geocoder country bias (`NO`, `SE`, …). */
|
|
84
86
|
market?: string;
|
|
87
|
+
scope?: JotulWidgetScope;
|
|
85
88
|
brands?: string[];
|
|
86
89
|
/** Optional Sanity campaign slug used to limit dealer results to campaign dealers. */
|
|
87
90
|
campaignSlug?: string;
|
package/dist/utils.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export declare const VALID_WIDGET_TYPES: JotulWidgetType[];
|
|
|
4
4
|
export declare function isWidgetType(value: string | undefined): value is JotulWidgetType;
|
|
5
5
|
export declare function asText(value: unknown): string | null;
|
|
6
6
|
export declare function formatDistance(dealer: DealerRecord): string | null;
|
|
7
|
+
export declare function isExclusiveDealer(dealer: DealerRecord): boolean;
|
|
7
8
|
export declare function getDealerKey(dealer: DealerRecord, index: number): string;
|
|
8
9
|
export declare function getDealerName(dealer: DealerRecord, unknownLabel: string): string;
|
|
9
10
|
/** True when the tapped map pin matches a dealer already in the current successful search payload. */
|
package/dist/utils.js
CHANGED
|
@@ -24,6 +24,18 @@ export function formatDistance(dealer) {
|
|
|
24
24
|
}
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
|
+
export function isExclusiveDealer(dealer) {
|
|
28
|
+
const rawExclusive = dealer.exclusive;
|
|
29
|
+
return (rawExclusive === true ||
|
|
30
|
+
rawExclusive === 1 ||
|
|
31
|
+
rawExclusive === '1' ||
|
|
32
|
+
rawExclusive === 'true' ||
|
|
33
|
+
rawExclusive === 'TRUE' ||
|
|
34
|
+
rawExclusive === 'yes' ||
|
|
35
|
+
rawExclusive === 'YES' ||
|
|
36
|
+
rawExclusive === 'y' ||
|
|
37
|
+
rawExclusive === 'Y');
|
|
38
|
+
}
|
|
27
39
|
export function getDealerKey(dealer, index) {
|
|
28
40
|
return String(dealer.dealerId ?? dealer.name ?? index);
|
|
29
41
|
}
|