@shop-prompter/react 1.0.0 → 1.1.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # shop-prompter-react
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8fe8877: Configurable card content
8
+
3
9
  ## 1.0.0
4
10
 
5
11
  ### Major Changes
package/dist/index.js CHANGED
@@ -800,6 +800,14 @@ var styles = {
800
800
  overflow: "hidden",
801
801
  textOverflow: "ellipsis"
802
802
  },
803
+ productDynamicField: {
804
+ fontSize: "0.6875rem",
805
+ color: "#6b7280",
806
+ margin: 0,
807
+ whiteSpace: "nowrap",
808
+ overflow: "hidden",
809
+ textOverflow: "ellipsis"
810
+ },
803
811
  productPrice: {
804
812
  fontSize: "0.8125rem",
805
813
  fontWeight: 500,
@@ -864,11 +872,43 @@ function ProductCardList(props) {
864
872
  const localized = ((_a = product.localization) == null ? void 0 : _a[locale]) || Object.values(product.localization || {})[0];
865
873
  return (localized == null ? void 0 : localized.name) || product.sku;
866
874
  }
875
+ function showPriceIfEmptyVal() {
876
+ const val = props.showPriceIfEmpty;
877
+ if (typeof val === "string") {
878
+ return val === "true";
879
+ }
880
+ return val != null ? val : false;
881
+ }
882
+ function visibleFieldsList() {
883
+ const val = props.visibleFields;
884
+ if (typeof val === "string") {
885
+ try {
886
+ return JSON.parse(val);
887
+ } catch (e) {
888
+ return val.split(",").map((s) => s.trim()).filter(Boolean);
889
+ }
890
+ }
891
+ return val || [];
892
+ }
893
+ function getDynamicField(product, field) {
894
+ var _a;
895
+ const locale = props.defaultLocale || "de";
896
+ const localized = ((_a = product.localization) == null ? void 0 : _a[locale]) || Object.values(product.localization || {})[0];
897
+ if (!localized) return void 0;
898
+ const parts = field.split(".");
899
+ let current = localized;
900
+ for (let i = 0; i < parts.length; i++) {
901
+ if (current === void 0 || current === null) return void 0;
902
+ current = current[parts[i]];
903
+ }
904
+ return current;
905
+ }
867
906
  function getProductPrice(product) {
868
907
  if (!product.pricing) return "";
869
908
  const priceVal = product.pricing.gross;
870
909
  const currency = product.pricing.currency;
871
910
  if (priceVal === void 0 || priceVal === null) return "";
911
+ if (priceVal === 0 && !showPriceIfEmptyVal()) return "";
872
912
  return priceVal.toFixed(2) + " " + (currency || "\u20AC");
873
913
  }
874
914
  function getProductImage(product) {
@@ -889,27 +929,40 @@ function ProductCardList(props) {
889
929
  "Error: ",
890
930
  error
891
931
  ] }) }) : null,
892
- !loading && products && products.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles.productCardsContainer, children: products == null ? void 0 : products.map((product) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles.productCard, children: [
893
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles.productImageContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
894
- "img",
895
- {
896
- src: getProductImage(product),
897
- alt: getProductName(product),
898
- style: styles.productImage
899
- }
900
- ) }),
901
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles.productInfo, children: [
902
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
903
- "p",
932
+ !loading && products && products.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles.productCardsContainer, children: products == null ? void 0 : products.map((product) => {
933
+ var _a;
934
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles.productCard, children: [
935
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles.productImageContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
936
+ "img",
904
937
  {
905
- style: styles.productName,
906
- title: getProductName(product),
907
- children: getProductName(product)
938
+ src: getProductImage(product),
939
+ alt: getProductName(product),
940
+ style: styles.productImage
908
941
  }
909
- ),
910
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: styles.productPrice, children: getProductPrice(product) })
911
- ] })
912
- ] }, product.sku)) }) : null
942
+ ) }),
943
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles.productInfo, children: [
944
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
945
+ "p",
946
+ {
947
+ style: styles.productName,
948
+ title: getProductName(product),
949
+ children: getProductName(product)
950
+ }
951
+ ),
952
+ (_a = visibleFieldsList()) == null ? void 0 : _a.map(
953
+ (field) => getDynamicField(product, field) !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
954
+ "p",
955
+ {
956
+ style: styles.productDynamicField,
957
+ title: String(getDynamicField(product, field)),
958
+ children: String(getDynamicField(product, field))
959
+ }
960
+ ) : null
961
+ ),
962
+ getProductPrice(product) !== "" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: styles.productPrice, children: getProductPrice(product) }) : null
963
+ ] })
964
+ ] }, product.sku);
965
+ }) }) : null
913
966
  ] }) }) : null });
914
967
  }
915
968
  var product_card_list_component_default = ProductCardList;
@@ -1322,7 +1375,6 @@ var TRANSLATIONS = {
1322
1375
  welcomeDescription: "I am your personal AI shopping assistant. Ask me anything about our products!",
1323
1376
  askMeAnything: "Ask me anything...",
1324
1377
  thinking: "Thinking...",
1325
- findByBudget: "Find by budget",
1326
1378
  feedbackError: "We are sorry, but we could not process your feedback. Please try again later."
1327
1379
  };
1328
1380
  var ICONS = {
@@ -1330,7 +1382,6 @@ var ICONS = {
1330
1382
  shopprompter: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/bot.svg",
1331
1383
  popularitems: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/fire.svg",
1332
1384
  compareproducts: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/box.svg",
1333
- findbybudget: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/foto.svg",
1334
1385
  sendHorizontal: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/send-horizontal.svg"
1335
1386
  };
1336
1387
  function ShopPrompter(props) {
@@ -1359,6 +1410,24 @@ function ShopPrompter(props) {
1359
1410
  const apiKey = (_b2 = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _b2.apiKey;
1360
1411
  return !token && !apiKey;
1361
1412
  }
1413
+ function showPriceIfEmptyVal() {
1414
+ const val = props.showPriceIfEmpty;
1415
+ if (typeof val === "string") {
1416
+ return val === "true";
1417
+ }
1418
+ return val != null ? val : false;
1419
+ }
1420
+ function visibleFieldsList() {
1421
+ const val = props.visibleFields;
1422
+ if (typeof val === "string") {
1423
+ try {
1424
+ return JSON.parse(val);
1425
+ } catch (e) {
1426
+ return val.split(",").map((s) => s.trim()).filter(Boolean);
1427
+ }
1428
+ }
1429
+ return val || [];
1430
+ }
1362
1431
  function themeObj() {
1363
1432
  if (typeof props.theme === "string") {
1364
1433
  try {
@@ -2096,7 +2165,9 @@ function ShopPrompter(props) {
2096
2165
  product_card_list_component_default,
2097
2166
  {
2098
2167
  skus: message.productSkus,
2099
- defaultLocale: props.defaultLocale
2168
+ defaultLocale: props.defaultLocale,
2169
+ showPriceIfEmpty: showPriceIfEmptyVal(),
2170
+ visibleFields: visibleFieldsList()
2100
2171
  }
2101
2172
  ) : null
2102
2173
  ] }) : null
package/dist/index.mjs CHANGED
@@ -764,6 +764,14 @@ var styles = {
764
764
  overflow: "hidden",
765
765
  textOverflow: "ellipsis"
766
766
  },
767
+ productDynamicField: {
768
+ fontSize: "0.6875rem",
769
+ color: "#6b7280",
770
+ margin: 0,
771
+ whiteSpace: "nowrap",
772
+ overflow: "hidden",
773
+ textOverflow: "ellipsis"
774
+ },
767
775
  productPrice: {
768
776
  fontSize: "0.8125rem",
769
777
  fontWeight: 500,
@@ -828,11 +836,43 @@ function ProductCardList(props) {
828
836
  const localized = ((_a = product.localization) == null ? void 0 : _a[locale]) || Object.values(product.localization || {})[0];
829
837
  return (localized == null ? void 0 : localized.name) || product.sku;
830
838
  }
839
+ function showPriceIfEmptyVal() {
840
+ const val = props.showPriceIfEmpty;
841
+ if (typeof val === "string") {
842
+ return val === "true";
843
+ }
844
+ return val != null ? val : false;
845
+ }
846
+ function visibleFieldsList() {
847
+ const val = props.visibleFields;
848
+ if (typeof val === "string") {
849
+ try {
850
+ return JSON.parse(val);
851
+ } catch (e) {
852
+ return val.split(",").map((s) => s.trim()).filter(Boolean);
853
+ }
854
+ }
855
+ return val || [];
856
+ }
857
+ function getDynamicField(product, field) {
858
+ var _a;
859
+ const locale = props.defaultLocale || "de";
860
+ const localized = ((_a = product.localization) == null ? void 0 : _a[locale]) || Object.values(product.localization || {})[0];
861
+ if (!localized) return void 0;
862
+ const parts = field.split(".");
863
+ let current = localized;
864
+ for (let i = 0; i < parts.length; i++) {
865
+ if (current === void 0 || current === null) return void 0;
866
+ current = current[parts[i]];
867
+ }
868
+ return current;
869
+ }
831
870
  function getProductPrice(product) {
832
871
  if (!product.pricing) return "";
833
872
  const priceVal = product.pricing.gross;
834
873
  const currency = product.pricing.currency;
835
874
  if (priceVal === void 0 || priceVal === null) return "";
875
+ if (priceVal === 0 && !showPriceIfEmptyVal()) return "";
836
876
  return priceVal.toFixed(2) + " " + (currency || "\u20AC");
837
877
  }
838
878
  function getProductImage(product) {
@@ -853,27 +893,40 @@ function ProductCardList(props) {
853
893
  "Error: ",
854
894
  error
855
895
  ] }) }) : null,
856
- !loading && products && products.length > 0 ? /* @__PURE__ */ jsx3("div", { style: styles.productCardsContainer, children: products == null ? void 0 : products.map((product) => /* @__PURE__ */ jsxs3("div", { style: styles.productCard, children: [
857
- /* @__PURE__ */ jsx3("div", { style: styles.productImageContainer, children: /* @__PURE__ */ jsx3(
858
- "img",
859
- {
860
- src: getProductImage(product),
861
- alt: getProductName(product),
862
- style: styles.productImage
863
- }
864
- ) }),
865
- /* @__PURE__ */ jsxs3("div", { style: styles.productInfo, children: [
866
- /* @__PURE__ */ jsx3(
867
- "p",
896
+ !loading && products && products.length > 0 ? /* @__PURE__ */ jsx3("div", { style: styles.productCardsContainer, children: products == null ? void 0 : products.map((product) => {
897
+ var _a;
898
+ return /* @__PURE__ */ jsxs3("div", { style: styles.productCard, children: [
899
+ /* @__PURE__ */ jsx3("div", { style: styles.productImageContainer, children: /* @__PURE__ */ jsx3(
900
+ "img",
868
901
  {
869
- style: styles.productName,
870
- title: getProductName(product),
871
- children: getProductName(product)
902
+ src: getProductImage(product),
903
+ alt: getProductName(product),
904
+ style: styles.productImage
872
905
  }
873
- ),
874
- /* @__PURE__ */ jsx3("p", { style: styles.productPrice, children: getProductPrice(product) })
875
- ] })
876
- ] }, product.sku)) }) : null
906
+ ) }),
907
+ /* @__PURE__ */ jsxs3("div", { style: styles.productInfo, children: [
908
+ /* @__PURE__ */ jsx3(
909
+ "p",
910
+ {
911
+ style: styles.productName,
912
+ title: getProductName(product),
913
+ children: getProductName(product)
914
+ }
915
+ ),
916
+ (_a = visibleFieldsList()) == null ? void 0 : _a.map(
917
+ (field) => getDynamicField(product, field) !== void 0 ? /* @__PURE__ */ jsx3(
918
+ "p",
919
+ {
920
+ style: styles.productDynamicField,
921
+ title: String(getDynamicField(product, field)),
922
+ children: String(getDynamicField(product, field))
923
+ }
924
+ ) : null
925
+ ),
926
+ getProductPrice(product) !== "" ? /* @__PURE__ */ jsx3("p", { style: styles.productPrice, children: getProductPrice(product) }) : null
927
+ ] })
928
+ ] }, product.sku);
929
+ }) }) : null
877
930
  ] }) }) : null });
878
931
  }
879
932
  var product_card_list_component_default = ProductCardList;
@@ -1286,7 +1339,6 @@ var TRANSLATIONS = {
1286
1339
  welcomeDescription: "I am your personal AI shopping assistant. Ask me anything about our products!",
1287
1340
  askMeAnything: "Ask me anything...",
1288
1341
  thinking: "Thinking...",
1289
- findByBudget: "Find by budget",
1290
1342
  feedbackError: "We are sorry, but we could not process your feedback. Please try again later."
1291
1343
  };
1292
1344
  var ICONS = {
@@ -1294,7 +1346,6 @@ var ICONS = {
1294
1346
  shopprompter: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/bot.svg",
1295
1347
  popularitems: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/fire.svg",
1296
1348
  compareproducts: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/box.svg",
1297
- findbybudget: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/foto.svg",
1298
1349
  sendHorizontal: "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/send-horizontal.svg"
1299
1350
  };
1300
1351
  function ShopPrompter(props) {
@@ -1323,6 +1374,24 @@ function ShopPrompter(props) {
1323
1374
  const apiKey = (_b2 = apiConfigObj == null ? void 0 : apiConfigObj()) == null ? void 0 : _b2.apiKey;
1324
1375
  return !token && !apiKey;
1325
1376
  }
1377
+ function showPriceIfEmptyVal() {
1378
+ const val = props.showPriceIfEmpty;
1379
+ if (typeof val === "string") {
1380
+ return val === "true";
1381
+ }
1382
+ return val != null ? val : false;
1383
+ }
1384
+ function visibleFieldsList() {
1385
+ const val = props.visibleFields;
1386
+ if (typeof val === "string") {
1387
+ try {
1388
+ return JSON.parse(val);
1389
+ } catch (e) {
1390
+ return val.split(",").map((s) => s.trim()).filter(Boolean);
1391
+ }
1392
+ }
1393
+ return val || [];
1394
+ }
1326
1395
  function themeObj() {
1327
1396
  if (typeof props.theme === "string") {
1328
1397
  try {
@@ -2060,7 +2129,9 @@ function ShopPrompter(props) {
2060
2129
  product_card_list_component_default,
2061
2130
  {
2062
2131
  skus: message.productSkus,
2063
- defaultLocale: props.defaultLocale
2132
+ defaultLocale: props.defaultLocale,
2133
+ showPriceIfEmpty: showPriceIfEmptyVal(),
2134
+ visibleFields: visibleFieldsList()
2064
2135
  }
2065
2136
  ) : null
2066
2137
  ] }) : null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shop-prompter/react",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -18,7 +18,8 @@ export interface ProductCategory {
18
18
 
19
19
  export interface ProductLocalization {
20
20
  name: string
21
- description: string
21
+ description: string,
22
+ extra: Record<string, any>,
22
23
  }
23
24
 
24
25
  export interface ProductApiResponse {
@@ -57,6 +57,14 @@ const styles = {
57
57
  overflow: "hidden",
58
58
  textOverflow: "ellipsis",
59
59
  },
60
+ productDynamicField: {
61
+ fontSize: "0.6875rem",
62
+ color: "#6b7280",
63
+ margin: 0,
64
+ whiteSpace: "nowrap",
65
+ overflow: "hidden",
66
+ textOverflow: "ellipsis",
67
+ },
60
68
  productPrice: {
61
69
  fontSize: "0.8125rem",
62
70
  fontWeight: 500,
@@ -134,11 +142,50 @@ function ProductCardList(props) {
134
142
  return localized?.name || product.sku;
135
143
  }
136
144
 
145
+ function showPriceIfEmptyVal() {
146
+ const val = props.showPriceIfEmpty;
147
+ if (typeof val === "string") {
148
+ return val === "true";
149
+ }
150
+ return val ?? false;
151
+ }
152
+
153
+ function visibleFieldsList() {
154
+ const val = props.visibleFields;
155
+ if (typeof val === "string") {
156
+ try {
157
+ return JSON.parse(val);
158
+ } catch (e) {
159
+ return val
160
+ .split(",")
161
+ .map((s) => s.trim())
162
+ .filter(Boolean);
163
+ }
164
+ }
165
+ return val || [];
166
+ }
167
+
168
+ function getDynamicField(product, field) {
169
+ const locale = props.defaultLocale || "de";
170
+ const localized =
171
+ product.localization?.[locale] ||
172
+ Object.values(product.localization || {})[0];
173
+ if (!localized) return undefined;
174
+ const parts = field.split(".");
175
+ let current = localized;
176
+ for (let i = 0; i < parts.length; i++) {
177
+ if (current === undefined || current === null) return undefined;
178
+ current = current[parts[i]];
179
+ }
180
+ return current;
181
+ }
182
+
137
183
  function getProductPrice(product) {
138
184
  if (!product.pricing) return "";
139
185
  const priceVal = product.pricing.gross;
140
186
  const currency = product.pricing.currency;
141
187
  if (priceVal === undefined || priceVal === null) return "";
188
+ if (priceVal === 0 && !showPriceIfEmptyVal()) return "";
142
189
  return priceVal.toFixed(2) + " " + (currency || "€");
143
190
  }
144
191
 
@@ -194,9 +241,21 @@ function ProductCardList(props) {
194
241
  >
195
242
  {getProductName(product)}
196
243
  </p>
197
- <p style={styles.productPrice}>
198
- {getProductPrice(product)}
199
- </p>
244
+ {visibleFieldsList()?.map((field) =>
245
+ getDynamicField(product, field) !== undefined ? (
246
+ <p
247
+ style={styles.productDynamicField}
248
+ title={String(getDynamicField(product, field))}
249
+ >
250
+ {String(getDynamicField(product, field))}
251
+ </p>
252
+ ) : null
253
+ )}
254
+ {getProductPrice(product) !== "" ? (
255
+ <p style={styles.productPrice}>
256
+ {getProductPrice(product)}
257
+ </p>
258
+ ) : null}
200
259
  </div>
201
260
  </div>
202
261
  ))}
@@ -414,7 +414,6 @@ const TRANSLATIONS = {
414
414
  "I am your personal AI shopping assistant. Ask me anything about our products!",
415
415
  askMeAnything: "Ask me anything...",
416
416
  thinking: "Thinking...",
417
- findByBudget: "Find by budget",
418
417
  feedbackError:
419
418
  "We are sorry, but we could not process your feedback. Please try again later.",
420
419
  };
@@ -426,8 +425,6 @@ const ICONS = {
426
425
  "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/fire.svg",
427
426
  compareproducts:
428
427
  "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/box.svg",
429
- findbybudget:
430
- "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/foto.svg",
431
428
  sendHorizontal:
432
429
  "https://cdn.jsdelivr.net/gh/lucide-icons/lucide@latest/icons/send-horizontal.svg",
433
430
  };
@@ -470,6 +467,29 @@ function ShopPrompter(props) {
470
467
  return !token && !apiKey;
471
468
  }
472
469
 
470
+ function showPriceIfEmptyVal() {
471
+ const val = props.showPriceIfEmpty;
472
+ if (typeof val === "string") {
473
+ return val === "true";
474
+ }
475
+ return val ?? false;
476
+ }
477
+
478
+ function visibleFieldsList() {
479
+ const val = props.visibleFields;
480
+ if (typeof val === "string") {
481
+ try {
482
+ return JSON.parse(val);
483
+ } catch (e) {
484
+ return val
485
+ .split(",")
486
+ .map((s) => s.trim())
487
+ .filter(Boolean);
488
+ }
489
+ }
490
+ return val || [];
491
+ }
492
+
473
493
  function themeObj() {
474
494
  if (typeof props.theme === "string") {
475
495
  try {
@@ -1288,6 +1308,8 @@ function ShopPrompter(props) {
1288
1308
  <ProductCardList
1289
1309
  skus={message.productSkus}
1290
1310
  defaultLocale={props.defaultLocale}
1311
+ showPriceIfEmpty={showPriceIfEmptyVal()}
1312
+ visibleFields={visibleFieldsList()}
1291
1313
  />
1292
1314
  ) : null}
1293
1315
  </div>