@pixelated-tech/components 3.4.2 → 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 (235) hide show
  1. package/README.md +32 -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/seo-metrics.config.json +111 -0
  5. package/dist/components/admin/site-health/site-health-accessibility.js +5 -1
  6. package/dist/components/admin/site-health/site-health-axe-core.js +4 -0
  7. package/dist/components/admin/site-health/site-health-cloudwatch.integration.js +0 -5
  8. package/dist/components/admin/site-health/site-health-cloudwatch.js +7 -1
  9. package/dist/components/admin/site-health/site-health-dependency-vulnerabilities.js +4 -0
  10. package/dist/components/admin/site-health/site-health-github.js +6 -0
  11. package/dist/components/admin/site-health/site-health-google-analytics.js +6 -0
  12. package/dist/components/admin/site-health/site-health-google-search-console.js +6 -0
  13. package/dist/components/admin/site-health/site-health-on-site-seo.integration.js +379 -12
  14. package/dist/components/admin/site-health/site-health-on-site-seo.js +4 -0
  15. package/dist/components/admin/site-health/site-health-overview.js +11 -4
  16. package/dist/components/admin/site-health/site-health-performance.js +4 -0
  17. package/dist/components/admin/site-health/site-health-security.js +5 -1
  18. package/dist/components/admin/site-health/site-health-seo.js +5 -1
  19. package/dist/components/admin/site-health/site-health-template.js +19 -9
  20. package/dist/components/admin/site-health/site-health-uptime.js +4 -0
  21. package/dist/components/callout/callout.js +0 -10
  22. package/dist/components/carousel/carousel.js +15 -4
  23. package/dist/components/carousel/tiles.js +1 -1
  24. package/dist/components/cms/contentful.items.components.js +3 -4
  25. package/dist/components/cms/flickr.js +1 -1
  26. package/dist/components/cms/google.reviews.components.js +3 -3
  27. package/dist/components/cms/instagram.components.js +15 -5
  28. package/dist/components/cms/smartimage.js +2 -2
  29. package/dist/components/cms/wordpress.components.js +32 -6
  30. package/dist/components/cms/yelp.js +5 -0
  31. package/dist/components/config/config.server.js +7 -1
  32. package/dist/components/general/css.js +0 -1
  33. package/dist/components/general/image.js +0 -1
  34. package/dist/components/general/loading.js +2 -1
  35. package/dist/components/general/microinteractions.js +0 -1
  36. package/dist/components/general/modal.css +2 -4
  37. package/dist/components/general/modal.js +72 -30
  38. package/dist/components/general/sidepanel.js +16 -0
  39. package/dist/components/general/tab.js +1 -0
  40. package/dist/components/menu/menu-accordion.css +1 -1
  41. package/dist/components/menu/menu-accordion.js +15 -4
  42. package/dist/components/menu/menu-expando.js +21 -19
  43. package/dist/components/menu/menu-simple.js +14 -14
  44. package/dist/components/nerdjoke/nerdjoke.js +1 -1
  45. package/dist/components/seo/googlesearch.js +0 -1
  46. package/dist/components/seo/schema-blogposting.js +6 -1
  47. package/dist/components/seo/schema-recipe.js +34 -1
  48. package/dist/components/seo/schema-services.js +20 -2
  49. package/dist/components/shoppingcart/ebay.components.js +3 -3
  50. package/dist/components/shoppingcart/shoppingcart.components.js +76 -28
  51. package/dist/components/shoppingcart/shoppingcart.functions.js +4 -4
  52. package/dist/components/sitebuilder/config/CompoundFontSelector.js +13 -4
  53. package/dist/components/sitebuilder/config/ConfigBuilder.css +194 -5
  54. package/dist/components/sitebuilder/config/ConfigBuilder.js +183 -17
  55. package/dist/components/sitebuilder/config/FontSelector.js +13 -2
  56. package/dist/components/sitebuilder/config/routes-form.json +67 -0
  57. package/dist/components/sitebuilder/config/siteinfo-form.json +28 -14
  58. package/dist/components/sitebuilder/config/visualdesignform.json +4 -4
  59. package/dist/components/sitebuilder/form/formbuilder.js +1 -0
  60. package/dist/components/sitebuilder/form/formcomponents.js +2 -3
  61. package/dist/components/sitebuilder/form/formengine.js +6 -5
  62. package/dist/components/sitebuilder/form/formvalidator.js +5 -0
  63. package/dist/components/sitebuilder/page/components/PageBuilderUI.js +5 -1
  64. package/dist/components/structured/buzzwordbingo.css +0 -1
  65. package/dist/components/structured/recipe.js +1 -1
  66. package/dist/components/structured/socialcard.js +2 -2
  67. package/dist/components/utilities/functions.js +82 -1
  68. package/dist/components/utilities/gemini-api.client.js +76 -0
  69. package/dist/components/utilities/gemini-api.server.js +185 -0
  70. package/dist/data/routes.json +5 -5
  71. package/dist/index.adminclient.js +30 -0
  72. package/dist/index.adminserver.js +21 -0
  73. package/dist/index.js +4 -18
  74. package/dist/index.server.js +15 -28
  75. package/dist/types/components/admin/componentusage/componentAnalysis.d.ts.map +1 -1
  76. package/dist/types/components/admin/componentusage/componentDiscovery.d.ts +1 -1
  77. package/dist/types/components/admin/componentusage/componentDiscovery.d.ts.map +1 -1
  78. package/dist/types/components/admin/site-health/site-health-accessibility.d.ts +7 -4
  79. package/dist/types/components/admin/site-health/site-health-accessibility.d.ts.map +1 -1
  80. package/dist/types/components/admin/site-health/site-health-axe-core.d.ts +7 -4
  81. package/dist/types/components/admin/site-health/site-health-axe-core.d.ts.map +1 -1
  82. package/dist/types/components/admin/site-health/site-health-cloudwatch.d.ts +9 -6
  83. package/dist/types/components/admin/site-health/site-health-cloudwatch.d.ts.map +1 -1
  84. package/dist/types/components/admin/site-health/site-health-cloudwatch.integration.d.ts.map +1 -1
  85. package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts +7 -4
  86. package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts.map +1 -1
  87. package/dist/types/components/admin/site-health/site-health-github.d.ts +9 -6
  88. package/dist/types/components/admin/site-health/site-health-github.d.ts.map +1 -1
  89. package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts +9 -6
  90. package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts.map +1 -1
  91. package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts +9 -6
  92. package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts.map +1 -1
  93. package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts +8 -3
  94. package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts.map +1 -1
  95. package/dist/types/components/admin/site-health/site-health-on-site-seo.integration.d.ts.map +1 -1
  96. package/dist/types/components/admin/site-health/site-health-overview.d.ts +7 -4
  97. package/dist/types/components/admin/site-health/site-health-overview.d.ts.map +1 -1
  98. package/dist/types/components/admin/site-health/site-health-performance.d.ts +7 -4
  99. package/dist/types/components/admin/site-health/site-health-performance.d.ts.map +1 -1
  100. package/dist/types/components/admin/site-health/site-health-security.d.ts +7 -4
  101. package/dist/types/components/admin/site-health/site-health-security.d.ts.map +1 -1
  102. package/dist/types/components/admin/site-health/site-health-seo.d.ts +7 -4
  103. package/dist/types/components/admin/site-health/site-health-seo.d.ts.map +1 -1
  104. package/dist/types/components/admin/site-health/site-health-template.d.ts +12 -10
  105. package/dist/types/components/admin/site-health/site-health-template.d.ts.map +1 -1
  106. package/dist/types/components/admin/site-health/site-health-uptime.d.ts +7 -4
  107. package/dist/types/components/admin/site-health/site-health-uptime.d.ts.map +1 -1
  108. package/dist/types/components/callout/callout.d.ts +3 -3
  109. package/dist/types/components/callout/callout.d.ts.map +1 -1
  110. package/dist/types/components/carousel/carousel.d.ts +16 -7
  111. package/dist/types/components/carousel/carousel.d.ts.map +1 -1
  112. package/dist/types/components/carousel/tiles.d.ts +3 -6
  113. package/dist/types/components/carousel/tiles.d.ts.map +1 -1
  114. package/dist/types/components/cms/flickr.d.ts +3 -6
  115. package/dist/types/components/cms/flickr.d.ts.map +1 -1
  116. package/dist/types/components/cms/google.reviews.components.d.ts +1 -7
  117. package/dist/types/components/cms/google.reviews.components.d.ts.map +1 -1
  118. package/dist/types/components/cms/hubspot.components.d.ts +1 -2
  119. package/dist/types/components/cms/hubspot.components.d.ts.map +1 -1
  120. package/dist/types/components/cms/instagram.components.d.ts +14 -9
  121. package/dist/types/components/cms/instagram.components.d.ts.map +1 -1
  122. package/dist/types/components/cms/smartimage.d.ts +2 -28
  123. package/dist/types/components/cms/smartimage.d.ts.map +1 -1
  124. package/dist/types/components/cms/wordpress.components.d.ts +33 -14
  125. package/dist/types/components/cms/wordpress.components.d.ts.map +1 -1
  126. package/dist/types/components/cms/yelp.d.ts +9 -4
  127. package/dist/types/components/cms/yelp.d.ts.map +1 -1
  128. package/dist/types/components/config/config.server.d.ts +9 -6
  129. package/dist/types/components/config/config.server.d.ts.map +1 -1
  130. package/dist/types/components/general/loading.d.ts +5 -1
  131. package/dist/types/components/general/loading.d.ts.map +1 -1
  132. package/dist/types/components/general/microinteractions.d.ts +1 -3
  133. package/dist/types/components/general/microinteractions.d.ts.map +1 -1
  134. package/dist/types/components/general/modal.d.ts +11 -5
  135. package/dist/types/components/general/modal.d.ts.map +1 -1
  136. package/dist/types/components/general/semantic.d.ts +3 -3
  137. package/dist/types/components/general/sidepanel.d.ts +20 -13
  138. package/dist/types/components/general/sidepanel.d.ts.map +1 -1
  139. package/dist/types/components/general/tab.d.ts +1 -2
  140. package/dist/types/components/general/tab.d.ts.map +1 -1
  141. package/dist/types/components/menu/menu-accordion.d.ts +22 -9
  142. package/dist/types/components/menu/menu-accordion.d.ts.map +1 -1
  143. package/dist/types/components/menu/menu-expando.d.ts +14 -5
  144. package/dist/types/components/menu/menu-expando.d.ts.map +1 -1
  145. package/dist/types/components/menu/menu-simple.d.ts +4 -5
  146. package/dist/types/components/menu/menu-simple.d.ts.map +1 -1
  147. package/dist/types/components/nerdjoke/nerdjoke.d.ts +1 -1
  148. package/dist/types/components/nerdjoke/nerdjoke.d.ts.map +1 -1
  149. package/dist/types/components/seo/googleanalytics.d.ts.map +1 -1
  150. package/dist/types/components/seo/metadata.components.d.ts +2 -2
  151. package/dist/types/components/seo/metadata.components.d.ts.map +1 -1
  152. package/dist/types/components/seo/schema-blogposting.d.ts +7 -4
  153. package/dist/types/components/seo/schema-blogposting.d.ts.map +1 -1
  154. package/dist/types/components/seo/schema-recipe.d.ts +29 -30
  155. package/dist/types/components/seo/schema-recipe.d.ts.map +1 -1
  156. package/dist/types/components/seo/schema-services.d.ts +19 -9
  157. package/dist/types/components/seo/schema-services.d.ts.map +1 -1
  158. package/dist/types/components/shoppingcart/paypal.d.ts +1 -1
  159. package/dist/types/components/shoppingcart/paypal.d.ts.map +1 -1
  160. package/dist/types/components/shoppingcart/shoppingcart.components.d.ts +77 -28
  161. package/dist/types/components/shoppingcart/shoppingcart.components.d.ts.map +1 -1
  162. package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts +4 -23
  163. package/dist/types/components/shoppingcart/shoppingcart.functions.d.ts.map +1 -1
  164. package/dist/types/components/sitebuilder/config/CompoundFontSelector.d.ts +10 -11
  165. package/dist/types/components/sitebuilder/config/CompoundFontSelector.d.ts.map +1 -1
  166. package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts +41 -174
  167. package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts.map +1 -1
  168. package/dist/types/components/sitebuilder/config/FontSelector.d.ts +12 -13
  169. package/dist/types/components/sitebuilder/config/FontSelector.d.ts.map +1 -1
  170. package/dist/types/components/sitebuilder/form/formbuilder.d.ts +7 -3
  171. package/dist/types/components/sitebuilder/form/formbuilder.d.ts.map +1 -1
  172. package/dist/types/components/sitebuilder/form/formcomponents.d.ts +1 -1
  173. package/dist/types/components/sitebuilder/form/formcomponents.d.ts.map +1 -1
  174. package/dist/types/components/sitebuilder/form/formengine.d.ts +1 -2
  175. package/dist/types/components/sitebuilder/form/formengine.d.ts.map +1 -1
  176. package/dist/types/components/sitebuilder/form/formextractor.d.ts +5 -4
  177. package/dist/types/components/sitebuilder/form/formextractor.d.ts.map +1 -1
  178. package/dist/types/components/sitebuilder/form/formtypes.d.ts +3 -3
  179. package/dist/types/components/sitebuilder/form/formtypes.d.ts.map +1 -1
  180. package/dist/types/components/sitebuilder/form/formvalidator.d.ts +8 -3
  181. package/dist/types/components/sitebuilder/form/formvalidator.d.ts.map +1 -1
  182. package/dist/types/components/sitebuilder/page/components/ComponentPropertiesForm.d.ts +2 -3
  183. package/dist/types/components/sitebuilder/page/components/ComponentPropertiesForm.d.ts.map +1 -1
  184. package/dist/types/components/sitebuilder/page/components/ComponentSelector.d.ts +2 -3
  185. package/dist/types/components/sitebuilder/page/components/ComponentSelector.d.ts.map +1 -1
  186. package/dist/types/components/sitebuilder/page/components/ComponentTree.d.ts +2 -3
  187. package/dist/types/components/sitebuilder/page/components/ComponentTree.d.ts.map +1 -1
  188. package/dist/types/components/sitebuilder/page/components/PageBuilderUI.d.ts +8 -7
  189. package/dist/types/components/sitebuilder/page/components/PageBuilderUI.d.ts.map +1 -1
  190. package/dist/types/components/sitebuilder/page/components/PageEngine.d.ts.map +1 -1
  191. package/dist/types/components/sitebuilder/page/components/SaveLoadSection.d.ts +2 -3
  192. package/dist/types/components/sitebuilder/page/components/SaveLoadSection.d.ts.map +1 -1
  193. package/dist/types/components/sitebuilder/page/lib/componentMap.d.ts +1 -1
  194. package/dist/types/components/structured/markdown.d.ts +1 -3
  195. package/dist/types/components/structured/markdown.d.ts.map +1 -1
  196. package/dist/types/components/structured/recipe.d.ts +5 -32
  197. package/dist/types/components/structured/recipe.d.ts.map +1 -1
  198. package/dist/types/components/structured/socialcard.d.ts +4 -0
  199. package/dist/types/components/structured/socialcard.d.ts.map +1 -1
  200. package/dist/types/components/structured/timeline.d.ts +1 -3
  201. package/dist/types/components/structured/timeline.d.ts.map +1 -1
  202. package/dist/types/components/utilities/functions.d.ts +20 -0
  203. package/dist/types/components/utilities/functions.d.ts.map +1 -1
  204. package/dist/types/components/utilities/gemini-api.client.d.ts +38 -0
  205. package/dist/types/components/utilities/gemini-api.client.d.ts.map +1 -0
  206. package/dist/types/components/utilities/gemini-api.server.d.ts +17 -0
  207. package/dist/types/components/utilities/gemini-api.server.d.ts.map +1 -0
  208. package/dist/types/index.adminclient.d.ts +27 -0
  209. package/dist/types/index.adminclient.d.ts.map +1 -0
  210. package/dist/types/index.adminserver.d.ts +19 -0
  211. package/dist/types/index.adminserver.d.ts.map +1 -0
  212. package/dist/types/index.d.ts +4 -18
  213. package/dist/types/index.server.d.ts +5 -28
  214. package/dist/types/stories/admin/site-health.stories.d.ts +4 -0
  215. package/dist/types/stories/admin/site-health.stories.d.ts.map +1 -1
  216. package/dist/types/stories/general/sidepanel.stories.d.ts.map +1 -1
  217. package/dist/types/stories/general/smartimage.stories.d.ts +74 -2
  218. package/dist/types/stories/general/smartimage.stories.d.ts.map +1 -1
  219. package/dist/types/tests/site-health-cloudwatch.test.d.ts +2 -0
  220. package/dist/types/tests/site-health-cloudwatch.test.d.ts.map +1 -0
  221. package/dist/types/tests/site-health-on-site-seo.integration.test.d.ts +2 -0
  222. package/dist/types/tests/site-health-on-site-seo.integration.test.d.ts.map +1 -0
  223. package/package.json +20 -10
  224. package/README.COMPONENTS.md +0 -2162
  225. package/dist/components/cms/pixelated.linkedin.js +0 -180
  226. package/dist/components/cms/pixelated.linkedin1.js +0 -84
  227. package/dist/components/cms/pixelated.linkedin2.js +0 -92
  228. package/dist/types/components/cms/pixelated.linkedin.d.ts +0 -2
  229. package/dist/types/components/cms/pixelated.linkedin.d.ts.map +0 -1
  230. package/dist/types/components/cms/pixelated.linkedin1.d.ts +0 -2
  231. package/dist/types/components/cms/pixelated.linkedin1.d.ts.map +0 -1
  232. package/dist/types/components/cms/pixelated.linkedin2.d.ts +0 -2
  233. package/dist/types/components/cms/pixelated.linkedin2.d.ts.map +0 -1
  234. package/dist/types/tests/pixelated.menu-expando.test.d.ts +0 -2
  235. package/dist/types/tests/pixelated.menu-expando.test.d.ts.map +0 -1
package/README.md CHANGED
@@ -165,6 +165,8 @@ User interface and interaction components:
165
165
  - **Menu** - Navigation components (Simple, Accordion, Expando)
166
166
  - **Tab** - Tabbed interface component for organizing content
167
167
  - **Tiles** - Image grid and tile layouts
168
+ - **FontSelector** - Font selection and Google Fonts integration
169
+ - **CompoundFontSelector** - Advanced font selection with multiple font families
168
170
 
169
171
  ### Development Tools
170
172
  Components for development, configuration, and site building:
@@ -172,6 +174,7 @@ Components for development, configuration, and site building:
172
174
  - **ComponentSelector** - Component selection interface
173
175
  - **ComponentTree** - Visual component hierarchy display
174
176
  - **ConfigBuilder** - Interactive configuration builder for site settings, metadata, routes, and visual design tokens
177
+ - **ConfigEngine** - Configuration processing and validation engine
175
178
  - **PageBuilderUI** - User interface for page building
176
179
  - **SaveLoadSection** - Save and load functionality for configurations
177
180
 
@@ -213,6 +216,23 @@ External service integrations:
213
216
  - **Yelp** - Business reviews and ratings
214
217
 
215
218
 
219
+ ### Site Health & Monitoring
220
+ Comprehensive site health monitoring and analytics:
221
+ - **SiteHealthOverview** - Dashboard overview of site health metrics
222
+ - **SiteHealthPerformance** - Performance monitoring and optimization insights
223
+ - **SiteHealthAccessibility** - Accessibility compliance testing with axe-core
224
+ - **SiteHealthSecurity** - Security vulnerability scanning and recommendations
225
+ - **SiteHealthSEO** - On-page SEO analysis and scoring
226
+ - **SiteHealthOnSiteSEO** - Advanced on-page SEO metrics (browser caching, gzip compression, mobile-first indexing, etc.)
227
+ - **SiteHealthGoogleAnalytics** - Google Analytics data integration
228
+ - **SiteHealthGoogleSearchConsole** - Google Search Console integration
229
+ - **SiteHealthCloudwatch** - AWS CloudWatch uptime monitoring
230
+ - **SiteHealthGit** - Git repository health and status
231
+ - **SiteHealthUptime** - Uptime monitoring and alerts
232
+ - **SiteHealthAxeCore** - Automated accessibility testing
233
+ - **SiteHealthDependencyVulnerabilities** - Dependency security scanning
234
+
235
+
216
236
  ## 🎨 Visual Design Configuration
217
237
 
218
238
  The ConfigBuilder now includes a **Visual Design** tab that allows users to configure visual design tokens such as colors, fonts, spacing, and other design system variables. These tokens are stored in the `routes.json` file under the `visualdesign` object and can be used throughout your application for consistent theming.
@@ -248,7 +268,7 @@ npm install @pixelated-tech/components
248
268
  import { Accordion, Callout } from '@pixelated-tech/components';
249
269
  ```
250
270
 
251
- For detailed usage examples and API documentation, see the [Component Reference Guide](README.COMPONENTS.md).
271
+ For detailed usage examples and API documentation, see the [Component Reference Guide](docs/components.md).
252
272
 
253
273
  ### Storybook Interactive Demos
254
274
 
@@ -262,72 +282,22 @@ npm run storybook
262
282
  **Access locally at:** `http://localhost:6006`
263
283
 
264
284
 
285
+ See the [open issues](https://github.com/brianwhaley/pixelated-components/issues) for a full list of proposed features (and known issues).
286
+
287
+
288
+
289
+
290
+
265
291
  <!-- ROADMAP -->
266
- ## Roadmap
267
-
268
- ### New Components
269
- - [ ] **IN PROGRESS** - Testimonial Block (Nextdoor/Yelp/Google): ingest review feeds + render carousel/grid.
270
- - [ ] **ON HOLD** LinkedIn Recommendations Integration (Not possible with current LinkedIn API)
271
- - [ ] **ON HOLD** eBay Feedback Integration - requires user OAuth login
272
- - [ ] **ON HOLD** Yelp Recommendations integration (Cost Prohibitive)
273
- - [ ] Instagram Image Integration for Carousels
274
- - [ ] Shopify Integration
275
- - [ ] Quickbooks Integration
276
- - [ ] Buffer Integration (or Sendible, Sprout Social, Hootsuite)
277
- - [ ] Zapier Integration
278
- - [ ] Hero Banner: headline, subtext, CTA, background image/video, overlay.
279
- - [ ] Accessibility Enhancer: wrapper component that automatically improves accessibility across Pixelated sites by adding ARIA labels, roles, and states to existing components. Includes color contrast checking, keyboard navigation helpers, alt-text suggestions for images, and automated accessibility audits.
280
- - [ ] SEO Dashboard with AI Integration: component that analyzes site content, suggests optimizations, integrates with AI for meta descriptions and keyword research.
281
-
282
- ### CI / CD Improvements
283
- - [ ] Add CI workflow to run tests and lints on pull requests.
284
-
285
- ### Component Improvements
286
- - [ ] Implement minimal `createContentfulImageURLs` with single `/images` sitemap entry.
287
- - [ ] Review Contentful helper functions for per-page mapping capability.
288
- - [ ] Implement `createContentfulImageURLs` per-page mapping with `contentType` & `pageField` config.
289
- - [ ] Align typography to `--font-sizeN` clamp variables.
290
- - [ ] Provide Cloudinary transforms presets for image components.
291
- - [ ] find a better solution than to generate image via build script in amplify for json for sitemap creation
292
- - [ ] **SocialCards Component**: Fix state initialization to track prop changes properly.
293
- - [ ] **Modal Component**: Clarify content source pattern (accepts both `modalContent` and `children`).
294
- - [ ] **Carousel Component**: Fix active card state reset when `props.cards` changes.
295
- - [ ] **NerdJoke Component**: Add props to useEffect dependencies if endpoint becomes configurable.
296
- - [ ] **GoogleReviews Component**: Add carousel/grid display modes.
297
- - [ ] **GoogleReviews Component**: Add API key to config provider instead of hardcoding.
298
- - [ ] **Instagram Component**: Add accessToken and userId to config provider for centralized API credentials.
299
- - [ ] **Critters Integration**: Explore adding critters CSS inlining tool for improved page load performance and critical CSS optimization.
300
-
301
- ### Platform Enhancements
302
- - [ ] **Project Scaffolding CLI**: Interactive CLI tool that generates complete Next.js projects with pixelated-components pre-configured, including routes.json, layout.tsx, package.json, and basic page structure
303
- - [ ] **Template Marketplace**: Pre-built industry-specific templates (restaurant, law firm, contractor, etc.) that users can clone and customize
304
- - [ ] **Configuration Wizard**: Step-by-step setup wizard that collects business info, generates site configuration, and creates initial content structure
305
- - [ IP ] **Site Health Monitoring**: Automated monitoring dashboard that checks site performance, broken links, SEO scores, and security vulnerabilities across all sites
306
- - [ ] **Content Migration Tools**: Automated importers for WordPress, Squarespace, Wix, and other platforms to migrate content to pixelated sites
307
- - [ ] **A/B Testing Framework**: Built-in experimentation system for testing different layouts, content, and CTAs with automatic winner selection
308
- - [ ] **Personalization Engine**: Dynamic content delivery based on user behavior, location, and preferences
309
- - [ ] **Hot Module Replacement for Configs**: Live preview of configuration changes without full rebuilds
310
- - [ ] **Automated Dependency Updates**: Smart update system that tests component changes across all sites before deployment
311
- - [ ] **Rollback System**: One-click rollback to previous versions with automatic database and asset restoration
312
- - [ ] **Performance Budget Tracker**: Automated monitoring of Core Web Vitals with alerts when sites exceed performance budgets
313
- - [ ] **ConfigBuilder SEO Enhancement**: Upgrade ConfigBuilder with AI-powered meta description generation, keyword optimization suggestions, and automated schema markup
314
- - [ ] **Conversion Funnel Builder**: Visual funnel creation with automated tracking, A/B testing, and optimization recommendations
315
- - [ ] **Automated Security Scanner**: Regular security audits with vulnerability detection and automated fixes
316
- - [ ] **GDPR Compliance Toolkit**: Automated cookie consent, data mapping, and privacy policy generation
317
- - [ ] **API Gateway**: Unified API management for connecting to CRM, email marketing, payment processors, and other business tools
318
- - [ ] **Webhook Automation**: Event-driven automation for form submissions, new content, user registrations, and business workflows
319
- - [ ] **Third-Party Sync Engine**: Bidirectional sync with tools like HubSpot, Mailchimp, QuickBooks, and project management systems
320
- - [ ] **Testing Strategy for Config Failure Scenarios**: Comprehensive testing framework for config-dependent components and error handling
321
- - Test components with missing config providers
322
- - Test error pages without config dependencies
323
- - Test app initialization with invalid environment variables
324
- - Include chaos engineering tests that simulate config failures
325
- - [ ] **Documentation Auto-Generator**: Automatically generated API docs, component usage guides, and deployment instructions
292
+ ## 🚀 Roadmap
326
293
 
294
+ See our detailed [Roadmap](docs/roadmap.md) for planned improvements and refactoring initiatives.
327
295
 
328
- See the [open issues](https://github.com/brianwhaley/pixelated-components/issues) for a full list of proposed features (and known issues).
329
296
 
297
+ <!-- TESTING -->
298
+ ## 🧪 Testing
330
299
 
300
+ See our comprehensive [Testing Documentation](docs/testing.md) for test coverage, setup, and strategies.
331
301
 
332
302
 
333
303
  <!-- CONTRIBUTING -->
@@ -377,135 +347,6 @@ Project Link: [https://github.com/brianwhaley/pixelated-components](https://gith
377
347
 
378
348
 
379
349
 
380
- ## 🧪 Testing
381
-
382
- ### Overview
383
-
384
- **Current Status**: ✅ 2,370 tests passing across 77 test files
385
-
386
- | Metric | Value |
387
- |--------|-------|
388
- | Test Files | 77 |
389
- | Total Tests | 2,370 |
390
- | Coverage (Statements) | 76.98% |
391
- | Coverage (Lines) | 79.55% |
392
- | Coverage (Functions) | 78.09% |
393
- | Coverage (Branches) | 67.57% |
394
- | Test Framework | Vitest 4.x |
395
- | Testing Library | @testing-library/react + jsdom |
396
-
397
- ### Quick Start
398
-
399
- ```bash
400
- npm run test # Watch mode
401
- npm run test:ui # Interactive UI dashboard
402
- npm run test:coverage # Generate coverage reports
403
- npm run test:run # Single run (for CI)
404
- ```
405
-
406
- ### Component Coverage
407
-
408
- **Component Coverage Summary**
409
-
410
- #### Component Coverage (Sorted by Statement Coverage)
411
- - **site-health-cache.ts**: 100% statements *(new shared caching utility)*
412
- - **sites.integration.ts**: 100% statements *(new site management functions)*
413
- - **site-health-indicators.ts**: 100% statements
414
- - **tiles.tsx**: 100% statements
415
- - **google.reviews.functions.ts**: 100% statements
416
- - **accordion.tsx**: 100% statements
417
- - **modal.tsx**: 100% statements
418
- - **tab.tsx**: 100% statements
419
- - **ComponentPropertiesForm.tsx**: 100% statements
420
- - **ComponentSelector.tsx**: 100% statements
421
- - **ComponentTree.tsx**: 100% statements
422
- - **formvalidations.tsx**: 100% statements
423
- - **googlesearch.tsx**: 100% statements
424
- - **schema-localbusiness.tsx**: 100% statements
425
- - **schema-recipe.tsx**: 100% statements
426
- - **schema-services.tsx**: 100% statements
427
- - **schema-website.tsx**: 100% statements
428
- - **schema-blogposting.tsx**: 100% statements
429
- - **buzzwordbingo.tsx**: 100% statements
430
- - **markdown.tsx**: 100% statements
431
- - **timeline.tsx**: 100% statements
432
- - **sidepanel.tsx**: 97.5% statements
433
- - **config.server.tsx**: 50% statements
434
- - **config.ts**: 96.55% statements
435
- - **google.reviews.components.tsx**: 95.83% statements
436
- - **schema-blogposting.tsx**: 95.24% statements
437
- - **recipe.tsx**: 94.59% statements
438
- - **resume.tsx**: 94.38% statements
439
- - **contentful.delivery.ts**: 92.5% statements
440
- - **css.tsx**: 91.43% statements
441
- - **functions.ts**: 90.91% statements
442
- - **menu-expando.tsx**: 90.12% statements
443
- - **config.client.tsx**: 100% statements
444
- - **loading.tsx**: 85.71% statements
445
- - **SaveLoadSection.tsx**: 84.85% statements
446
- - **table.tsx**: 84.48% statements
447
- - **ConfigBuilder.tsx**: 83.52% statements
448
- - **cloudinary.ts**: 83.33% statements
449
- - **formcomponents.tsx**: 83.33% statements
450
- - **form.tsx**: 83.2% statements
451
- - **shoppingcart.functions.ts**: 81.7% statements
452
- - **callout.tsx**: 80% statements
453
- - **microinteractions.tsx**: 80% statements
454
- - **smartimage.tsx**: 82.75% statements
455
- - **sitemap.ts**: 76.06% statements
456
- - **manifest.tsx**: 75% statements
457
- - **carousel.tsx**: 71.7% statements
458
- - **nerdjoke.tsx**: 69.44% statements
459
- - **menu-accordion.tsx**: 68.47% statements
460
- - **semantic.tsx**: 63.51% statements
461
- - **componentMap.tsx**: 60% statements
462
- - **propTypeIntrospection.tsx**: 60% statements
463
- - **wordpress.functions.ts**: 51.43% statements
464
- - **PageEngine.tsx**: 48% statements
465
- - **componentGeneration.tsx**: 38.89% statements
466
- - **socialcard.tsx**: 29.51% statements
467
- - **PageBuilderUI.tsx**: 26.67% statements
468
-
469
- ### Testing Next Steps
470
-
471
- #### Integration Testing Gaps
472
- - [ ] **Cross-component interactions** - Test how components work together (e.g., forms with validation, carousels with loading states)
473
- - [ ] **Form validation edge cases** - Test URL validation, required fields, and complex validation rules under various conditions
474
- - [ ] **CMS API integrations** - Test API failures, rate limiting, authentication errors, and network timeouts
475
- - [ ] **Responsive design breakpoints** - Test component behavior across different screen sizes and device types
476
- - [ ] **Accessibility (a11y) compliance** - Test keyboard navigation, screen reader compatibility, and ARIA attributes
477
-
478
- ### Test Configuration
479
-
480
-
481
- **Coverage Targets** (configured in `vitest.config.ts`):
482
- - **Statements**: 70% threshold
483
- - **Lines**: 70% threshold
484
- - **Functions**: 70% threshold
485
- - **Branches**: 60% threshold
486
-
487
- **Coverage Thresholds in vitest.config.ts**:
488
- - Lines: 70% threshold
489
- - Functions: 70% threshold
490
- - Branches: 60% threshold
491
- - Statements: 70% threshold
492
-
493
- **Test Environment**: jsdom with @testing-library/react
494
- **Test Pattern**: Data-focused validation + behavioral testing
495
-
496
- ### Tools & Dependencies
497
-
498
- | Tool | Purpose |
499
- |------|---------|
500
- | Vitest 4.x | Test runner |
501
- | @testing-library/react | Component testing utilities |
502
- | jsdom | DOM environment for tests |
503
- | v8 | Coverage reporting |
504
-
505
-
506
-
507
-
508
-
509
350
  <!-- MARKDOWN LINKS & IMAGES -->
510
351
  <!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
511
352
  [contributors-shield]: https://img.shields.io/github/contributors/brianwhaley/pixelated-components.svg?style=for-the-badge
@@ -71,13 +71,17 @@ export async function checkComponentUsage(sitePath, componentName) {
71
71
  ];
72
72
  for (const file of files) {
73
73
  const content = await fs.readFile(file, 'utf-8');
74
- if (content.includes('@pixelated-tech/components')) {
74
+ if (content.includes('@pixelated-tech/components') ||
75
+ content.includes('@pixelated-tech/components/adminclient') ||
76
+ content.includes('@pixelated-tech/components/adminserver')) {
75
77
  // Check if any semantic export is imported (case insensitive)
76
78
  for (const exportName of semanticExports) {
77
79
  const contentLower = content.toLowerCase();
78
80
  const exportNameLower = exportName.toLowerCase();
79
81
  if (contentLower.includes(exportNameLower) ||
80
- new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components`, 'i').test(content)) {
82
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components`, 'i').test(content) ||
83
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components/adminclient`, 'i').test(content) ||
84
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components/adminserver`, 'i').test(content)) {
81
85
  return true;
82
86
  }
83
87
  }
@@ -92,9 +96,13 @@ export async function checkComponentUsage(sitePath, componentName) {
92
96
  // Check for import statements - look for the actual export name (case insensitive)
93
97
  const contentLower = content.toLowerCase();
94
98
  const exportNameLower = exportName.toLowerCase();
95
- if (content.includes('@pixelated-tech/components') &&
99
+ if ((content.includes('@pixelated-tech/components') ||
100
+ content.includes('@pixelated-tech/components/adminclient') ||
101
+ content.includes('@pixelated-tech/components/adminserver')) &&
96
102
  (contentLower.includes(exportNameLower) ||
97
- new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components`, 'i').test(content))) {
103
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components`, 'i').test(content) ||
104
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components/adminclient`, 'i').test(content) ||
105
+ new RegExp(`import.*${exportNameLower}.*from.*@pixelated-tech/components/adminserver`, 'i').test(content))) {
98
106
  return true;
99
107
  }
100
108
  }
@@ -44,19 +44,33 @@ function getPixelatedComponentsPath() {
44
44
  }
45
45
  }
46
46
  /**
47
- * Discover components dynamically by parsing the pixelated-components index
47
+ * Discover components dynamically by parsing the pixelated-components index files
48
48
  * This runs on the server side during API calls
49
49
  */
50
50
  export async function discoverComponentsFromLibrary() {
51
51
  try {
52
52
  // Get the pixelated-components package path
53
53
  const pixelatedPath = getPixelatedComponentsPath();
54
- // Look for the built dist/index.js file
54
+ const componentNames = [];
55
+ // Read from main index.js
55
56
  const indexPath = path.join(pixelatedPath, 'dist', 'index.js');
56
- // Read and parse the index.js file
57
- const indexContent = fs.readFileSync(indexPath, 'utf-8');
58
- const componentNames = parseComponentExports(indexContent);
59
- return componentNames;
57
+ if (fs.existsSync(indexPath)) {
58
+ const indexContent = fs.readFileSync(indexPath, 'utf-8');
59
+ componentNames.push(...parseComponentExports(indexContent));
60
+ }
61
+ // Read from adminclient index
62
+ const adminClientPath = path.join(pixelatedPath, 'dist', 'index.adminclient.js');
63
+ if (fs.existsSync(adminClientPath)) {
64
+ const adminClientContent = fs.readFileSync(adminClientPath, 'utf-8');
65
+ componentNames.push(...parseComponentExports(adminClientContent));
66
+ }
67
+ // Read from adminserver index
68
+ const adminServerPath = path.join(pixelatedPath, 'dist', 'index.adminserver.js');
69
+ if (fs.existsSync(adminServerPath)) {
70
+ const adminServerContent = fs.readFileSync(adminServerPath, 'utf-8');
71
+ componentNames.push(...parseComponentExports(adminServerContent));
72
+ }
73
+ return [...new Set(componentNames)].sort(); // Remove duplicates and sort alphabetically
60
74
  }
61
75
  catch (error) {
62
76
  console.error('Error in dynamic component discovery:', error);
@@ -187,6 +187,101 @@
187
187
  "countLogic": "count",
188
188
  "scoreLogic": "present",
189
189
  "displayTemplate": "{{count}} ItemProp tag(s) found"
190
+ },
191
+ "robots-meta-directives": {
192
+ "id": "robots-meta-directives",
193
+ "title": "Robots Meta Directives",
194
+ "description": "Checks for robots meta tags (noindex, nofollow, noarchive)",
195
+ "scoreDisplayMode": "binary",
196
+ "pattern": "<meta[^>]*name=[\"']robots[\"'][^>]*content=[\"'][^\"']*[\"'][^>]*>",
197
+ "countLogic": "count",
198
+ "scoreLogic": "present",
199
+ "displayTemplate": "{{count}} robots meta tag(s) found"
200
+ },
201
+ "hreflang-tags": {
202
+ "id": "hreflang-tags",
203
+ "title": "Hreflang Tags",
204
+ "description": "Checks for hreflang link tags for international SEO",
205
+ "scoreDisplayMode": "binary",
206
+ "pattern": "<link[^>]*rel=[\"']alternate[\"'][^>]*hreflang=[\"'][^\"']*[\"'][^>]*>",
207
+ "countLogic": "count",
208
+ "scoreLogic": "present",
209
+ "displayTemplate": "{{count}} hreflang link(s) found"
210
+ },
211
+ "indexability-status": {
212
+ "id": "indexability-status",
213
+ "title": "Indexability Status",
214
+ "description": "Checks for unintended noindex directives",
215
+ "scoreDisplayMode": "binary",
216
+ "pattern": "<meta[^>]*name=[\"']?robots[\"']?[^>]*content=[\"']?[^\"']*noindex[^\"']*[\"']?[^>]*>",
217
+ "countLogic": "count",
218
+ "scoreLogic": "exact",
219
+ "expectedCount": 0,
220
+ "displayTemplate": "{{count}} noindex directive(s) found"
221
+ },
222
+ "image-optimization": {
223
+ "id": "image-optimization",
224
+ "title": "Image Optimization",
225
+ "description": "Checks for lazy loading and modern image formats",
226
+ "scoreDisplayMode": "binary",
227
+ "pattern": "<img[^>]*loading=[\"']lazy[\"'][^>]*>|<img[^>]*\\.(webp|avif)[^>]*>",
228
+ "countLogic": "count",
229
+ "scoreLogic": "present",
230
+ "displayTemplate": "{{count}} optimized image(s) found"
231
+ },
232
+ "pagination-structure": {
233
+ "id": "pagination-structure",
234
+ "title": "Pagination Structure",
235
+ "description": "Checks for proper rel='next/prev' pagination links",
236
+ "scoreDisplayMode": "binary",
237
+ "pattern": "<link[^>]*rel=[\"']?(next|prev)[\"']?[^>]*href=[\"']?[^\"']*[\"']?[^>]*>",
238
+ "countLogic": "count",
239
+ "scoreLogic": "present",
240
+ "displayTemplate": "{{count}} pagination link(s) found"
241
+ },
242
+ "local-seo-elements": {
243
+ "id": "local-seo-elements",
244
+ "title": "Local SEO Elements",
245
+ "description": "Checks for local business schema markup",
246
+ "scoreDisplayMode": "binary",
247
+ "pattern": "(<script[^>]*type=[\"']application/ld\\+json[\"'][^>]*>[^<]*\"@type\"[^<]*\"LocalBusiness\"[^<]*</script>)|(<[^>]*itemtype=[\"'][^\"']*LocalBusiness[^\"']*[\"'][^>]*>)",
248
+ "countLogic": "count",
249
+ "scoreLogic": "present",
250
+ "displayTemplate": "{{count}} local business schema element(s) found"
251
+ },
252
+ "amp-validation": {
253
+ "id": "amp-validation",
254
+ "title": "AMP Validation",
255
+ "description": "Checks for Accelerated Mobile Pages implementation",
256
+ "scoreDisplayMode": "binary",
257
+ "pattern": "<html[^>]*amp[^>]*>|<script[^>]*src=[\"']?[^\"']*cdn\\.ampproject\\.org[^\"']*[\"']?[^>]*>",
258
+ "countLogic": "count",
259
+ "scoreLogic": "present",
260
+ "displayTemplate": "{{count}} AMP element(s) found"
261
+ },
262
+ "mobile-first-indexing": {
263
+ "id": "mobile-first-indexing",
264
+ "title": "Mobile-First Indexing",
265
+ "description": "Checks for mobile-friendly viewport and responsive design",
266
+ "scoreDisplayMode": "binary",
267
+ "dataCollector": "collectMobileFirstIndexingData",
268
+ "scorer": "calculateMobileFirstIndexingScore"
269
+ },
270
+ "international-seo": {
271
+ "id": "international-seo",
272
+ "title": "International SEO",
273
+ "description": "Checks for currency and locale detection elements",
274
+ "scoreDisplayMode": "binary",
275
+ "dataCollector": "collectInternationalSEOData",
276
+ "scorer": "calculateInternationalSEOData"
277
+ },
278
+ "faceted-navigation": {
279
+ "id": "faceted-navigation",
280
+ "title": "Faceted Navigation",
281
+ "description": "Checks for SEO-friendly filter and navigation URLs",
282
+ "scoreDisplayMode": "numeric",
283
+ "dataCollector": "collectFacetedNavigationData",
284
+ "scorer": "calculateFacetedNavigationScore"
190
285
  }
191
286
  }
192
287
  },
@@ -258,6 +353,22 @@
258
353
  "scoreDisplayMode": "binary",
259
354
  "dataCollector": null,
260
355
  "scorer": null
356
+ },
357
+ "gzip-compression": {
358
+ "id": "gzip-compression",
359
+ "title": "Gzip Compression",
360
+ "description": "Checks for server compression verification (requires HTTP headers analysis)",
361
+ "scoreDisplayMode": "binary",
362
+ "dataCollector": "collectGzipCompressionData",
363
+ "scorer": "calculateGzipCompressionScore"
364
+ },
365
+ "browser-caching": {
366
+ "id": "browser-caching",
367
+ "title": "Browser Caching",
368
+ "description": "Checks cache headers for static assets (requires HTTP headers analysis)",
369
+ "scoreDisplayMode": "binary",
370
+ "dataCollector": "collectBrowserCachingData",
371
+ "scorer": "calculateBrowserCachingScore"
261
372
  }
262
373
  }
263
374
  }
@@ -1,8 +1,12 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useCallback } from 'react';
4
+ import PropTypes from 'prop-types';
4
5
  import { SiteHealthTemplate } from './site-health-template';
5
6
  import { getScoreIndicator } from './site-health-indicators';
7
+ SiteHealthAccessibility.propTypes = {
8
+ siteName: PropTypes.string.isRequired,
9
+ };
6
10
  export function SiteHealthAccessibility({ siteName }) {
7
11
  const fetchAccessibilityData = useCallback(async (site) => {
8
12
  const response = await fetch(`/api/site-health/core-web-vitals?siteName=${encodeURIComponent(site)}`);
@@ -116,7 +120,7 @@ export function SiteHealthAccessibility({ siteName }) {
116
120
  width: `${(siteData.scores.accessibility || 0) * 100}%`,
117
121
  backgroundColor: getScoreColor(siteData.scores.accessibility)
118
122
  } }) })] }) })), siteData.categories.accessibility && siteData.categories.accessibility.audits.length > 0 && (_jsxs("div", { children: [_jsx("h5", { style: { fontSize: '1rem', fontWeight: '600', marginBottom: '1rem' }, children: "Accessibility Issues & Recommendations" }), _jsx("div", { className: "space-y-2", children: siteData.categories.accessibility.audits
119
- .filter(audit => audit.scoreDisplayMode !== 'notApplicable')
123
+ .filter((audit) => audit.scoreDisplayMode !== 'notApplicable')
120
124
  .sort((a, b) => {
121
125
  // Prioritize specific important accessibility audits
122
126
  const priorityAudits = [
@@ -1,8 +1,12 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useCallback } from 'react';
4
+ import PropTypes from 'prop-types';
4
5
  import { SiteHealthTemplate } from './site-health-template';
5
6
  import { getImpactIndicator, getIncompleteIndicator, getPassingIndicator } from './site-health-indicators';
7
+ SiteHealthAxeCore.propTypes = {
8
+ siteName: PropTypes.string.isRequired,
9
+ };
6
10
  export function SiteHealthAxeCore({ siteName }) {
7
11
  const fetchAxeCoreData = useCallback(async (site) => {
8
12
  const response = await fetch(`/api/site-health/axe-core?siteName=${encodeURIComponent(site)}`);
@@ -28,7 +28,6 @@ export async function getCloudwatchHealthCheckData(config, siteName, startDate,
28
28
  // Add 1 day to end time to include the full end date
29
29
  const endTimePlusOne = new Date(endTime);
30
30
  endTimePlusOne.setDate(endTimePlusOne.getDate() + 1);
31
- console.log(`CloudWatch: Fetching data for health check ${config.healthCheckId} from ${startTime.toISOString()} to ${endTimePlusOne.toISOString()}`);
32
31
  const metricDataQuery = {
33
32
  MetricDataQueries: [
34
33
  {
@@ -55,9 +54,7 @@ export async function getCloudwatchHealthCheckData(config, siteName, startDate,
55
54
  };
56
55
  const command = new GetMetricDataCommand(metricDataQuery);
57
56
  const response = await cloudWatchClient.send(command);
58
- console.log(`CloudWatch: Received ${response.MetricDataResults?.[0]?.Timestamps?.length || 0} data points`);
59
57
  if (!response.MetricDataResults || response.MetricDataResults.length === 0) {
60
- console.log(`CloudWatch: No metric data found for health check ${config.healthCheckId}`);
61
58
  return {
62
59
  success: false,
63
60
  error: 'No health check metric data found'
@@ -65,7 +62,6 @@ export async function getCloudwatchHealthCheckData(config, siteName, startDate,
65
62
  }
66
63
  const metricResult = response.MetricDataResults[0];
67
64
  if (!metricResult.Timestamps || !metricResult.Values) {
68
- console.log(`CloudWatch: No timestamps or values in metric data`);
69
65
  return {
70
66
  success: false,
71
67
  error: 'No health check metric data available'
@@ -101,7 +97,6 @@ export async function getCloudwatchHealthCheckData(config, siteName, startDate,
101
97
  };
102
98
  })
103
99
  .sort((a, b) => a.date.localeCompare(b.date));
104
- console.log(`CloudWatch: Processed ${data.length} date groups with data`);
105
100
  // Fill in the date range with data points for each day
106
101
  let filledData = [];
107
102
  if (startDate && endDate) {
@@ -1,7 +1,13 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import PropTypes from 'prop-types';
3
4
  import { ComposedChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
4
5
  import { SiteHealthTemplate } from './site-health-template';
6
+ SiteHealthCloudwatch.propTypes = {
7
+ siteName: PropTypes.string.isRequired,
8
+ startDate: PropTypes.string,
9
+ endDate: PropTypes.string,
10
+ };
5
11
  export function SiteHealthCloudwatch({ siteName, startDate, endDate }) {
6
12
  const fetchCloudwatchData = async (site) => {
7
13
  const params = new URLSearchParams({ siteName: site });
@@ -29,7 +35,7 @@ export function SiteHealthCloudwatch({ siteName, startDate, endDate }) {
29
35
  return (_jsx("div", { className: "flex items-center justify-center h-64", children: _jsx("div", { className: "text-gray-500", children: "No uptime data available. Route53 health checks may not be configured to send metrics to CloudWatch." }) }));
30
36
  }
31
37
  // Check if all data points have zero checks (no actual data)
32
- const hasActualData = data.some(point => point.totalChecks > 0);
38
+ const hasActualData = data.some((point) => point.totalChecks > 0);
33
39
  if (!hasActualData) {
34
40
  return (_jsx("div", { className: "flex items-center justify-center h-64", children: _jsxs("div", { className: "text-gray-500", children: ["Health check exists but has no metric data in CloudWatch for the selected period.", _jsx("br", {}), "Route53 health checks must be configured to send metrics to CloudWatch for historical data."] }) }));
35
41
  }
@@ -1,7 +1,11 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useCallback } from 'react';
4
+ import PropTypes from 'prop-types';
4
5
  import { SiteHealthTemplate } from './site-health-template';
6
+ SiteHealthDependencyVulnerabilities.propTypes = {
7
+ siteName: PropTypes.string.isRequired,
8
+ };
5
9
  export function SiteHealthDependencyVulnerabilities({ siteName }) {
6
10
  const fetchDependencyData = useCallback(async (site) => {
7
11
  const response = await fetch(`/api/site-health/security?siteName=${encodeURIComponent(site)}`);
@@ -1,7 +1,13 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import PropTypes from 'prop-types';
3
4
  import { Table } from '@pixelated-tech/components';
4
5
  import { SiteHealthTemplate } from './site-health-template';
6
+ SiteHealthGit.propTypes = {
7
+ siteName: PropTypes.string.isRequired,
8
+ startDate: PropTypes.string,
9
+ endDate: PropTypes.string,
10
+ };
5
11
  export function SiteHealthGit({ siteName, startDate, endDate }) {
6
12
  const fetchGitData = async (site) => {
7
13
  const params = new URLSearchParams({ site: encodeURIComponent(site) });
@@ -1,7 +1,13 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import PropTypes from 'prop-types';
3
4
  import { ComposedChart, Bar, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts';
4
5
  import { SiteHealthTemplate } from './site-health-template';
6
+ SiteHealthGoogleAnalytics.propTypes = {
7
+ siteName: PropTypes.string.isRequired,
8
+ startDate: PropTypes.string,
9
+ endDate: PropTypes.string,
10
+ };
5
11
  export function SiteHealthGoogleAnalytics({ siteName, startDate, endDate }) {
6
12
  const fetchAnalyticsData = async (site) => {
7
13
  const params = new URLSearchParams({ siteName: site });
@@ -1,7 +1,13 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import PropTypes from 'prop-types';
3
4
  import { ComposedChart, Bar, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
4
5
  import { SiteHealthTemplate } from './site-health-template';
6
+ SiteHealthGoogleSearchConsole.propTypes = {
7
+ siteName: PropTypes.string.isRequired,
8
+ startDate: PropTypes.string,
9
+ endDate: PropTypes.string,
10
+ };
5
11
  export function SiteHealthGoogleSearchConsole({ siteName, startDate, endDate }) {
6
12
  const fetchSearchConsoleData = async (site) => {
7
13
  const params = new URLSearchParams({ siteName: site });