@jotul/jotul-widgets 0.0.2 → 0.0.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.
@@ -6,6 +6,43 @@ const VALID_WIDGET_TYPES = [
6
6
  'dealerFinder',
7
7
  'warrantyForm',
8
8
  ];
9
+ function PinIcon() {
10
+ return (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", className: "h-4 w-4 shrink-0", children: _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M2.70895 0.833313H5.20957C5.41781 0.833313 5.60425 0.962386 5.67756 1.15731L6.64785 3.73723C6.68 3.82263 6.68813 3.91519 6.6714 4.00488L6.1852 6.61285C6.7828 8.01818 7.76987 8.96258 9.40693 9.80971L11.9836 9.31045C12.0751 9.29271 12.1697 9.30091 12.2567 9.33411L14.8446 10.3202C15.0385 10.3941 15.1665 10.58 15.1665 10.7874V13.177C15.1665 14.2606 14.2117 15.14 13.0949 14.897C11.0592 14.454 7.28767 13.3282 4.64633 10.6868C2.11624 8.15678 1.26855 4.66166 0.983187 2.77244C0.820367 1.69446 1.6849 0.833313 2.70895 0.833313Z", fill: "currentColor" }) }));
11
+ }
12
+ function ArrowRightIcon() {
13
+ return (_jsx("svg", { width: "22", height: "22", viewBox: "0 0 22 22", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", className: "h-5 w-5 shrink-0", children: _jsx("path", { d: "M2.75 11L19.25 11M19.25 11L11.4583 3.20836M19.25 11L11.4583 18.7917", stroke: "currentColor", strokeWidth: "2.08333", strokeLinecap: "round", strokeLinejoin: "round" }) }));
14
+ }
15
+ function TelephoneIcon() {
16
+ return (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", className: "h-4 w-4 shrink-0", children: _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M2.70895 0.833313H5.20957C5.41781 0.833313 5.60425 0.962386 5.67756 1.15731L6.64785 3.73723C6.68 3.82263 6.68813 3.91519 6.6714 4.00488L6.1852 6.61285C6.7828 8.01818 7.76987 8.96258 9.40693 9.80971L11.9836 9.31045C12.0751 9.29271 12.1697 9.30091 12.2567 9.33411L14.8446 10.3202C15.0385 10.3941 15.1665 10.58 15.1665 10.7874V13.177C15.1665 14.2606 14.2117 15.14 13.0949 14.897C11.0592 14.454 7.28767 13.3282 4.64633 10.6868C2.11624 8.15678 1.26855 4.66166 0.983187 2.77244C0.820367 1.69446 1.6849 0.833313 2.70895 0.833313Z", fill: "currentColor" }) }));
17
+ }
18
+ function asText(value) {
19
+ return typeof value === 'string' && value.trim() ? value.trim() : null;
20
+ }
21
+ function asNumber(value) {
22
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
23
+ }
24
+ function formatDistance(dealer) {
25
+ const distanceKm = asNumber(dealer.distanceKm);
26
+ if (distanceKm !== null) {
27
+ return `${Math.round(distanceKm)} km`;
28
+ }
29
+ const postalDistance = asNumber(dealer.postalDistance);
30
+ if (postalDistance !== null) {
31
+ return `${Math.round(postalDistance)} km`;
32
+ }
33
+ return null;
34
+ }
35
+ function getDealerKey(dealer, index) {
36
+ return String(dealer.dealerId ?? dealer.name ?? index);
37
+ }
38
+ function getDealerName(dealer) {
39
+ return asText(dealer.name) ?? asText(dealer.dealerId) ?? 'Unknown dealer';
40
+ }
41
+ function getDealerAddressLines(dealer) {
42
+ const address = asText(dealer.address);
43
+ const postalCode = asText(dealer.postalCode);
44
+ return [address, postalCode].filter((value) => Boolean(value));
45
+ }
9
46
  export async function checkWidgetAuthorization(options) {
10
47
  const endpoint = options?.endpoint ?? '/api/jotul/widget';
11
48
  const fetcher = options?.fetcher ?? fetch;
@@ -119,13 +156,23 @@ export function JotulWidget({ type, endpoint = '/api/jotul/widget', className, }
119
156
  return _jsx("div", { className: className, children: "Invalid widget type" });
120
157
  }
121
158
  if (type === 'productPage') {
122
- const dealers = searchResult?.dealers ?? [];
123
- return (_jsx("div", { className: className, children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("input", { type: "text", value: postalCode, onChange: (event) => setPostalCode(event.target.value), placeholder: "Zipcode" }), _jsx("button", { type: "button", disabled: isSearching || postalCode.trim().length === 0, onClick: async () => {
124
- setIsSearching(true);
125
- const result = await searchDealersByPostalCode(postalCode, { endpoint });
126
- setSearchResult(result);
127
- setIsSearching(false);
128
- }, children: isSearching ? 'Searching…' : 'Search' }), searchResult?.ok === false && (_jsx("div", { children: searchResult.error ?? 'Unknown widget error' })), searchResult?.ok && (_jsx("ul", { children: dealers.map((dealer, index) => (_jsx("li", { children: String(dealer.name ?? dealer.dealerId ?? 'Unknown dealer') }, String(dealer.dealerId ?? dealer.name ?? index)))) }))] }) }));
159
+ const dealers = (searchResult?.dealers ?? []);
160
+ const canSearch = postalCode.trim().length > 0;
161
+ const total = searchResult?.total ?? dealers.length;
162
+ return (_jsx("div", { className: className, children: _jsxs("div", { className: "w-full rounded-[32px] border border-[#e9e5dc] bg-[#f8f6f2] p-4 text-[#111111] shadow-[0_6px_20px_rgba(17,17,17,0.04)] md:p-6", children: [_jsx("div", { className: "overflow-hidden rounded-[24px] border border-[#d8d2c7] bg-white", children: _jsxs("div", { className: "flex flex-col md:flex-row", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3 px-5 py-4 md:px-6", children: [_jsx("span", { className: "text-black", children: _jsx(PinIcon, {}) }), _jsx("input", { type: "text", inputMode: "numeric", autoComplete: "postal-code", pattern: "[0-9]*", maxLength: 10, value: postalCode, onChange: (event) => {
163
+ const next = event.target.value.replace(/\D+/g, '');
164
+ setPostalCode(next);
165
+ }, placeholder: "Enter postcode", className: "w-full border-0 bg-transparent text-base text-[#111111] outline-none placeholder:text-[#767676]" })] }), _jsx("button", { type: "button", disabled: isSearching || !canSearch, onClick: async () => {
166
+ setIsSearching(true);
167
+ const result = await searchDealersByPostalCode(postalCode, { endpoint });
168
+ setSearchResult(result);
169
+ setIsSearching(false);
170
+ }, className: "min-h-[64px] bg-black px-8 text-base font-medium text-white transition hover:bg-[#1f1f1f] disabled:cursor-not-allowed disabled:bg-[#444444]", children: isSearching ? 'Finding...' : 'Find' })] }) }), searchResult?.ok === false && (_jsx("div", { className: "mt-4 rounded-2xl border border-[#f0c7c2] bg-[#fff3f1] px-4 py-3 text-sm text-[#8f2d21]", children: searchResult.error ?? 'Unknown widget error' })), searchResult?.ok && (_jsxs("div", { className: "mt-5", children: [_jsxs("div", { className: "border-b border-[#e6e1d7] pb-4 text-base font-medium text-[#111111]", children: [total, " dealers near you"] }), _jsx("div", { className: "mt-5 max-h-[700px] space-y-4 overflow-y-auto pr-1", children: dealers.map((dealer, index) => {
171
+ const addressLines = getDealerAddressLines(dealer);
172
+ const phone = asText(dealer.phone);
173
+ const distance = formatDistance(dealer);
174
+ return (_jsxs("div", { className: "rounded-[24px] border border-[#e6e1d7] bg-white p-5 shadow-[0_1px_2px_rgba(17,17,17,0.03)]", children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsx("div", { className: "max-w-[70%]", children: _jsx("h3", { className: "text-[22px] font-semibold leading-[1.15] text-[#111111]", children: getDealerName(dealer) }) }), distance && (_jsx("div", { className: "rounded-full bg-[#fbf3db] px-4 py-2 text-xl font-medium leading-none text-[#111111]", children: distance }))] }), addressLines.length > 0 && (_jsx("div", { className: "mt-5 space-y-1 text-[18px] leading-[1.15] text-[#111111]", children: addressLines.map((line) => (_jsx("div", { children: line }, line))) })), _jsxs("div", { className: "mt-6 flex flex-col gap-4 md:flex-row md:items-center md:justify-between", children: [_jsxs("button", { type: "button", className: "inline-flex min-h-[70px] w-full items-center justify-between rounded-[16px] bg-[#ef2b18] px-7 text-[18px] font-medium text-white transition hover:bg-[#d92817] md:w-[390px]", children: [_jsx("span", { children: "Send foresporsel" }), _jsx(ArrowRightIcon, {})] }), phone && (_jsxs("a", { href: `tel:${phone.replace(/\s+/g, '')}`, className: "inline-flex items-center gap-3 text-[18px] font-medium text-[#111111] hover:underline", children: [_jsx(TelephoneIcon, {}), _jsx("span", { children: phone })] }))] })] }, getDealerKey(dealer, index)));
175
+ }) })] }))] }) }));
129
176
  }
130
177
  return _jsx("div", { className: className, children: renderReadyState(type) });
131
178
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jotul/jotul-widgets",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "sideEffects": false,