@pixelated-tech/components 3.4.3 → 3.5.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.
Files changed (228) hide show
  1. package/README.md +12 -191
  2. package/dist/components/admin/componentusage/componentAnalysis.js +12 -4
  3. package/dist/components/admin/componentusage/componentDiscovery.js +20 -6
  4. package/dist/components/admin/site-health/site-health-accessibility.js +5 -1
  5. package/dist/components/admin/site-health/site-health-axe-core.js +4 -0
  6. package/dist/components/admin/site-health/site-health-cloudwatch.integration.js +0 -5
  7. package/dist/components/admin/site-health/site-health-cloudwatch.js +7 -1
  8. package/dist/components/admin/site-health/site-health-dependency-vulnerabilities.js +4 -0
  9. package/dist/components/admin/site-health/site-health-github.js +6 -0
  10. package/dist/components/admin/site-health/site-health-google-analytics.js +6 -0
  11. package/dist/components/admin/site-health/site-health-google-search-console.js +6 -0
  12. package/dist/components/admin/site-health/site-health-on-site-seo.integration.js +128 -55
  13. package/dist/components/admin/site-health/site-health-on-site-seo.js +4 -0
  14. package/dist/components/admin/site-health/site-health-overview.js +11 -4
  15. package/dist/components/admin/site-health/site-health-performance.js +4 -0
  16. package/dist/components/admin/site-health/site-health-security.js +5 -1
  17. package/dist/components/admin/site-health/site-health-seo.js +5 -1
  18. package/dist/components/admin/site-health/site-health-template.js +19 -9
  19. package/dist/components/admin/site-health/site-health-uptime.js +4 -0
  20. package/dist/components/callout/callout.js +0 -10
  21. package/dist/components/carousel/carousel.js +15 -4
  22. package/dist/components/carousel/tiles.js +1 -1
  23. package/dist/components/cms/contentful.items.components.js +3 -4
  24. package/dist/components/cms/flickr.js +1 -1
  25. package/dist/components/cms/google.reviews.components.js +3 -3
  26. package/dist/components/cms/instagram.components.js +15 -5
  27. package/dist/components/cms/smartimage.js +2 -2
  28. package/dist/components/cms/wordpress.components.js +32 -6
  29. package/dist/components/cms/yelp.js +5 -0
  30. package/dist/components/config/config.server.js +7 -1
  31. package/dist/components/general/css.js +0 -1
  32. package/dist/components/general/image.js +0 -1
  33. package/dist/components/general/loading.js +2 -1
  34. package/dist/components/general/microinteractions.js +0 -1
  35. package/dist/components/general/modal.css +2 -4
  36. package/dist/components/general/modal.js +72 -30
  37. package/dist/components/general/sidepanel.js +16 -0
  38. package/dist/components/general/tab.js +1 -0
  39. package/dist/components/menu/menu-accordion.css +1 -1
  40. package/dist/components/menu/menu-accordion.js +15 -4
  41. package/dist/components/menu/menu-expando.js +21 -19
  42. package/dist/components/menu/menu-simple.js +14 -14
  43. package/dist/components/nerdjoke/nerdjoke.js +1 -1
  44. package/dist/components/seo/googlesearch.js +0 -1
  45. package/dist/components/seo/schema-blogposting.js +6 -1
  46. package/dist/components/seo/schema-recipe.js +34 -1
  47. package/dist/components/seo/schema-services.js +20 -2
  48. package/dist/components/shoppingcart/ebay.components.js +3 -3
  49. package/dist/components/shoppingcart/shoppingcart.components.js +76 -28
  50. package/dist/components/shoppingcart/shoppingcart.functions.js +4 -4
  51. package/dist/components/sitebuilder/config/CompoundFontSelector.js +13 -4
  52. package/dist/components/sitebuilder/config/ConfigBuilder.css +194 -5
  53. package/dist/components/sitebuilder/config/ConfigBuilder.js +183 -17
  54. package/dist/components/sitebuilder/config/FontSelector.js +13 -2
  55. package/dist/components/sitebuilder/config/routes-form.json +67 -0
  56. package/dist/components/sitebuilder/config/siteinfo-form.json +28 -14
  57. package/dist/components/sitebuilder/config/visualdesignform.json +4 -4
  58. package/dist/components/sitebuilder/form/formbuilder.js +1 -0
  59. package/dist/components/sitebuilder/form/formcomponents.js +2 -3
  60. package/dist/components/sitebuilder/form/formengine.js +6 -5
  61. package/dist/components/sitebuilder/form/formvalidator.js +5 -0
  62. package/dist/components/sitebuilder/page/components/PageBuilderUI.js +5 -1
  63. package/dist/components/structured/buzzwordbingo.css +0 -1
  64. package/dist/components/structured/recipe.js +1 -1
  65. package/dist/components/structured/socialcard.js +2 -2
  66. package/dist/components/utilities/functions.js +82 -1
  67. package/dist/components/utilities/gemini-api.client.js +76 -0
  68. package/dist/components/utilities/gemini-api.server.js +185 -0
  69. package/dist/data/routes.json +5 -5
  70. package/dist/index.adminclient.js +30 -0
  71. package/dist/index.adminserver.js +21 -0
  72. package/dist/index.js +4 -18
  73. package/dist/index.server.js +15 -28
  74. package/dist/types/components/admin/componentusage/componentAnalysis.d.ts.map +1 -1
  75. package/dist/types/components/admin/componentusage/componentDiscovery.d.ts +1 -1
  76. package/dist/types/components/admin/componentusage/componentDiscovery.d.ts.map +1 -1
  77. package/dist/types/components/admin/site-health/site-health-accessibility.d.ts +7 -4
  78. package/dist/types/components/admin/site-health/site-health-accessibility.d.ts.map +1 -1
  79. package/dist/types/components/admin/site-health/site-health-axe-core.d.ts +7 -4
  80. package/dist/types/components/admin/site-health/site-health-axe-core.d.ts.map +1 -1
  81. package/dist/types/components/admin/site-health/site-health-cloudwatch.d.ts +9 -6
  82. package/dist/types/components/admin/site-health/site-health-cloudwatch.d.ts.map +1 -1
  83. package/dist/types/components/admin/site-health/site-health-cloudwatch.integration.d.ts.map +1 -1
  84. package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts +7 -4
  85. package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts.map +1 -1
  86. package/dist/types/components/admin/site-health/site-health-github.d.ts +9 -6
  87. package/dist/types/components/admin/site-health/site-health-github.d.ts.map +1 -1
  88. package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts +9 -6
  89. package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts.map +1 -1
  90. package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts +9 -6
  91. package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts.map +1 -1
  92. package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts +8 -3
  93. package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts.map +1 -1
  94. package/dist/types/components/admin/site-health/site-health-on-site-seo.integration.d.ts.map +1 -1
  95. package/dist/types/components/admin/site-health/site-health-overview.d.ts +7 -4
  96. package/dist/types/components/admin/site-health/site-health-overview.d.ts.map +1 -1
  97. package/dist/types/components/admin/site-health/site-health-performance.d.ts +7 -4
  98. package/dist/types/components/admin/site-health/site-health-performance.d.ts.map +1 -1
  99. package/dist/types/components/admin/site-health/site-health-security.d.ts +7 -4
  100. package/dist/types/components/admin/site-health/site-health-security.d.ts.map +1 -1
  101. package/dist/types/components/admin/site-health/site-health-seo.d.ts +7 -4
  102. package/dist/types/components/admin/site-health/site-health-seo.d.ts.map +1 -1
  103. package/dist/types/components/admin/site-health/site-health-template.d.ts +12 -10
  104. package/dist/types/components/admin/site-health/site-health-template.d.ts.map +1 -1
  105. package/dist/types/components/admin/site-health/site-health-uptime.d.ts +7 -4
  106. package/dist/types/components/admin/site-health/site-health-uptime.d.ts.map +1 -1
  107. package/dist/types/components/callout/callout.d.ts +3 -3
  108. package/dist/types/components/callout/callout.d.ts.map +1 -1
  109. package/dist/types/components/carousel/carousel.d.ts +16 -7
  110. package/dist/types/components/carousel/carousel.d.ts.map +1 -1
  111. package/dist/types/components/carousel/tiles.d.ts +3 -6
  112. package/dist/types/components/carousel/tiles.d.ts.map +1 -1
  113. package/dist/types/components/cms/flickr.d.ts +3 -6
  114. package/dist/types/components/cms/flickr.d.ts.map +1 -1
  115. package/dist/types/components/cms/google.reviews.components.d.ts +1 -7
  116. package/dist/types/components/cms/google.reviews.components.d.ts.map +1 -1
  117. package/dist/types/components/cms/hubspot.components.d.ts +1 -2
  118. package/dist/types/components/cms/hubspot.components.d.ts.map +1 -1
  119. package/dist/types/components/cms/instagram.components.d.ts +14 -9
  120. package/dist/types/components/cms/instagram.components.d.ts.map +1 -1
  121. package/dist/types/components/cms/smartimage.d.ts +2 -28
  122. package/dist/types/components/cms/smartimage.d.ts.map +1 -1
  123. package/dist/types/components/cms/wordpress.components.d.ts +33 -14
  124. package/dist/types/components/cms/wordpress.components.d.ts.map +1 -1
  125. package/dist/types/components/cms/yelp.d.ts +9 -4
  126. package/dist/types/components/cms/yelp.d.ts.map +1 -1
  127. package/dist/types/components/config/config.server.d.ts +9 -6
  128. package/dist/types/components/config/config.server.d.ts.map +1 -1
  129. package/dist/types/components/general/loading.d.ts +5 -1
  130. package/dist/types/components/general/loading.d.ts.map +1 -1
  131. package/dist/types/components/general/microinteractions.d.ts +1 -3
  132. package/dist/types/components/general/microinteractions.d.ts.map +1 -1
  133. package/dist/types/components/general/modal.d.ts +11 -5
  134. package/dist/types/components/general/modal.d.ts.map +1 -1
  135. package/dist/types/components/general/semantic.d.ts +3 -3
  136. package/dist/types/components/general/sidepanel.d.ts +20 -13
  137. package/dist/types/components/general/sidepanel.d.ts.map +1 -1
  138. package/dist/types/components/general/tab.d.ts +1 -2
  139. package/dist/types/components/general/tab.d.ts.map +1 -1
  140. package/dist/types/components/menu/menu-accordion.d.ts +22 -9
  141. package/dist/types/components/menu/menu-accordion.d.ts.map +1 -1
  142. package/dist/types/components/menu/menu-expando.d.ts +14 -5
  143. package/dist/types/components/menu/menu-expando.d.ts.map +1 -1
  144. package/dist/types/components/menu/menu-simple.d.ts +4 -5
  145. package/dist/types/components/menu/menu-simple.d.ts.map +1 -1
  146. package/dist/types/components/nerdjoke/nerdjoke.d.ts +1 -1
  147. package/dist/types/components/nerdjoke/nerdjoke.d.ts.map +1 -1
  148. package/dist/types/components/seo/googleanalytics.d.ts.map +1 -1
  149. package/dist/types/components/seo/metadata.components.d.ts +2 -2
  150. package/dist/types/components/seo/metadata.components.d.ts.map +1 -1
  151. package/dist/types/components/seo/schema-blogposting.d.ts +7 -4
  152. package/dist/types/components/seo/schema-blogposting.d.ts.map +1 -1
  153. package/dist/types/components/seo/schema-recipe.d.ts +29 -30
  154. package/dist/types/components/seo/schema-recipe.d.ts.map +1 -1
  155. package/dist/types/components/seo/schema-services.d.ts +19 -9
  156. package/dist/types/components/seo/schema-services.d.ts.map +1 -1
  157. package/dist/types/components/shoppingcart/paypal.d.ts +1 -1
  158. package/dist/types/components/shoppingcart/paypal.d.ts.map +1 -1
  159. package/dist/types/components/shoppingcart/shoppingcart.components.d.ts +77 -28
  160. package/dist/types/components/shoppingcart/shoppingcart.components.d.ts.map +1 -1
  161. package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts +4 -23
  162. package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts.map +1 -1
  163. package/dist/types/components/sitebuilder/config/CompoundFontSelector.d.ts +10 -11
  164. package/dist/types/components/sitebuilder/config/CompoundFontSelector.d.ts.map +1 -1
  165. package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts +41 -174
  166. package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts.map +1 -1
  167. package/dist/types/components/sitebuilder/config/FontSelector.d.ts +12 -13
  168. package/dist/types/components/sitebuilder/config/FontSelector.d.ts.map +1 -1
  169. package/dist/types/components/sitebuilder/form/formbuilder.d.ts +7 -3
  170. package/dist/types/components/sitebuilder/form/formbuilder.d.ts.map +1 -1
  171. package/dist/types/components/sitebuilder/form/formcomponents.d.ts +1 -1
  172. package/dist/types/components/sitebuilder/form/formcomponents.d.ts.map +1 -1
  173. package/dist/types/components/sitebuilder/form/formengine.d.ts +1 -2
  174. package/dist/types/components/sitebuilder/form/formengine.d.ts.map +1 -1
  175. package/dist/types/components/sitebuilder/form/formextractor.d.ts +5 -4
  176. package/dist/types/components/sitebuilder/form/formextractor.d.ts.map +1 -1
  177. package/dist/types/components/sitebuilder/form/formtypes.d.ts +3 -3
  178. package/dist/types/components/sitebuilder/form/formtypes.d.ts.map +1 -1
  179. package/dist/types/components/sitebuilder/form/formvalidator.d.ts +8 -3
  180. package/dist/types/components/sitebuilder/form/formvalidator.d.ts.map +1 -1
  181. package/dist/types/components/sitebuilder/page/components/ComponentPropertiesForm.d.ts +2 -3
  182. package/dist/types/components/sitebuilder/page/components/ComponentPropertiesForm.d.ts.map +1 -1
  183. package/dist/types/components/sitebuilder/page/components/ComponentSelector.d.ts +2 -3
  184. package/dist/types/components/sitebuilder/page/components/ComponentSelector.d.ts.map +1 -1
  185. package/dist/types/components/sitebuilder/page/components/ComponentTree.d.ts +2 -3
  186. package/dist/types/components/sitebuilder/page/components/ComponentTree.d.ts.map +1 -1
  187. package/dist/types/components/sitebuilder/page/components/PageBuilderUI.d.ts +8 -7
  188. package/dist/types/components/sitebuilder/page/components/PageBuilderUI.d.ts.map +1 -1
  189. package/dist/types/components/sitebuilder/page/components/PageEngine.d.ts.map +1 -1
  190. package/dist/types/components/sitebuilder/page/components/SaveLoadSection.d.ts +2 -3
  191. package/dist/types/components/sitebuilder/page/components/SaveLoadSection.d.ts.map +1 -1
  192. package/dist/types/components/sitebuilder/page/lib/componentMap.d.ts +1 -1
  193. package/dist/types/components/structured/markdown.d.ts +1 -3
  194. package/dist/types/components/structured/markdown.d.ts.map +1 -1
  195. package/dist/types/components/structured/recipe.d.ts +5 -32
  196. package/dist/types/components/structured/recipe.d.ts.map +1 -1
  197. package/dist/types/components/structured/socialcard.d.ts +4 -0
  198. package/dist/types/components/structured/socialcard.d.ts.map +1 -1
  199. package/dist/types/components/structured/timeline.d.ts +1 -3
  200. package/dist/types/components/structured/timeline.d.ts.map +1 -1
  201. package/dist/types/components/utilities/functions.d.ts +20 -0
  202. package/dist/types/components/utilities/functions.d.ts.map +1 -1
  203. package/dist/types/components/utilities/gemini-api.client.d.ts +38 -0
  204. package/dist/types/components/utilities/gemini-api.client.d.ts.map +1 -0
  205. package/dist/types/components/utilities/gemini-api.server.d.ts +17 -0
  206. package/dist/types/components/utilities/gemini-api.server.d.ts.map +1 -0
  207. package/dist/types/index.adminclient.d.ts +27 -0
  208. package/dist/types/index.adminclient.d.ts.map +1 -0
  209. package/dist/types/index.adminserver.d.ts +19 -0
  210. package/dist/types/index.adminserver.d.ts.map +1 -0
  211. package/dist/types/index.d.ts +4 -18
  212. package/dist/types/index.server.d.ts +5 -28
  213. package/dist/types/stories/general/sidepanel.stories.d.ts.map +1 -1
  214. package/dist/types/stories/general/smartimage.stories.d.ts +74 -2
  215. package/dist/types/stories/general/smartimage.stories.d.ts.map +1 -1
  216. package/package.json +19 -9
  217. package/README.COMPONENTS.md +0 -2310
  218. package/dist/components/cms/pixelated.linkedin.js +0 -180
  219. package/dist/components/cms/pixelated.linkedin1.js +0 -84
  220. package/dist/components/cms/pixelated.linkedin2.js +0 -92
  221. package/dist/types/components/cms/pixelated.linkedin.d.ts +0 -2
  222. package/dist/types/components/cms/pixelated.linkedin.d.ts.map +0 -1
  223. package/dist/types/components/cms/pixelated.linkedin1.d.ts +0 -2
  224. package/dist/types/components/cms/pixelated.linkedin1.d.ts.map +0 -1
  225. package/dist/types/components/cms/pixelated.linkedin2.d.ts +0 -2
  226. package/dist/types/components/cms/pixelated.linkedin2.d.ts.map +0 -1
  227. package/dist/types/tests/pixelated.menu-expando.test.d.ts +0 -2
  228. package/dist/types/tests/pixelated.menu-expando.test.d.ts.map +0 -1
@@ -1,6 +1,24 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- export function ServicesSchema({ provider, services }) {
3
- const serviceObjects = services.map(service => ({
2
+ import PropTypes from 'prop-types';
3
+ ServicesSchema.propTypes = {
4
+ provider: PropTypes.shape({
5
+ name: PropTypes.string.isRequired,
6
+ url: PropTypes.string.isRequired,
7
+ logo: PropTypes.string,
8
+ telephone: PropTypes.string,
9
+ email: PropTypes.string,
10
+ }).isRequired,
11
+ services: PropTypes.arrayOf(PropTypes.shape({
12
+ name: PropTypes.string.isRequired,
13
+ description: PropTypes.string.isRequired,
14
+ url: PropTypes.string,
15
+ image: PropTypes.string,
16
+ areaServed: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
17
+ })).isRequired,
18
+ };
19
+ export function ServicesSchema(props) {
20
+ const { provider, services } = props;
21
+ const serviceObjects = services.map((service) => ({
4
22
  '@type': 'Service',
5
23
  name: service.name,
6
24
  description: service.description,
@@ -5,7 +5,7 @@ import PropTypes from "prop-types";
5
5
  import { Carousel } from '../carousel/carousel';
6
6
  import { SmartImage } from "../cms/smartimage";
7
7
  import { defaultEbayProps, ebaySunglassCategory, getEbayItems, getEbayItem, getShoppingCartItem } from "./ebay.functions";
8
- import { AddToShoppingCart } from "./shoppingcart.functions";
8
+ import { addToShoppingCart } from "./shoppingcart.functions";
9
9
  import { AddToCartButton, /* GoToCartButton */ ViewItemDetails } from "./shoppingcart.components";
10
10
  import { getCloudinaryRemoteFetchURL as getImg } from "../cms/cloudinary";
11
11
  import { Loading, ToggleLoading } from "../general/loading";
@@ -143,7 +143,7 @@ export function EbayListItem(props) {
143
143
  ? _jsx(EbayItemHeader, { url: itemURL, target: itemURLTarget, title: thisItem.title })
144
144
  : _jsx(EbayItemHeader, { title: thisItem.title }) }), _jsxs("div", { className: "ebayItemDetails grid12", children: [_jsxs("div", { children: [_jsx("b", { children: "Item ID: " }), thisItem.legacyItemId] }), _jsxs("div", { children: [_jsx("b", { children: "Quantity: " }), thisItem.categories[0].categoryId == ebaySunglassCategory ? 1 : 10] }), _jsxs("div", { children: [_jsx("b", { children: "Condition: " }), thisItem.condition] }), _jsxs("div", { children: [_jsx("b", { children: "Seller: " }), thisItem.seller.username, " (", thisItem.seller.feedbackScore, ")", _jsx("br", {}), thisItem.seller.feedbackPercentage, "% positive"] }), _jsxs("div", { children: [_jsx("b", { children: "Buying Options: " }), thisItem.buyingOptions[0]] }), _jsxs("div", { children: [_jsx("b", { children: "Location: " }), thisItem.itemLocation.postalCode + ", " + thisItem.itemLocation.country] }), _jsxs("div", { children: [_jsx("b", { children: "Listing Date: " }), thisItem.itemCreationDate] })] }), _jsx("div", { className: "ebayItemPrice", children: itemURL
145
145
  ? _jsxs("a", { href: itemURL, target: itemURLTarget, rel: "noreferrer", children: ["$", thisItem.price.value + " " + thisItem.price.currency] })
146
- : "$" + thisItem.price.value + " " + thisItem.price.currency }), _jsx("br", {}), _jsxs("div", { className: "ebayItemAddToCart", children: [_jsx(ViewItemDetails, { href: "/store", itemID: thisItem.legacyItemId }), _jsx(AddToCartButton, { handler: AddToShoppingCart, item: shoppingCartItem, itemID: thisItem.legacyItemId })] })] })] }));
146
+ : "$" + thisItem.price.value + " " + thisItem.price.currency }), _jsx("br", {}), _jsxs("div", { className: "ebayItemAddToCart", children: [_jsx(ViewItemDetails, { href: "/store", itemID: thisItem.legacyItemId }), _jsx(AddToCartButton, { handler: addToShoppingCart, item: shoppingCartItem, itemID: thisItem.legacyItemId })] })] })] }));
147
147
  }
148
148
  EbayItemHeader.propTypes = {
149
149
  title: PropTypes.string.isRequired,
@@ -195,7 +195,7 @@ export function EbayItemDetail(props) {
195
195
  ? _jsx(EbayItemHeader, { url: itemURL, title: thisItem.title })
196
196
  : _jsx(EbayItemHeader, { title: thisItem.title }) }), _jsx("br", {}), _jsx("div", { className: "ebayItemPhotoCarousel grid-s1-e7", children: _jsx(Carousel, { cards: images, draggable: true, imgFit: "contain" }) }), _jsxs("div", { className: "grid-s7-e13", children: [_jsx("div", { className: "ebayItemDetails grid12", children: _jsx("div", { dangerouslySetInnerHTML: { __html: thisItem.description.replace(/(<br\s*\/?>\s*){2,}/gi, '') } }) }), _jsx("br", {}), _jsxs("div", { className: "ebayItemDetails grid12", children: [_jsxs("div", { children: [_jsx("b", { children: "Item ID: " }), thisItem.legacyItemId] }), _jsxs("div", { children: [_jsx("b", { children: "Quantity: " }), thisItem.categoryId == ebaySunglassCategory ? 1 : 10] }), _jsxs("div", { children: [_jsx("b", { children: "Category: " }), thisItem.categoryPath] }), _jsxs("div", { children: [_jsx("b", { children: "Condition: " }), thisItem.condition] }), _jsxs("div", { children: [_jsx("b", { children: "Seller: " }), thisItem.seller.username, " (", thisItem.seller.feedbackScore, ")", _jsx("br", {}), thisItem.seller.feedbackPercentage, "% positive"] }), _jsxs("div", { children: [_jsx("b", { children: "Buying Options: " }), thisItem.buyingOptions[0]] }), _jsxs("div", { children: [_jsx("b", { children: "Location: " }), thisItem.itemLocation.city + ", " + thisItem.itemLocation.stateOrProvince] }), _jsxs("div", { children: [_jsx("b", { children: "Listing Date: " }), thisItem.itemCreationDate] }), _jsx("br", {})] }), _jsx("div", { className: "ebayItemPrice", children: itemURL
197
197
  ? _jsxs("a", { href: itemURL, target: itemURLTarget, rel: "noreferrer", children: ["$", thisItem.price.value + " " + thisItem.price.currency] })
198
- : "$" + thisItem.price.value + " " + thisItem.price.currency }), _jsx("br", {}), _jsx("div", { className: "ebayItemAddToCart", children: _jsx(AddToCartButton, { handler: AddToShoppingCart, item: shoppingCartItem, itemID: thisItem.legacyItemId }) })] })] }) }));
198
+ : "$" + thisItem.price.value + " " + thisItem.price.currency }), _jsx("br", {}), _jsx("div", { className: "ebayItemAddToCart", children: _jsx(AddToCartButton, { handler: addToShoppingCart, item: shoppingCartItem, itemID: thisItem.legacyItemId }) })] })] }) }));
199
199
  }
200
200
  else {
201
201
  return (_jsx(_Fragment, { children: _jsx("div", { id: "ebayItems", className: "ebayItems", children: _jsx("div", { className: "centered", children: "Loading..." }) }) }));
@@ -11,7 +11,7 @@ import '../sitebuilder/form/form.css';
11
11
  import { MicroInteractions } from '../general/microinteractions';
12
12
  import { Modal, handleModalOpen } from '../general/modal';
13
13
  import { Table } from "../general/table";
14
- import { getCart, getShippingInfo, SetShippingInfo, setDiscountCodes, getRemoteDiscountCodes, getCheckoutData, RemoveFromShoppingCart, ClearShoppingCart, formatAsUSD, getCartItemCount } from "./shoppingcart.functions";
14
+ import { getCart, getShippingInfo, setShippingInfo, setDiscountCodes, getRemoteDiscountCodes, getCheckoutData, removeFromShoppingCart, clearShoppingCart, formatAsUSD, getCartItemCount } from "./shoppingcart.functions";
15
15
  import { usePixelatedConfig } from '../config/config.client';
16
16
  import { SmartImage } from '../cms/smartimage';
17
17
  import shippingToData from "./shipping.to.json";
@@ -20,10 +20,13 @@ const debug = false;
20
20
  /* ================================================ */
21
21
  /* ========== SHOPPING CART UI COMPONENT ========== */
22
22
  /* ================================================ */
23
+ ShoppingCart.propTypes = {
24
+ payPalClientID: PropTypes.string.isRequired,
25
+ };
23
26
  export function ShoppingCart(props) {
24
27
  const [shoppingCart, setShoppingCart] = useState();
25
- const [shippingInfo, setShippingInfo] = useState();
26
- const [checkoutInfo, setCheckoutInfo] = useState();
28
+ const [shippingData, setShippingData] = useState();
29
+ const [checkoutData, setcheckoutData] = useState();
27
30
  const [orderData, setOrderData] = useState();
28
31
  const [progressStep, setProgressStep] = useState("EmptyCart");
29
32
  function SetProgressStep(step) {
@@ -61,7 +64,7 @@ export function ShoppingCart(props) {
61
64
  setCart(shoppingCart ?? []);
62
65
  }, [shoppingCart]); */
63
66
  /* useEffect(() => {
64
- // UPDATE LOCALSTORAGE IF SHIPPINGINFO STATE CHANGES
67
+ // UPDATE LOCALSTORAGE IF SHIPPINGDATA STATE CHANGES
65
68
  setShippingInfo(shippingInfo);
66
69
  }, [shippingInfo]); */
67
70
  useEffect(() => {
@@ -69,11 +72,11 @@ export function ShoppingCart(props) {
69
72
  (async () => {
70
73
  setDiscountCodes(await getRemoteDiscountCodes());
71
74
  })();
72
- // UPDATE SHOPPINGCART AND SHIPPINGINFO STATES IF LOCALSTORAGE CHANGES
75
+ // UPDATE SHOPPINGCART AND SHIPPINGDATA STATES IF LOCALSTORAGE CHANGES
73
76
  function handleStorageChange() {
74
77
  setShoppingCart(getCart());
75
- setShippingInfo(getShippingInfo());
76
- setCheckoutInfo(getCheckoutData());
78
+ setShippingData(getShippingInfo());
79
+ setcheckoutData(getCheckoutData());
77
80
  SetProgressStep();
78
81
  }
79
82
  window.addEventListener('storage', handleStorageChange);
@@ -85,11 +88,11 @@ export function ShoppingCart(props) {
85
88
  useEffect(() => {
86
89
  // LOAD THE SHIPPING INFO FORM WITH VALUES IF SHIPPING INFO HAS ALREADY BEEN SAVED
87
90
  const form = document.getElementById("address_to");
88
- if (shippingInfo && form) {
89
- for (const key in shippingInfo) {
91
+ if (shippingData && form) {
92
+ for (const key in shippingData) {
90
93
  const input = form.elements[key];
91
94
  if (input) { // Check if the form element exists
92
- input.value = shippingInfo[key].toString();
95
+ input.value = shippingData[key].toString();
93
96
  }
94
97
  }
95
98
  }
@@ -113,7 +116,7 @@ export function ShoppingCart(props) {
113
116
  const formElement = document.getElementById(formID);
114
117
  const formData = new FormData(formElement);
115
118
  const formObject = Object.fromEntries(formData);
116
- SetShippingInfo(formObject);
119
+ setShippingInfo(formObject);
117
120
  }
118
121
  handleOnApprove.propTypes = {
119
122
  data: PropTypes.object.isRequired
@@ -121,9 +124,8 @@ export function ShoppingCart(props) {
121
124
  function handleOnApprove(props) {
122
125
  if (debug)
123
126
  console.log("Handling onApprove");
124
- // eslint-disable-next-line react/prop-types
125
127
  setOrderData(props.data);
126
- ClearShoppingCart();
128
+ clearShoppingCart();
127
129
  // SetProgressStep();
128
130
  SetProgressStep("ThankYou");
129
131
  }
@@ -144,20 +146,27 @@ export function ShoppingCart(props) {
144
146
  }
145
147
  else if (progressStep === "Checkout") {
146
148
  // ========== CHECKOUT ==========
147
- return (_jsxs("div", { className: "pixCart", children: [_jsx(CalloutHeader, { title: "Checkout Summary : " }), checkoutInfo && _jsx(CheckoutItems, { checkoutData: checkoutInfo }), _jsx("br", {}), _jsx(FormButton, { className: "pixCartButton", type: "button", id: "backToCart", text: "<= Back To Cart", onClick: () => SetProgressStep("ShippingInfo") }), _jsx("br", {}), _jsx(PayPal, { payPalClientID: props.payPalClientID, checkoutData: getCheckoutData(), onApprove: handleOnApprove })] }));
149
+ return (_jsxs("div", { className: "pixCart", children: [_jsx(CalloutHeader, { title: "Checkout Summary : " }), checkoutData && _jsx(CheckoutItems, { ...checkoutData }), _jsx("br", {}), _jsx(FormButton, { className: "pixCartButton", type: "button", id: "backToCart", text: "<= Back To Cart", onClick: () => SetProgressStep("ShippingInfo") }), _jsx("br", {}), _jsx(PayPal, { payPalClientID: props.payPalClientID, checkoutData: getCheckoutData(), onApprove: handleOnApprove })] }));
148
150
  }
149
151
  else if (progressStep === "ShippingInfo") {
150
152
  // ========== SHOPPING CART ==========
151
153
  // ========== SHIPPING INFO ==========
152
- return (_jsxs("div", { className: "pixCart", children: [_jsx(CalloutHeader, { title: "Shopping Cart : " }), paintCartItems(shoppingCart ?? []), _jsx("br", {}), _jsx("div", { children: _jsx(FormButton, { className: "pixCartButton", type: "button", id: "backToCart", text: "Clear Cart", onClick: () => ClearShoppingCart() }) }), _jsx("br", {}), _jsx("br", {}), _jsx("hr", {}), _jsx("br", {}), _jsx("br", {}), _jsxs("div", { children: [_jsx(CalloutHeader, { title: "Shipping To : " }), _jsx(FormEngine, { name: "address_to", id: "address_to", formData: shippingToData, onSubmitHandler: onShippingSubmit })] })] }));
154
+ return (_jsxs("div", { className: "pixCart", children: [_jsx(CalloutHeader, { title: "Shopping Cart : " }), paintCartItems(shoppingCart ?? []), _jsx("br", {}), _jsx("div", { children: _jsx(FormButton, { className: "pixCartButton", type: "button", id: "backToCart", text: "Clear Cart", onClick: () => clearShoppingCart() }) }), _jsx("br", {}), _jsx("br", {}), _jsx("hr", {}), _jsx("br", {}), _jsx("br", {}), _jsxs("div", { children: [_jsx(CalloutHeader, { title: "Shipping To : " }), _jsx(FormEngine, { name: "address_to", id: "address_to", formData: shippingToData, onSubmitHandler: onShippingSubmit })] })] }));
153
155
  }
154
156
  else {
155
157
  // ========== EMPTY SHOPPING CART ==========
156
158
  return (_jsxs("div", { className: "pixCart", children: [_jsx(CalloutHeader, { title: "Shopping Cart : " }), _jsx("br", {}), _jsx("div", { className: "centered", children: "No items in your shopping cart" }), _jsx("div", { id: "paypal-button-container", className: "paypal-button-container" })] }));
157
159
  }
158
160
  }
159
- ShoppingCartItem.PropTypes = {
160
- item: PropTypes.object.isRequired
161
+ ShoppingCartItem.propTypes = {
162
+ item: PropTypes.shape({
163
+ itemID: PropTypes.string.isRequired,
164
+ itemURL: PropTypes.string,
165
+ itemTitle: PropTypes.string.isRequired,
166
+ itemImageURL: PropTypes.string,
167
+ itemQuantity: PropTypes.number.isRequired,
168
+ itemCost: PropTypes.number.isRequired,
169
+ }).isRequired
161
170
  };
162
171
  export function ShoppingCartItem(props) {
163
172
  const thisItem = props.item;
@@ -171,30 +180,53 @@ export function ShoppingCartItem(props) {
171
180
  _jsx(SmartImage, { src: thisItem.itemImageURL, title: thisItem.itemTitle, alt: thisItem.itemTitle, cloudinaryEnv: config?.cloudinary?.product_env, cloudinaryDomain: config?.cloudinary?.baseUrl, cloudinaryTransforms: config?.cloudinary?.transforms }))
172
181
  : _jsx(_Fragment, {}) }), _jsxs("div", { className: "grid-s4-e11", children: [_jsx("div", { className: "pixCartItemHeader", children: _jsx("span", { children: thisItem.itemURL
173
182
  ? _jsx("a", { href: thisItem.itemURL, target: thisItemTarget, rel: "noopener noreferrer", children: _jsx("h2", { className: "", children: thisItem.itemTitle }) })
174
- : _jsx("h2", { className: "", children: thisItem.itemTitle }) }) }), _jsxs("div", { className: "pixCartItemDetails grid12", children: [_jsx("br", {}), _jsxs("div", { children: [_jsx("b", { children: "Item ID: " }), thisItem.itemID] }), _jsxs("div", { children: [_jsx("b", { children: "Quantity: " }), thisItem.itemQuantity] }), _jsx("br", {}), _jsx("div", { children: _jsx(FormButton, { className: "pixCartButton", type: "button", id: `btn-rm-${thisItem.itemID}`, text: "Remove Item From Cart", onClick: () => RemoveFromShoppingCart(thisItem) }) })] })] }), _jsx("div", { className: "grid-s11-e13", children: _jsx("div", { className: "pixCartItemPrice", children: formatAsUSD(thisItem.itemCost) }) })] }));
183
+ : _jsx("h2", { className: "", children: thisItem.itemTitle }) }) }), _jsxs("div", { className: "pixCartItemDetails grid12", children: [_jsx("br", {}), _jsxs("div", { children: [_jsx("b", { children: "Item ID: " }), thisItem.itemID] }), _jsxs("div", { children: [_jsx("b", { children: "Quantity: " }), thisItem.itemQuantity] }), _jsx("br", {}), _jsx("div", { children: _jsx(FormButton, { className: "pixCartButton", type: "button", id: `btn-rm-${thisItem.itemID}`, text: "Remove Item From Cart", onClick: () => removeFromShoppingCart(thisItem) }) })] })] }), _jsx("div", { className: "grid-s11-e13", children: _jsx("div", { className: "pixCartItemPrice", children: formatAsUSD(thisItem.itemCost) }) })] }));
175
184
  }
185
+ CheckoutItems.propTypes = {
186
+ items: PropTypes.arrayOf(PropTypes.shape({
187
+ itemID: PropTypes.string.isRequired,
188
+ itemURL: PropTypes.string,
189
+ itemTitle: PropTypes.string.isRequired,
190
+ itemImageURL: PropTypes.string,
191
+ itemQuantity: PropTypes.number.isRequired,
192
+ itemCost: PropTypes.number.isRequired,
193
+ })).isRequired,
194
+ shippingTo: PropTypes.shape({
195
+ name: PropTypes.string.isRequired,
196
+ street1: PropTypes.string.isRequired,
197
+ city: PropTypes.string.isRequired,
198
+ state: PropTypes.string.isRequired,
199
+ zip: PropTypes.string.isRequired,
200
+ }).isRequired,
201
+ subtotal_discount: PropTypes.number.isRequired,
202
+ subtotal: PropTypes.number.isRequired,
203
+ shippingCost: PropTypes.number.isRequired,
204
+ handlingFee: PropTypes.number.isRequired,
205
+ salesTax: PropTypes.number.isRequired,
206
+ total: PropTypes.number.isRequired,
207
+ };
176
208
  export function CheckoutItems(props) {
177
- const items = props.checkoutData.items.map((item) => (_jsxs("div", { children: [item.itemQuantity, " X - ", item.itemTitle, " ( ", formatAsUSD(item.itemCost), " )"] }, item.itemID)));
178
- const to = props.checkoutData.shippingTo;
209
+ const { items, shippingTo, subtotal_discount, subtotal, shippingCost, handlingFee, salesTax, total } = props;
210
+ const to = shippingTo;
179
211
  const addr = _jsxs(_Fragment, { children: [_jsx("div", { children: to.name }), _jsx("div", { children: to.street1 }), _jsxs("div", { children: [to.city, ", ", to.state, " ", to.zip] })] });
180
212
  let checkoutTableData = [{
181
213
  "Name": "Shopping Cart Items : ",
182
214
  "Value": items,
183
215
  }, {
184
216
  "Name": "Subtotal Discount : ",
185
- "Value": formatAsUSD(props.checkoutData.subtotal_discount),
217
+ "Value": formatAsUSD(subtotal_discount),
186
218
  }, {
187
219
  "Name": "Subtotal : ",
188
- "Value": formatAsUSD(props.checkoutData.subtotal),
220
+ "Value": formatAsUSD(subtotal),
189
221
  }, {
190
222
  "Name": "Shipping Address : ",
191
223
  "Value": addr,
192
224
  }, {
193
225
  "Name": "Shipping Cost : ",
194
- "Value": formatAsUSD(props.checkoutData.shippingCost),
226
+ "Value": formatAsUSD(shippingCost),
195
227
  }, {
196
228
  "Name": "Handling Fee : ",
197
- "Value": formatAsUSD(props.checkoutData.handlingFee),
229
+ "Value": formatAsUSD(handlingFee),
198
230
  }, /* {
199
231
  "Name": "Insurance Cost : ",
200
232
  "Value": formatAsUSD(checkoutData.insuranceCost ?? 0),
@@ -204,16 +236,19 @@ export function CheckoutItems(props) {
204
236
  }, */
205
237
  {
206
238
  "Name": "Sales Tax : ",
207
- "Value": formatAsUSD(props.checkoutData.salesTax),
239
+ "Value": formatAsUSD(salesTax),
208
240
  }, {
209
241
  "Name": "TOTAL : ",
210
- "Value": formatAsUSD(props.checkoutData.total),
242
+ "Value": formatAsUSD(total),
211
243
  }];
212
- if (props.checkoutData.subtotal_discount == 0) {
244
+ if (subtotal_discount == 0) {
213
245
  checkoutTableData = checkoutTableData.filter(obj => obj.Name !== "Subtotal Discount : ");
214
246
  }
215
247
  return (_jsx(Table, { id: "pixCheckout", data: checkoutTableData }));
216
248
  }
249
+ CartButton.propTypes = {
250
+ href: PropTypes.string.isRequired,
251
+ };
217
252
  export function CartButton(props) {
218
253
  const config = usePixelatedConfig();
219
254
  const [cartCount, setCartCount] = useState(0);
@@ -238,9 +273,18 @@ export function CartButton(props) {
238
273
  }, [cartCount]);
239
274
  return (_jsx("div", { className: "pixCart", children: _jsxs("button", { className: "pixCartButton", type: "button", id: "pixCartButton", onClick: () => window.location.href = props.href, children: [_jsx(SmartImage, { src: "/images/icons/cart-icon.png", title: "View Shopping Cart", alt: "View Shopping Cart", cloudinaryEnv: config?.cloudinary?.product_env, cloudinaryDomain: config?.cloudinary?.baseUrl, cloudinaryTransforms: config?.cloudinary?.transforms }), _jsxs("span", { children: ["\u00A0", `(${cartCount})`] })] }) }));
240
275
  }
276
+ ViewItemDetails.propTypes = {
277
+ href: PropTypes.string.isRequired,
278
+ itemID: PropTypes.string.isRequired,
279
+ };
241
280
  export function ViewItemDetails(props) {
242
281
  return (_jsx("div", { children: _jsx(FormButton, { className: "pixCartButton", type: "button", id: `btn-item-${props.itemID}`, text: "View Item Details", onClick: () => window.location.href = `${props.href}/${props.itemID}` }) }));
243
282
  }
283
+ AddToCartButton.propTypes = {
284
+ handler: PropTypes.func.isRequired,
285
+ item: PropTypes.object.isRequired,
286
+ itemID: PropTypes.string.isRequired,
287
+ };
244
288
  export function AddToCartButton(props) {
245
289
  const [modalContent, setModalContent] = useState();
246
290
  useEffect(() => {
@@ -251,8 +295,12 @@ export function AddToCartButton(props) {
251
295
  props.handler(props.item);
252
296
  handleModalOpen(e.nativeEvent, "-" + props.itemID);
253
297
  }
254
- return (_jsxs("div", { children: [_jsx(FormButton, { className: "pixCartButton", type: "button", id: `btn-add-${props.itemID}`, text: "Add to Shopping Cart", onClick: (e) => handleClick(e) }), _jsx(Modal, { modalContent: modalContent, modalID: "-" + props.itemID })] }));
298
+ return (_jsxs("div", { children: [_jsx(FormButton, { className: "pixCartButton", type: "button", id: `btn-add-${props.itemID}`, text: "Add to Shopping Cart", onClick: (e) => handleClick(e) }), modalContent && _jsx(Modal, { modalContent: modalContent, modalID: "-" + props.itemID })] }));
255
299
  }
300
+ GoToCartButton.propTypes = {
301
+ href: PropTypes.string.isRequired,
302
+ itemID: PropTypes.string.isRequired,
303
+ };
256
304
  export function GoToCartButton(props) {
257
305
  return (_jsx("div", { children: _jsx(FormButton, { className: "pixCartButton", type: "button", id: `btn-cart-${props.itemID}`, text: "Go to Shopping Cart", onClick: () => window.location.href = props.href }) }));
258
306
  }
@@ -127,7 +127,7 @@ export function getCartSubTotal(cart) {
127
127
  }
128
128
  return formatAsHundredths(cartSubTotal);
129
129
  }
130
- export function AddToShoppingCart(thisItem) {
130
+ export function addToShoppingCart(thisItem) {
131
131
  let cart = getCart();
132
132
  if (alreadyInCart(cart, thisItem.itemID)) {
133
133
  const index = getIndexInCart(cart, thisItem.itemID);
@@ -153,7 +153,7 @@ export function AddToShoppingCart(thisItem) {
153
153
  localStorage.setItem(shoppingCartKey, JSON.stringify(cart));
154
154
  window.dispatchEvent(new Event('storage'));
155
155
  }
156
- export function RemoveFromShoppingCart(thisItem) {
156
+ export function removeFromShoppingCart(thisItem) {
157
157
  let cart = getCart();
158
158
  if (alreadyInCart(cart, thisItem.itemID)) {
159
159
  cart.splice(getIndexInCart(cart, thisItem.itemID), 1);
@@ -161,7 +161,7 @@ export function RemoveFromShoppingCart(thisItem) {
161
161
  localStorage.setItem(shoppingCartKey, JSON.stringify(cart));
162
162
  window.dispatchEvent(new Event('storage'));
163
163
  }
164
- export function ClearShoppingCart() {
164
+ export function clearShoppingCart() {
165
165
  localStorage.removeItem(shoppingCartKey);
166
166
  localStorage.removeItem(shippingInfoKey);
167
167
  window.dispatchEvent(new Event('storage'));
@@ -171,7 +171,7 @@ export function getShippingInfo() {
171
171
  const ship = localStorage.getItem(shippingInfoKey);
172
172
  return ship ? JSON.parse(ship) : [];
173
173
  }
174
- export function SetShippingInfo(shippingFormData) {
174
+ export function setShippingInfo(shippingFormData) {
175
175
  localStorage.setItem(shippingInfoKey, JSON.stringify(shippingFormData));
176
176
  window.dispatchEvent(new Event('storage'));
177
177
  }
@@ -3,7 +3,16 @@ import { useState, useEffect } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import { FontSelector } from './FontSelector';
5
5
  import './CompoundFontSelector.css';
6
- export function CompoundFontSelector({ id, name, label, required = false, value = '', onChange }) {
6
+ CompoundFontSelector.propTypes = {
7
+ id: PropTypes.string.isRequired,
8
+ name: PropTypes.string.isRequired,
9
+ label: PropTypes.string.isRequired,
10
+ required: PropTypes.bool,
11
+ value: PropTypes.string,
12
+ onChange: PropTypes.func,
13
+ };
14
+ export function CompoundFontSelector(props) {
15
+ const { id, name, label, required = false, value = '', onChange } = props;
7
16
  // Parse the compound value into primary, fallback, generic parts
8
17
  const parseCompoundValue = (val) => {
9
18
  const parts = val.split(',').map(s => s.trim());
@@ -13,10 +22,10 @@ export function CompoundFontSelector({ id, name, label, required = false, value
13
22
  generic: parts[2] || ''
14
23
  };
15
24
  };
16
- const [fonts, setFonts] = useState(parseCompoundValue(value));
25
+ const [fonts, setFonts] = useState(parseCompoundValue(value || ''));
17
26
  // Update fonts when value changes externally
18
27
  useEffect(() => {
19
- setFonts(parseCompoundValue(value));
28
+ setFonts(parseCompoundValue(value || ''));
20
29
  }, [value]);
21
30
  // Combine fonts into a single font stack value
22
31
  const combineFonts = (fontParts) => {
@@ -29,7 +38,7 @@ export function CompoundFontSelector({ id, name, label, required = false, value
29
38
  const combinedValue = combineFonts(updatedFonts);
30
39
  onChange?.(combinedValue);
31
40
  };
32
- return (_jsxs("div", { className: "compound-font-selector", children: [_jsx("label", { children: label }), _jsxs("div", { className: "compound-container", children: [_jsx(FontSelector, { id: `${id}-primary`, name: `${name}-primary`, label: "Primary Font", fontType: "google", required: required, placeholder: "Select Google Font", value: fonts.primary, onChange: (val) => handleFontChange('primary', val) }), _jsx(FontSelector, { id: `${id}-fallback`, name: `${name}-fallback`, label: "Fallback Font", fontType: "websafe", required: false, placeholder: "Select web-safe font", value: fonts.fallback, onChange: (val) => handleFontChange('fallback', val) }), _jsx(FontSelector, { id: `${id}-generic`, name: `${name}-generic`, label: "Generic Family", fontType: "generic", required: false, placeholder: "Select generic family", value: fonts.generic, onChange: (val) => handleFontChange('generic', val) })] })] }));
41
+ return (_jsxs("div", { className: "compound-font-selector", children: [_jsx("label", { children: label }), _jsxs("div", { className: "compound-container", children: [_jsx(FontSelector, { id: `${id}-primary`, name: `${name}-primary`, label: "Primary Font", fontType: "google", required: !!required, placeholder: "Select Google Font", value: fonts.primary, onChange: (val) => handleFontChange('primary', val) }), _jsx(FontSelector, { id: `${id}-fallback`, name: `${name}-fallback`, label: "Fallback Font", fontType: "websafe", required: false, placeholder: "Select web-safe font", value: fonts.fallback, onChange: (val) => handleFontChange('fallback', val) }), _jsx(FontSelector, { id: `${id}-generic`, name: `${name}-generic`, label: "Generic Family", fontType: "generic", required: false, placeholder: "Select generic family", value: fonts.generic, onChange: (val) => handleFontChange('generic', val) })] })] }));
33
42
  }
34
43
  CompoundFontSelector.propTypes = {
35
44
  id: PropTypes.string.isRequired,
@@ -162,8 +162,6 @@
162
162
  }
163
163
 
164
164
  .route-item {
165
- display: grid;
166
- grid-template-columns: 2fr 2fr 2fr 2fr auto;
167
165
  gap: 10px;
168
166
  align-items: center;
169
167
  padding: 10px;
@@ -172,11 +170,18 @@
172
170
  margin-bottom: 10px;
173
171
  }
174
172
 
175
- .route-item input {
173
+ .route-item input,
174
+ .route-item select,
175
+ .route-item textarea {
176
176
  padding: 6px 8px;
177
177
  border: 1px solid #ddd;
178
178
  border-radius: 3px;
179
- font-size: 14px;
179
+ font-size: var(--font-size5);
180
+ }
181
+
182
+ .route-item label {
183
+ font-size: var(--font-size5);
184
+ font-weight: bold;
180
185
  }
181
186
 
182
187
  .route-item button {
@@ -274,4 +279,188 @@
274
279
  font-size: 14px;
275
280
  margin-top: 8px;
276
281
  font-weight: 500;
277
- }
282
+ }
283
+ /* AI Recommendations Modal */
284
+ .ai-recommendations-modal {
285
+ max-width: 600px;
286
+ }
287
+
288
+ .ai-recommendations-modal h3 {
289
+ margin-top: 0;
290
+ color: #333;
291
+ }
292
+
293
+ .ai-loading {
294
+ text-align: center;
295
+ padding: 20px;
296
+ }
297
+
298
+ .loading-spinner {
299
+ border: 4px solid #f3f3f3;
300
+ border-top: 4px solid #007acc;
301
+ border-radius: 50%;
302
+ width: 30px;
303
+ height: 30px;
304
+ animation: spin 1s linear infinite;
305
+ margin: 10px auto;
306
+ }
307
+
308
+ @keyframes spin {
309
+ 0% { transform: rotate(0deg); }
310
+ 100% { transform: rotate(360deg); }
311
+ }
312
+
313
+ .ai-error {
314
+ color: #dc3545;
315
+ padding: 10px;
316
+ background-color: #f8d7da;
317
+ border-radius: 4px;
318
+ margin: 10px 0;
319
+ }
320
+
321
+ .ai-recommendations {
322
+ margin: 20px 0;
323
+ }
324
+
325
+ .recommendation-item {
326
+ margin-bottom: 20px;
327
+ padding: 15px;
328
+ background-color: #f8f9fa;
329
+ border-radius: 6px;
330
+ border-left: 4px solid #007acc;
331
+ }
332
+
333
+ .recommendation-item label {
334
+ display: block;
335
+ font-weight: bold;
336
+ margin-bottom: 8px;
337
+ cursor: pointer;
338
+ }
339
+
340
+ .recommendation-item input[type="checkbox"] {
341
+ margin-right: 8px;
342
+ accent-color: #007acc;
343
+ }
344
+
345
+ .recommendation-item label {
346
+ display: flex;
347
+ align-items: center;
348
+ cursor: pointer;
349
+ padding: 5px;
350
+ border-radius: 4px;
351
+ transition: background-color 0.2s;
352
+ }
353
+
354
+ .recommendation-item label:hover {
355
+ background-color: #f0f8ff;
356
+ }
357
+
358
+ .recommendation-content {
359
+ margin-left: 20px;
360
+ }
361
+
362
+ .current-value {
363
+ color: #666;
364
+ font-size: 0.9em;
365
+ margin-bottom: 5px;
366
+ }
367
+
368
+ .suggested-value {
369
+ color: #007acc;
370
+ font-weight: 500;
371
+ line-height: 1.4;
372
+ }
373
+
374
+ .modal-actions {
375
+ display: flex;
376
+ gap: 10px;
377
+ justify-content: flex-end;
378
+ margin-top: 20px;
379
+ padding-top: 15px;
380
+ border-top: 1px solid #dee2e6;
381
+ }
382
+
383
+ .modal-actions button {
384
+ padding: 8px 16px;
385
+ border: 1px solid #dee2e6;
386
+ border-radius: 4px;
387
+ background-color: #fff;
388
+ cursor: pointer;
389
+ font-size: 14px;
390
+ }
391
+
392
+ .modal-actions button:hover {
393
+ background-color: #f8f9fa;
394
+ }
395
+
396
+ .accept-button {
397
+ background-color: #28a745 !important;
398
+ color: white !important;
399
+ border-color: #28a745 !important;
400
+ }
401
+
402
+ .accept-button:hover {
403
+ background-color: #218838 !important;
404
+ }
405
+
406
+ .accept-button:disabled {
407
+ background-color: #6c757d !important;
408
+ border-color: #6c757d !important;
409
+ cursor: not-allowed;
410
+ color: white !important;
411
+ }
412
+
413
+ /* Route management buttons */
414
+ .route-buttons {
415
+ display: flex;
416
+ gap: 8px;
417
+ margin-top: 10px;
418
+ }
419
+
420
+ .route-button {
421
+ min-height: 32px;
422
+ display: inline-flex;
423
+ align-items: center;
424
+ gap: 4px;
425
+ padding: 6px 12px;
426
+ border: 1px solid #ced4da;
427
+ border-radius: 4px;
428
+ background-color: #fff;
429
+ color: #495057;
430
+ font-size: 14px;
431
+ cursor: pointer;
432
+ transition: all 0.2s ease;
433
+ }
434
+
435
+ .route-button:hover {
436
+ background-color: #f8f9fa;
437
+ border-color: #adb5bd;
438
+ }
439
+
440
+ .route-button.ai-recommend {
441
+ background-color: #4285f4;
442
+ color: #fff;
443
+ border-color: #4285f4;
444
+ }
445
+
446
+ .route-button.ai-recommend:hover {
447
+ background-color: #3367d6;
448
+ border-color: #3367d6;
449
+ }
450
+
451
+ .route-button.remove {
452
+ background-color: #dc3545;
453
+ color: #fff;
454
+ border-color: #dc3545;
455
+ }
456
+
457
+ .route-button.remove:hover {
458
+ background-color: #c82333;
459
+ border-color: #c82333;
460
+ }
461
+
462
+ .ai-icon {
463
+ font-size: 14px;
464
+ font-weight: bold;
465
+ color: #fff;
466
+ }