@pixelated-tech/components 3.3.5 → 3.4.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 (158) hide show
  1. package/README.COMPONENTS.md +126 -0
  2. package/README.md +15 -9
  3. package/dist/components/admin/componentusage/componentAnalysis.js +144 -0
  4. package/dist/components/admin/componentusage/componentDiscovery.js +85 -0
  5. package/dist/components/admin/deploy/deployment.integration.js +170 -0
  6. package/dist/components/admin/site-health/google-api-auth.js +69 -0
  7. package/dist/components/admin/site-health/seo-metrics.config.json +265 -0
  8. package/dist/components/admin/site-health/site-health-accessibility.js +158 -0
  9. package/dist/components/admin/site-health/site-health-axe-core.integration.js +119 -0
  10. package/dist/components/admin/site-health/site-health-axe-core.js +53 -0
  11. package/dist/components/admin/site-health/site-health-cache.js +23 -0
  12. package/dist/components/admin/site-health/site-health-core-web-vitals.integration.js +208 -0
  13. package/dist/components/admin/site-health/site-health-dependency-vulnerabilities.js +38 -0
  14. package/dist/components/admin/site-health/site-health-github.integration.js +81 -0
  15. package/dist/components/admin/site-health/site-health-github.js +34 -0
  16. package/dist/components/admin/site-health/site-health-google-analytics.integration.js +112 -0
  17. package/dist/components/admin/site-health/site-health-google-analytics.js +43 -0
  18. package/dist/components/admin/site-health/site-health-google-search-console.integration.js +118 -0
  19. package/dist/components/admin/site-health/site-health-google-search-console.js +43 -0
  20. package/dist/components/admin/site-health/site-health-indicators.js +71 -0
  21. package/dist/components/admin/site-health/site-health-on-site-seo.integration.js +578 -0
  22. package/dist/components/admin/site-health/site-health-on-site-seo.js +204 -0
  23. package/dist/components/admin/site-health/site-health-overview.js +65 -0
  24. package/dist/components/admin/site-health/site-health-performance.js +191 -0
  25. package/dist/components/admin/site-health/site-health-security.integration.js +109 -0
  26. package/dist/components/admin/site-health/site-health-security.js +169 -0
  27. package/dist/components/admin/site-health/site-health-seo.js +124 -0
  28. package/dist/components/admin/site-health/site-health-template.js +62 -0
  29. package/dist/components/admin/site-health/site-health-types.js +1 -0
  30. package/dist/components/admin/site-health/site-health-uptime.integration.js +29 -0
  31. package/dist/components/admin/site-health/site-health-uptime.js +30 -0
  32. package/dist/components/admin/site-health/site-health.css +427 -0
  33. package/dist/components/admin/sites/sites.integration.js +117 -0
  34. package/dist/components/cms/contentful.management.js +104 -0
  35. package/dist/components/cms/hubspot.components.js +3 -3
  36. package/dist/components/config/config.client.js +21 -10
  37. package/dist/components/general/table.js +3 -1
  38. package/dist/components/seo/googleanalytics.js +1 -2
  39. package/dist/components/shoppingcart/shipping.from.json +101 -0
  40. package/dist/components/shoppingcart/shipping.parcel.json +112 -0
  41. package/dist/components/shoppingcart/shipping.to.json +422 -0
  42. package/dist/components/shoppingcart/shoppingCartDiscountCodes.json +26 -0
  43. package/dist/components/shoppingcart/shoppingcart.components.js +1 -1
  44. package/dist/components/sitebuilder/config/ConfigBuilder.js +36 -140
  45. package/dist/components/sitebuilder/config/siteinfo-form.json +200 -0
  46. package/dist/components/sitebuilder/config/visualdesignform.json +244 -0
  47. package/dist/components/structured/buzzwordbingo.js +3 -2
  48. package/dist/data/404-data.json +128 -102
  49. package/dist/data/flickr.json +25 -0
  50. package/dist/data/form.json +368 -368
  51. package/dist/data/recipes.json +3251 -3251
  52. package/dist/data/references.json +138 -137
  53. package/dist/data/requestform.json +111 -0
  54. package/dist/data/requests.json +136 -135
  55. package/dist/data/resume.json +2573 -2575
  56. package/dist/data/routes.json +238 -238
  57. package/dist/data/routes2.json +141 -140
  58. package/dist/index.js +16 -3
  59. package/dist/index.server.js +36 -15
  60. package/dist/types/components/admin/componentusage/componentAnalysis.d.ts +35 -0
  61. package/dist/types/components/admin/componentusage/componentAnalysis.d.ts.map +1 -0
  62. package/dist/types/components/admin/componentusage/componentDiscovery.d.ts +10 -0
  63. package/dist/types/components/admin/componentusage/componentDiscovery.d.ts.map +1 -0
  64. package/dist/types/components/admin/deploy/deployment.integration.d.ts +26 -0
  65. package/dist/types/components/admin/deploy/deployment.integration.d.ts.map +1 -0
  66. package/dist/types/components/admin/site-health/google-api-auth.d.ts +37 -0
  67. package/dist/types/components/admin/site-health/google-api-auth.d.ts.map +1 -0
  68. package/dist/types/components/admin/site-health/site-health-accessibility.d.ts +6 -0
  69. package/dist/types/components/admin/site-health/site-health-accessibility.d.ts.map +1 -0
  70. package/dist/types/components/admin/site-health/site-health-axe-core.d.ts +6 -0
  71. package/dist/types/components/admin/site-health/site-health-axe-core.d.ts.map +1 -0
  72. package/dist/types/components/admin/site-health/site-health-axe-core.integration.d.ts +63 -0
  73. package/dist/types/components/admin/site-health/site-health-axe-core.integration.d.ts.map +1 -0
  74. package/dist/types/components/admin/site-health/site-health-cache.d.ts +12 -0
  75. package/dist/types/components/admin/site-health/site-health-cache.d.ts.map +1 -0
  76. package/dist/types/components/admin/site-health/site-health-core-web-vitals.integration.d.ts +3 -0
  77. package/dist/types/components/admin/site-health/site-health-core-web-vitals.integration.d.ts.map +1 -0
  78. package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts +6 -0
  79. package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts.map +1 -0
  80. package/dist/types/components/admin/site-health/site-health-github.d.ts +8 -0
  81. package/dist/types/components/admin/site-health/site-health-github.d.ts.map +1 -0
  82. package/dist/types/components/admin/site-health/site-health-github.integration.d.ts +26 -0
  83. package/dist/types/components/admin/site-health/site-health-github.integration.d.ts.map +1 -0
  84. package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts +8 -0
  85. package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts.map +1 -0
  86. package/dist/types/components/admin/site-health/site-health-google-analytics.integration.d.ts +26 -0
  87. package/dist/types/components/admin/site-health/site-health-google-analytics.integration.d.ts.map +1 -0
  88. package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts +8 -0
  89. package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts.map +1 -0
  90. package/dist/types/components/admin/site-health/site-health-google-search-console.integration.d.ts +46 -0
  91. package/dist/types/components/admin/site-health/site-health-google-search-console.integration.d.ts.map +1 -0
  92. package/dist/types/components/admin/site-health/site-health-indicators.d.ts +73 -0
  93. package/dist/types/components/admin/site-health/site-health-indicators.d.ts.map +1 -0
  94. package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts +4 -0
  95. package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts.map +1 -0
  96. package/dist/types/components/admin/site-health/site-health-on-site-seo.integration.d.ts +34 -0
  97. package/dist/types/components/admin/site-health/site-health-on-site-seo.integration.d.ts.map +1 -0
  98. package/dist/types/components/admin/site-health/site-health-overview.d.ts +6 -0
  99. package/dist/types/components/admin/site-health/site-health-overview.d.ts.map +1 -0
  100. package/dist/types/components/admin/site-health/site-health-performance.d.ts +6 -0
  101. package/dist/types/components/admin/site-health/site-health-performance.d.ts.map +1 -0
  102. package/dist/types/components/admin/site-health/site-health-security.d.ts +6 -0
  103. package/dist/types/components/admin/site-health/site-health-security.d.ts.map +1 -0
  104. package/dist/types/components/admin/site-health/site-health-security.integration.d.ts +29 -0
  105. package/dist/types/components/admin/site-health/site-health-security.integration.d.ts.map +1 -0
  106. package/dist/types/components/admin/site-health/site-health-seo.d.ts +6 -0
  107. package/dist/types/components/admin/site-health/site-health-seo.d.ts.map +1 -0
  108. package/dist/types/components/admin/site-health/site-health-template.d.ts +12 -0
  109. package/dist/types/components/admin/site-health/site-health-template.d.ts.map +1 -0
  110. package/dist/types/components/admin/site-health/site-health-types.d.ts +186 -0
  111. package/dist/types/components/admin/site-health/site-health-types.d.ts.map +1 -0
  112. package/dist/types/components/admin/site-health/site-health-uptime.d.ts +6 -0
  113. package/dist/types/components/admin/site-health/site-health-uptime.d.ts.map +1 -0
  114. package/dist/types/components/admin/site-health/site-health-uptime.integration.d.ts +10 -0
  115. package/dist/types/components/admin/site-health/site-health-uptime.integration.d.ts.map +1 -0
  116. package/dist/types/components/admin/sites/sites.integration.d.ts +40 -0
  117. package/dist/types/components/admin/sites/sites.integration.d.ts.map +1 -0
  118. package/dist/types/components/cms/contentful.management.d.ts +41 -0
  119. package/dist/types/components/cms/contentful.management.d.ts.map +1 -1
  120. package/dist/types/components/config/config.client.d.ts +1 -2
  121. package/dist/types/components/config/config.client.d.ts.map +1 -1
  122. package/dist/types/components/general/table.d.ts +1 -0
  123. package/dist/types/components/general/table.d.ts.map +1 -1
  124. package/dist/types/components/seo/googleanalytics.d.ts +1 -1
  125. package/dist/types/components/seo/googleanalytics.d.ts.map +1 -1
  126. package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts +4 -4
  127. package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts.map +1 -1
  128. package/dist/types/components/structured/buzzwordbingo.d.ts +1 -1
  129. package/dist/types/components/structured/buzzwordbingo.d.ts.map +1 -1
  130. package/dist/types/components/structured/buzzwordbingo.words.d.ts +2 -0
  131. package/dist/types/components/structured/buzzwordbingo.words.d.ts.map +1 -0
  132. package/dist/types/index.d.ts +16 -3
  133. package/dist/types/index.server.d.ts +36 -13
  134. package/dist/types/stories/admin/preview.d.ts +12 -0
  135. package/dist/types/stories/admin/preview.d.ts.map +1 -0
  136. package/dist/types/stories/admin/site-health.stories.d.ts +65 -0
  137. package/dist/types/stories/admin/site-health.stories.d.ts.map +1 -0
  138. package/dist/types/stories/structured/buzzword-bingo.stories.d.ts +1 -1
  139. package/dist/types/stories/structured/buzzword-bingo.stories.d.ts.map +1 -1
  140. package/dist/types/tests/site-health-axe-core.test.d.ts +2 -0
  141. package/dist/types/tests/site-health-axe-core.test.d.ts.map +1 -0
  142. package/dist/types/tests/site-health-cache.test.d.ts +2 -0
  143. package/dist/types/tests/site-health-cache.test.d.ts.map +1 -0
  144. package/dist/types/tests/site-health-indicators.test.d.ts +2 -0
  145. package/dist/types/tests/site-health-indicators.test.d.ts.map +1 -0
  146. package/dist/types/tests/site-health-overview.test.d.ts +2 -0
  147. package/dist/types/tests/site-health-overview.test.d.ts.map +1 -0
  148. package/dist/types/tests/site-health-template.test.d.ts +2 -0
  149. package/dist/types/tests/site-health-template.test.d.ts.map +1 -0
  150. package/dist/types/tests/sites.integration.test.d.ts +2 -0
  151. package/dist/types/tests/sites.integration.test.d.ts.map +1 -0
  152. package/package.json +15 -9
  153. package/dist/data/shipping.to.json +0 -422
  154. package/dist/data/siteinfo-form.json +0 -200
  155. package/dist/data/visualdesignform.json +0 -244
  156. package/dist/types/data/buzzwords.d.ts +0 -2
  157. package/dist/types/data/buzzwords.d.ts.map +0 -1
  158. /package/dist/{data/buzzwords.js → components/structured/buzzwordbingo.words.js} +0 -0
@@ -0,0 +1,427 @@
1
+ /* Site Health - Consolidated Styles */
2
+
3
+ /* CSS Variables */
4
+ :root {
5
+ --color-primary: #3b82f6; /* Blue accent for focus states and links */
6
+ --color-secondary: #6b7280; /* Neutral gray for secondary text */
7
+ --color-accent-1: #10b981; /* Green for success/good states */
8
+ --color-accent-2: #f59e0b; /* Amber for warning states */
9
+ --color-background: #f0f0f0; /* Main page background */
10
+ --color-border: #ddd; /* Default borders */
11
+ --color-text-primary: #111827; /* Primary text */
12
+ --color-text-secondary: #6b7280; /* Secondary text */
13
+ --color-text-muted: #374151; /* Muted text */
14
+ --color-success: #10b981; /* Success state */
15
+ --color-warning: #f59e0b; /* Warning state */
16
+ --color-error: #ef4444; /* Error state */
17
+ --color-neutral: #6b7280; /* Neutral state */
18
+ }
19
+
20
+ /* Page Layout */
21
+ .site-health-page {
22
+ min-height: 100vh;
23
+ background-color: var(--color-background);
24
+ padding: 2rem;
25
+ }
26
+
27
+ .site-health-container {
28
+ max-width: 1280px;
29
+ margin: 0 auto;
30
+ }
31
+
32
+ .site-health-header {
33
+ margin-bottom: 2rem;
34
+ }
35
+
36
+ .site-health-title {
37
+ font-size: 1.875rem;
38
+ font-weight: 700;
39
+ margin-bottom: 2rem;
40
+ color: var(--color-text-primary);
41
+ }
42
+
43
+ .site-health-select {
44
+ margin-bottom: 2rem;
45
+ }
46
+
47
+ .site-health-select label {
48
+ display: block;
49
+ font-size: 0.875rem;
50
+ font-weight: 500;
51
+ color: var(--color-text-muted);
52
+ margin-bottom: 0.5rem;
53
+ }
54
+
55
+ .site-health-select select {
56
+ display: block;
57
+ width: 100%;
58
+ max-width: 20rem;
59
+ padding: 0.5rem 0.75rem;
60
+ border: 1px solid var(--color-border);
61
+ border-radius: 0.375rem;
62
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
63
+ font-size: 0.875rem;
64
+ color: var(--color-text-muted);
65
+ background-color: var(--color-background);
66
+ }
67
+
68
+ .site-health-select select:focus {
69
+ outline: none;
70
+ ring: 2px;
71
+ ring-color: var(--color-primary);
72
+ border-color: var(--color-primary);
73
+ }
74
+
75
+ /* Health Cards Grid */
76
+ .site-health-grid {
77
+ display: grid;
78
+ grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
79
+ gap: 1.5rem;
80
+ }
81
+
82
+ /* Standardized Health Card Styling */
83
+ .health-card {
84
+ background: var(--color-background);
85
+ border: 2px solid var(--color-border);
86
+ border-radius: 0.5rem;
87
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
88
+ overflow: hidden;
89
+ display: flex;
90
+ flex-direction: column;
91
+ transition: box-shadow 0.15s ease-in-out;
92
+ }
93
+
94
+ .health-card:hover {
95
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.07), 0 2px 4px rgba(0, 0, 0, 0.06);
96
+ }
97
+
98
+ .health-card-title {
99
+ padding: 1rem 1.5rem;
100
+ margin: 0;
101
+ font-size: 1.125rem;
102
+ font-weight: 600;
103
+ color: var(--color-text-primary);
104
+ background-color: var(--color-background);
105
+ border-bottom: 1px solid var(--color-border);
106
+ flex-shrink: 0;
107
+ }
108
+
109
+ .health-card-content {
110
+ padding: 1.5rem;
111
+ flex: 1;
112
+ display: flex;
113
+ flex-direction: column;
114
+ background-color: #fff;
115
+ }
116
+
117
+ /* Standardized Component Content */
118
+ .health-site-name {
119
+ font-size: 1.125rem;
120
+ font-weight: 600;
121
+ color: var(--color-text-primary);
122
+ margin-bottom: 0.5rem;
123
+ }
124
+
125
+ .health-site-url {
126
+ font-size: 0.875rem;
127
+ color: var(--color-text-secondary);
128
+ margin-bottom: 1rem;
129
+ }
130
+
131
+ .health-timestamp {
132
+ font-size: 0.75rem;
133
+ color: var(--color-text-secondary);
134
+ margin-top: 1rem;
135
+ text-align: center;
136
+ }
137
+
138
+ /* Standardized Audit Items */
139
+ .health-audit-item {
140
+ display: flex;
141
+ align-items: flex-start;
142
+ gap: 0.75rem;
143
+ }
144
+
145
+ .health-audit-icon {
146
+ font-size: 0.875rem;
147
+ font-weight: 600;
148
+ flex-shrink: 0;
149
+ margin-top: 0.125rem;
150
+ min-width: 1rem;
151
+ text-align: center;
152
+ }
153
+
154
+ .health-audit-content {
155
+ flex: 1;
156
+ min-width: 0;
157
+ }
158
+
159
+ .health-audit-title {
160
+ font-size: 0.875rem;
161
+ font-weight: 500;
162
+ color: var(--color-text-primary);
163
+ line-height: 1.25;
164
+ white-space: nowrap;
165
+ overflow: hidden;
166
+ text-overflow: ellipsis;
167
+ }
168
+
169
+ .health-audit-description {
170
+ font-size: 0.75rem;
171
+ color: var(--color-text-secondary);
172
+ margin-top: 0.25rem;
173
+ line-height: 1.4;
174
+ }
175
+
176
+ /* Status Colors */
177
+ .health-status-good { color: var(--color-success); }
178
+ .health-status-warning { color: var(--color-warning); }
179
+ .health-status-error { color: var(--color-error); }
180
+ .health-status-neutral { color: var(--color-neutral); }
181
+
182
+ /* Loading States */
183
+ .health-loading {
184
+ display: flex;
185
+ flex-direction: column;
186
+ align-items: center;
187
+ justify-content: center;
188
+ padding: 2rem;
189
+ }
190
+
191
+ .health-loading-spinner {
192
+ width: 1.5rem;
193
+ height: 1.5rem;
194
+ border: 2px solid var(--color-border);
195
+ border-top: 2px solid var(--color-primary);
196
+ border-radius: 50%;
197
+ animation: spin 1s linear infinite;
198
+ }
199
+
200
+ @keyframes spin {
201
+ 0% { transform: rotate(0deg); }
202
+ 100% { transform: rotate(360deg); }
203
+ }
204
+
205
+ .health-loading-text {
206
+ margin-top: 0.5rem;
207
+ font-size: 0.875rem;
208
+ color: var(--color-text-secondary);
209
+ }
210
+
211
+ /* Error States */
212
+ .health-error {
213
+ text-align: center;
214
+ padding: 2rem;
215
+ }
216
+
217
+ .health-error-text {
218
+ font-size: 0.875rem;
219
+ color: var(--color-error);
220
+ }
221
+
222
+ /* Score Displays */
223
+ .health-score-container {
224
+ display: flex;
225
+ flex-direction: column;
226
+ gap: 0.75rem;
227
+ margin-bottom: 1.5rem;
228
+ }
229
+
230
+ .health-score-item {
231
+ padding: 1rem;
232
+ border: 1px solid var(--color-border);
233
+ border-radius: 0.375rem;
234
+ background-color: var(--color-background);
235
+ text-align: center;
236
+ }
237
+
238
+ .health-score-label {
239
+ font-size: 0.75rem;
240
+ font-weight: 500;
241
+ color: var(--color-text-secondary);
242
+ margin-bottom: 0.5rem;
243
+ text-transform: capitalize;
244
+ }
245
+
246
+ .health-score-value {
247
+ font-size: 1.5rem;
248
+ font-weight: 700;
249
+ margin-bottom: 0.75rem;
250
+ }
251
+
252
+ .health-score-bar {
253
+ width: 100%;
254
+ height: 6px;
255
+ background-color: var(--color-border);
256
+ border-radius: 3px;
257
+ overflow: hidden;
258
+ }
259
+
260
+ .health-score-fill {
261
+ height: 100%;
262
+ border-radius: 3px;
263
+ transition: width 0.3s ease;
264
+ }
265
+
266
+ /* Core Web Vitals */
267
+ .health-cwv-grid {
268
+ display: grid;
269
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
270
+ gap: 0.75rem;
271
+ margin-bottom: 1.5rem;
272
+ }
273
+
274
+ .health-cwv-item {
275
+ display: flex;
276
+ justify-content: space-between;
277
+ align-items: center;
278
+ padding: 0.75rem;
279
+ background-color: var(--color-background);
280
+ border-radius: 0.375rem;
281
+ border: 1px solid var(--color-border);
282
+ }
283
+
284
+ .health-cwv-label {
285
+ font-size: 0.875rem;
286
+ color: var(--color-text-secondary);
287
+ }
288
+
289
+ .health-cwv-value {
290
+ font-size: 0.875rem;
291
+ font-weight: 500;
292
+ }
293
+
294
+ /* Vulnerability Items */
295
+ .health-vulnerability-item {
296
+ padding: 1rem;
297
+ border-radius: 0.375rem;
298
+ border: 1px solid;
299
+ margin-bottom: 0.5rem;
300
+ }
301
+
302
+ .health-vulnerability-critical {
303
+ background-color: #fef2f2;
304
+ border-color: #fecaca;
305
+ }
306
+
307
+ .health-vulnerability-high {
308
+ background-color: #fff7ed;
309
+ border-color: #fed7aa;
310
+ }
311
+
312
+ .health-vulnerability-moderate {
313
+ background-color: #fefce8;
314
+ border-color: #fde68a;
315
+ }
316
+
317
+ .health-vulnerability-low {
318
+ background-color: #fefefe;
319
+ border-color: #f3f4f6;
320
+ }
321
+
322
+ .health-vulnerability-info {
323
+ background-color: var(--color-background);
324
+ border-color: var(--color-border);
325
+ }
326
+
327
+ .health-vulnerability-header {
328
+ display: flex;
329
+ align-items: flex-start;
330
+ gap: 0.75rem;
331
+ margin-bottom: 0.5rem;
332
+ }
333
+
334
+ .health-vulnerability-severity {
335
+ font-size: 0.75rem;
336
+ font-weight: 600;
337
+ padding: 0.125rem 0.375rem;
338
+ border-radius: 0.25rem;
339
+ text-transform: uppercase;
340
+ flex-shrink: 0;
341
+ }
342
+
343
+ .health-vulnerability-critical .health-vulnerability-severity {
344
+ background-color: #fee2e2;
345
+ color: #dc2626;
346
+ }
347
+
348
+ .health-vulnerability-high .health-vulnerability-severity {
349
+ background-color: #fed7aa;
350
+ color: #ea580c;
351
+ }
352
+
353
+ .health-vulnerability-moderate .health-vulnerability-severity {
354
+ background-color: #fde68a;
355
+ color: #d97706;
356
+ }
357
+
358
+ .health-vulnerability-low .health-vulnerability-severity {
359
+ background-color: #e5e7eb;
360
+ color: #6b7280;
361
+ }
362
+
363
+ .health-vulnerability-info .health-vulnerability-severity {
364
+ background-color: #f3f4f6;
365
+ color: #374151;
366
+ }
367
+
368
+ .health-vulnerability-name {
369
+ font-size: 0.875rem;
370
+ font-weight: 600;
371
+ color: var(--color-text-primary);
372
+ }
373
+
374
+ .health-vulnerability-details {
375
+ font-size: 0.75rem;
376
+ color: var(--color-text-secondary);
377
+ margin-top: 0.25rem;
378
+ }
379
+
380
+ .health-vulnerability-meta {
381
+ display: flex;
382
+ align-items: center;
383
+ gap: 1rem;
384
+ margin-top: 0.5rem;
385
+ }
386
+
387
+ .health-vulnerability-range {
388
+ font-size: 0.75rem;
389
+ color: var(--color-text-secondary);
390
+ }
391
+
392
+ .health-vulnerability-fix {
393
+ font-size: 0.75rem;
394
+ font-weight: 500;
395
+ color: var(--color-success);
396
+ }
397
+
398
+ .health-vulnerability-link {
399
+ font-size: 0.75rem;
400
+ color: var(--color-primary);
401
+ text-decoration: none;
402
+ }
403
+
404
+ .health-vulnerability-link:hover {
405
+ text-decoration: underline;
406
+ }
407
+
408
+ /* Utility Classes */
409
+ .text-center { text-align: center; }
410
+ .mb-2 { margin-bottom: 0.5rem; }
411
+ .mb-4 { margin-bottom: 1rem; }
412
+
413
+ /* Table styling */
414
+ td {
415
+ font-size: .875rem;
416
+ vertical-align: top;
417
+ }
418
+
419
+ table {
420
+ width: 100%;
421
+ table-layout: fixed;
422
+ }
423
+
424
+ th, td {
425
+ word-wrap: break-word;
426
+ overflow-wrap: break-word;
427
+ }
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Sites Management Integration Services
3
+ * Server-side utilities for site configuration and data management
4
+ */
5
+ import fs from 'fs';
6
+ import path from 'path';
7
+ /**
8
+ * Load sites configuration from JSON file
9
+ */
10
+ export async function loadSitesConfig(configPath) {
11
+ try {
12
+ const sitesPath = configPath || path.join(process.cwd(), 'src/app/data/sites.json');
13
+ if (!fs.existsSync(sitesPath)) {
14
+ throw new Error('Sites configuration not found');
15
+ }
16
+ const sitesData = fs.readFileSync(sitesPath, 'utf8');
17
+ const sites = JSON.parse(sitesData);
18
+ return sites;
19
+ }
20
+ catch (error) {
21
+ console.error('Error loading sites:', error);
22
+ throw new Error('Failed to load sites configuration');
23
+ }
24
+ }
25
+ /**
26
+ * Save sites configuration to JSON file
27
+ */
28
+ export async function saveSitesConfig(sites, configPath) {
29
+ try {
30
+ const sitesPath = configPath || path.join(process.cwd(), 'src/app/data/sites.json');
31
+ // Ensure directory exists
32
+ const dir = path.dirname(sitesPath);
33
+ if (!fs.existsSync(dir)) {
34
+ fs.mkdirSync(dir, { recursive: true });
35
+ }
36
+ fs.writeFileSync(sitesPath, JSON.stringify(sites, null, 2), 'utf8');
37
+ }
38
+ catch (error) {
39
+ console.error('Error saving sites:', error);
40
+ throw new Error('Failed to save sites configuration');
41
+ }
42
+ }
43
+ /**
44
+ * Get a specific site configuration by name
45
+ */
46
+ export async function getSiteConfig(siteName, configPath) {
47
+ const sites = await loadSitesConfig(configPath);
48
+ return sites.find(site => site.name === siteName) || null;
49
+ }
50
+ /**
51
+ * Validate site configuration
52
+ */
53
+ export function validateSiteConfig(site) {
54
+ const errors = [];
55
+ if (!site.name) {
56
+ errors.push('Site name is required');
57
+ }
58
+ if (!site.localPath) {
59
+ errors.push('Local path is required');
60
+ }
61
+ else if (!fs.existsSync(site.localPath)) {
62
+ errors.push(`Local path does not exist: ${site.localPath}`);
63
+ }
64
+ // Validate Google Analytics configuration
65
+ if (site.ga4PropertyId && site.ga4PropertyId !== 'GA4_PROPERTY_ID_HERE') {
66
+ // Basic GA4 property ID validation (should start with numbers)
67
+ if (!/^\d+$/.test(site.ga4PropertyId)) {
68
+ errors.push('Invalid GA4 Property ID format');
69
+ }
70
+ }
71
+ // Validate Search Console URL
72
+ if (site.searchConsoleUrl) {
73
+ try {
74
+ new URL(site.searchConsoleUrl);
75
+ }
76
+ catch {
77
+ errors.push('Invalid Search Console URL format');
78
+ }
79
+ }
80
+ return {
81
+ valid: errors.length === 0,
82
+ errors
83
+ };
84
+ }
85
+ /**
86
+ * Add or update a site configuration
87
+ */
88
+ export async function upsertSiteConfig(site, configPath) {
89
+ const sites = await loadSitesConfig(configPath);
90
+ const existingIndex = sites.findIndex(s => s.name === site.name);
91
+ // Validate the site config
92
+ const validation = validateSiteConfig(site);
93
+ if (!validation.valid) {
94
+ throw new Error(`Invalid site configuration: ${validation.errors.join(', ')}`);
95
+ }
96
+ if (existingIndex >= 0) {
97
+ // Update existing site
98
+ sites[existingIndex] = { ...sites[existingIndex], ...site };
99
+ }
100
+ else {
101
+ // Add new site
102
+ sites.push(site);
103
+ }
104
+ await saveSitesConfig(sites, configPath);
105
+ }
106
+ /**
107
+ * Remove a site configuration
108
+ */
109
+ export async function removeSiteConfig(siteName, configPath) {
110
+ const sites = await loadSitesConfig(configPath);
111
+ const filteredSites = sites.filter(site => site.name !== siteName);
112
+ if (filteredSites.length === sites.length) {
113
+ return false; // Site not found
114
+ }
115
+ await saveSitesConfig(filteredSites, configPath);
116
+ return true;
117
+ }
@@ -252,3 +252,107 @@ export async function deleteEntry(entryId, config) {
252
252
  };
253
253
  }
254
254
  }
255
+ /**
256
+ * Validate Contentful credentials by attempting to access the space
257
+ */
258
+ export async function validateContentfulCredentials(credentials) {
259
+ try {
260
+ const response = await fetch(`https://api.contentful.com/spaces/${credentials.spaceId}`, {
261
+ method: 'GET',
262
+ headers: {
263
+ 'Authorization': `Bearer ${credentials.accessToken}`,
264
+ 'Content-Type': 'application/vnd.contentful.management.v1+json',
265
+ },
266
+ });
267
+ if (!response.ok) {
268
+ return { valid: false, error: 'Failed to access space' };
269
+ }
270
+ return { valid: true };
271
+ }
272
+ catch (error) {
273
+ return { valid: false, error: error.message };
274
+ }
275
+ }
276
+ /**
277
+ * Get all content types from a Contentful space
278
+ */
279
+ export async function getContentTypes(credentials) {
280
+ const { spaceId, accessToken } = credentials;
281
+ // First get space info to find the default environment
282
+ const spaceResponse = await fetch(`https://api.contentful.com/spaces/${spaceId}`, {
283
+ method: 'GET',
284
+ headers: {
285
+ 'Authorization': `Bearer ${accessToken}`,
286
+ 'Content-Type': 'application/vnd.contentful.management.v1+json',
287
+ },
288
+ });
289
+ if (!spaceResponse.ok) {
290
+ throw new Error('Failed to access space');
291
+ }
292
+ // Try different environment names - Contentful uses 'master' for older spaces, 'main' for newer ones
293
+ const environmentsToTry = ['master', 'main'];
294
+ let contentTypesResponse = null;
295
+ let lastError = null;
296
+ for (const env of environmentsToTry) {
297
+ try {
298
+ const response = await fetch(`https://api.contentful.com/spaces/${spaceId}/environments/${env}/content_types`, {
299
+ method: 'GET',
300
+ headers: {
301
+ 'Authorization': `Bearer ${accessToken}`,
302
+ 'Content-Type': 'application/vnd.contentful.management.v1+json',
303
+ },
304
+ });
305
+ if (response.ok) {
306
+ contentTypesResponse = response;
307
+ break;
308
+ }
309
+ }
310
+ catch (error) {
311
+ lastError = error;
312
+ }
313
+ }
314
+ if (!contentTypesResponse) {
315
+ throw new Error(`Failed to fetch content types: ${lastError}`);
316
+ }
317
+ const contentTypesData = await contentTypesResponse.json();
318
+ return contentTypesData.items || [];
319
+ }
320
+ /**
321
+ * Migrate a content type from source to destination space
322
+ */
323
+ export async function migrateContentType(sourceCredentials, destCredentials, contentTypeId) {
324
+ try {
325
+ // Get content type from source
326
+ const sourceEnv = sourceCredentials.environment || 'master';
327
+ const sourceResponse = await fetch(`https://api.contentful.com/spaces/${sourceCredentials.spaceId}/environments/${sourceEnv}/content_types/${contentTypeId}`, {
328
+ method: 'GET',
329
+ headers: {
330
+ 'Authorization': `Bearer ${sourceCredentials.accessToken}`,
331
+ 'Content-Type': 'application/vnd.contentful.management.v1+json',
332
+ },
333
+ });
334
+ if (!sourceResponse.ok) {
335
+ throw new Error('Failed to fetch content type from source');
336
+ }
337
+ const contentType = await sourceResponse.json();
338
+ // Create content type in destination
339
+ const destEnv = destCredentials.environment || 'master';
340
+ const createResponse = await fetch(`https://api.contentful.com/spaces/${destCredentials.spaceId}/environments/${destEnv}/content_types`, {
341
+ method: 'POST',
342
+ headers: {
343
+ 'Authorization': `Bearer ${destCredentials.accessToken}`,
344
+ 'Content-Type': 'application/vnd.contentful.management.v1+json',
345
+ 'X-Contentful-Version': '1',
346
+ },
347
+ body: JSON.stringify(contentType),
348
+ });
349
+ if (!createResponse.ok) {
350
+ const errorData = await createResponse.json();
351
+ throw new Error(`Failed to create content type: ${errorData.message}`);
352
+ }
353
+ return { success: true };
354
+ }
355
+ catch (error) {
356
+ return { success: false, error: error.message };
357
+ }
358
+ }
@@ -25,9 +25,9 @@ HubSpotForm.propTypes = {
25
25
  };
26
26
  export function HubSpotForm({ region, portalId, formId, target, containerId = 'hubspot-form-container' }) {
27
27
  const config = usePixelatedConfig();
28
- const finalRegion = region || config.hubspot?.region || 'na1';
29
- const finalPortalId = portalId || config.hubspot?.portalId || '';
30
- const finalFormId = formId || config.hubspot?.formId || '';
28
+ const finalRegion = region || config?.hubspot?.region || 'na1';
29
+ const finalPortalId = portalId || config?.hubspot?.portalId || '';
30
+ const finalFormId = formId || config?.hubspot?.formId || '';
31
31
  const formTarget = target || `#${containerId}`;
32
32
  useEffect(() => {
33
33
  const createHubspotForm = () => {
@@ -12,18 +12,29 @@ export const PixelatedClientConfigProvider = ({ config, children, }) => {
12
12
  export const usePixelatedConfig = () => {
13
13
  const ctx = React.useContext(PixelatedConfigContext);
14
14
  if (!ctx) {
15
- // Always throw error when provider is missing (consistent across dev/prod)
16
- // Previously had environment-specific behavior:
17
- // if (process.env.NODE_ENV !== 'production') {
18
- // throw new Error('PixelatedClientConfigProvider not found. Wrap your app with PixelatedClientConfigProvider.');
19
- // }
20
- // // In production return an empty object typed as PixelatedConfig to avoid runtime crashes
21
- // return {} as PixelatedConfig;
22
- throw new Error('PixelatedClientConfigProvider not found. Wrap your app with PixelatedClientConfigProvider.');
15
+ // Get calling function name from stack trace
16
+ let caller = 'unknown component';
17
+ try {
18
+ const error = new Error();
19
+ const stack = error.stack?.split('\n')[2]; // Get the caller line
20
+ if (stack) {
21
+ const match = stack.match(/at\s+([^\s(]+)/);
22
+ if (match && match[1]) {
23
+ caller = match[1].replace(/^use/, '').toLowerCase(); // Remove 'use' prefix and lowercase
24
+ }
25
+ }
26
+ }
27
+ catch {
28
+ // Ignore errors in stack parsing
29
+ }
30
+ // Log warning when provider is missing but continue gracefully
31
+ console.warn(`PixelatedClientConfigProvider not found when called by ${caller}. Some components may not work as expected. Wrap your app with PixelatedClientConfigProvider for full functionality.`);
32
+ return null;
23
33
  }
24
- // Also throw if config is empty (no environment config loaded)
34
+ // Also return null if config is empty (no environment config loaded)
25
35
  if (Object.keys(ctx).length === 0) {
26
- throw new Error('Pixelated config is empty. Check that PIXELATED_CONFIG_JSON or PIXELATED_CONFIG_B64 environment variables are set.');
36
+ console.warn('Pixelated config is empty. Check that PIXELATED_CONFIG_JSON or PIXELATED_CONFIG_B64 environment variables are set.');
37
+ return null;
27
38
  }
28
39
  return ctx;
29
40
  };