@pixelated-tech/components 3.3.6 → 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.
- package/README.COMPONENTS.md +126 -0
- package/README.md +14 -7
- package/dist/components/admin/componentusage/componentAnalysis.js +144 -0
- package/dist/components/admin/componentusage/componentDiscovery.js +85 -0
- package/dist/components/admin/deploy/deployment.integration.js +170 -0
- package/dist/components/admin/site-health/google-api-auth.js +69 -0
- package/dist/components/admin/site-health/seo-metrics.config.json +265 -0
- package/dist/components/admin/site-health/site-health-accessibility.js +158 -0
- package/dist/components/admin/site-health/site-health-axe-core.integration.js +119 -0
- package/dist/components/admin/site-health/site-health-axe-core.js +53 -0
- package/dist/components/admin/site-health/site-health-cache.js +23 -0
- package/dist/components/admin/site-health/site-health-core-web-vitals.integration.js +208 -0
- package/dist/components/admin/site-health/site-health-dependency-vulnerabilities.js +38 -0
- package/dist/components/admin/site-health/site-health-github.integration.js +81 -0
- package/dist/components/admin/site-health/site-health-github.js +34 -0
- package/dist/components/admin/site-health/site-health-google-analytics.integration.js +112 -0
- package/dist/components/admin/site-health/site-health-google-analytics.js +43 -0
- package/dist/components/admin/site-health/site-health-google-search-console.integration.js +118 -0
- package/dist/components/admin/site-health/site-health-google-search-console.js +43 -0
- package/dist/components/admin/site-health/site-health-indicators.js +71 -0
- package/dist/components/admin/site-health/site-health-on-site-seo.integration.js +578 -0
- package/dist/components/admin/site-health/site-health-on-site-seo.js +204 -0
- package/dist/components/admin/site-health/site-health-overview.js +65 -0
- package/dist/components/admin/site-health/site-health-performance.js +191 -0
- package/dist/components/admin/site-health/site-health-security.integration.js +109 -0
- package/dist/components/admin/site-health/site-health-security.js +169 -0
- package/dist/components/admin/site-health/site-health-seo.js +124 -0
- package/dist/components/admin/site-health/site-health-template.js +62 -0
- package/dist/components/admin/site-health/site-health-types.js +1 -0
- package/dist/components/admin/site-health/site-health-uptime.integration.js +29 -0
- package/dist/components/admin/site-health/site-health-uptime.js +30 -0
- package/dist/components/admin/site-health/site-health.css +427 -0
- package/dist/components/admin/sites/sites.integration.js +117 -0
- package/dist/components/cms/contentful.management.js +104 -0
- package/dist/components/shoppingcart/shipping.from.json +101 -0
- package/dist/components/shoppingcart/shipping.parcel.json +112 -0
- package/dist/components/shoppingcart/shipping.to.json +422 -0
- package/dist/components/shoppingcart/shoppingCartDiscountCodes.json +26 -0
- package/dist/components/shoppingcart/shoppingcart.components.js +1 -1
- package/dist/components/sitebuilder/config/ConfigBuilder.js +36 -140
- package/dist/components/sitebuilder/config/siteinfo-form.json +200 -0
- package/dist/components/sitebuilder/config/visualdesignform.json +244 -0
- package/dist/components/structured/buzzwordbingo.js +3 -2
- package/dist/data/404-data.json +128 -102
- package/dist/data/flickr.json +25 -0
- package/dist/data/form.json +368 -368
- package/dist/data/recipes.json +3251 -3251
- package/dist/data/references.json +138 -137
- package/dist/data/requestform.json +111 -0
- package/dist/data/requests.json +136 -135
- package/dist/data/resume.json +2573 -2575
- package/dist/data/routes.json +238 -238
- package/dist/data/routes2.json +141 -140
- package/dist/index.js +16 -3
- package/dist/index.server.js +36 -15
- package/dist/types/components/admin/componentusage/componentAnalysis.d.ts +35 -0
- package/dist/types/components/admin/componentusage/componentAnalysis.d.ts.map +1 -0
- package/dist/types/components/admin/componentusage/componentDiscovery.d.ts +10 -0
- package/dist/types/components/admin/componentusage/componentDiscovery.d.ts.map +1 -0
- package/dist/types/components/admin/deploy/deployment.integration.d.ts +26 -0
- package/dist/types/components/admin/deploy/deployment.integration.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/google-api-auth.d.ts +37 -0
- package/dist/types/components/admin/site-health/google-api-auth.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-accessibility.d.ts +6 -0
- package/dist/types/components/admin/site-health/site-health-accessibility.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-axe-core.d.ts +6 -0
- package/dist/types/components/admin/site-health/site-health-axe-core.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-axe-core.integration.d.ts +63 -0
- package/dist/types/components/admin/site-health/site-health-axe-core.integration.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-cache.d.ts +12 -0
- package/dist/types/components/admin/site-health/site-health-cache.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-core-web-vitals.integration.d.ts +3 -0
- package/dist/types/components/admin/site-health/site-health-core-web-vitals.integration.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts +6 -0
- package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-github.d.ts +8 -0
- package/dist/types/components/admin/site-health/site-health-github.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-github.integration.d.ts +26 -0
- package/dist/types/components/admin/site-health/site-health-github.integration.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts +8 -0
- package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-google-analytics.integration.d.ts +26 -0
- package/dist/types/components/admin/site-health/site-health-google-analytics.integration.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts +8 -0
- package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-google-search-console.integration.d.ts +46 -0
- package/dist/types/components/admin/site-health/site-health-google-search-console.integration.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-indicators.d.ts +73 -0
- package/dist/types/components/admin/site-health/site-health-indicators.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts +4 -0
- package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-on-site-seo.integration.d.ts +34 -0
- package/dist/types/components/admin/site-health/site-health-on-site-seo.integration.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-overview.d.ts +6 -0
- package/dist/types/components/admin/site-health/site-health-overview.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-performance.d.ts +6 -0
- package/dist/types/components/admin/site-health/site-health-performance.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-security.d.ts +6 -0
- package/dist/types/components/admin/site-health/site-health-security.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-security.integration.d.ts +29 -0
- package/dist/types/components/admin/site-health/site-health-security.integration.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-seo.d.ts +6 -0
- package/dist/types/components/admin/site-health/site-health-seo.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-template.d.ts +12 -0
- package/dist/types/components/admin/site-health/site-health-template.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-types.d.ts +186 -0
- package/dist/types/components/admin/site-health/site-health-types.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-uptime.d.ts +6 -0
- package/dist/types/components/admin/site-health/site-health-uptime.d.ts.map +1 -0
- package/dist/types/components/admin/site-health/site-health-uptime.integration.d.ts +10 -0
- package/dist/types/components/admin/site-health/site-health-uptime.integration.d.ts.map +1 -0
- package/dist/types/components/admin/sites/sites.integration.d.ts +40 -0
- package/dist/types/components/admin/sites/sites.integration.d.ts.map +1 -0
- package/dist/types/components/cms/contentful.management.d.ts +41 -0
- package/dist/types/components/cms/contentful.management.d.ts.map +1 -1
- package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts +4 -4
- package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts.map +1 -1
- package/dist/types/components/structured/buzzwordbingo.d.ts +1 -1
- package/dist/types/components/structured/buzzwordbingo.d.ts.map +1 -1
- package/dist/types/components/structured/buzzwordbingo.words.d.ts +2 -0
- package/dist/types/components/structured/buzzwordbingo.words.d.ts.map +1 -0
- package/dist/types/index.d.ts +16 -3
- package/dist/types/index.server.d.ts +36 -13
- package/dist/types/stories/admin/preview.d.ts +12 -0
- package/dist/types/stories/admin/preview.d.ts.map +1 -0
- package/dist/types/stories/admin/site-health.stories.d.ts +65 -0
- package/dist/types/stories/admin/site-health.stories.d.ts.map +1 -0
- package/dist/types/stories/structured/buzzword-bingo.stories.d.ts +1 -1
- package/dist/types/stories/structured/buzzword-bingo.stories.d.ts.map +1 -1
- package/dist/types/tests/site-health-axe-core.test.d.ts +2 -0
- package/dist/types/tests/site-health-axe-core.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-cache.test.d.ts +2 -0
- package/dist/types/tests/site-health-cache.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-indicators.test.d.ts +2 -0
- package/dist/types/tests/site-health-indicators.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-overview.test.d.ts +2 -0
- package/dist/types/tests/site-health-overview.test.d.ts.map +1 -0
- package/dist/types/tests/site-health-template.test.d.ts +2 -0
- package/dist/types/tests/site-health-template.test.d.ts.map +1 -0
- package/dist/types/tests/sites.integration.test.d.ts +2 -0
- package/dist/types/tests/sites.integration.test.d.ts.map +1 -0
- package/package.json +14 -8
- package/dist/data/shipping.to.json +0 -422
- package/dist/data/siteinfo-form.json +0 -200
- package/dist/data/visualdesignform.json +0 -244
- package/dist/types/data/buzzwords.d.ts +0 -2
- package/dist/types/data/buzzwords.d.ts.map +0 -1
- /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
|
+
}
|