sanity-plugin-seofields 1.4.1 → 1.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.
- package/README.md +1 -1
- package/dist/SeoHealthDashboard-3VBITMWT.cjs +10 -0
- package/dist/SeoHealthDashboard-3VBITMWT.cjs.map +1 -0
- package/dist/SeoHealthDashboard-BNJBRQVN.js +4 -0
- package/dist/SeoHealthDashboard-BNJBRQVN.js.map +1 -0
- package/dist/SeoHealthTool-4P6JST5S.cjs +14 -0
- package/dist/SeoHealthTool-4P6JST5S.cjs.map +1 -0
- package/dist/SeoHealthTool-MQBE5YGN.js +12 -0
- package/dist/SeoHealthTool-MQBE5YGN.js.map +1 -0
- package/dist/SeoPreview-G3LPA7GV.js +148 -0
- package/dist/SeoPreview-G3LPA7GV.js.map +1 -0
- package/dist/SeoPreview-Y3CFDVBR.cjs +154 -0
- package/dist/SeoPreview-Y3CFDVBR.cjs.map +1 -0
- package/dist/chunk-25JLWVEU.js +472 -0
- package/dist/chunk-25JLWVEU.js.map +1 -0
- package/dist/chunk-2NMEKWO5.js +35 -0
- package/dist/chunk-2NMEKWO5.js.map +1 -0
- package/dist/chunk-527WXITP.js +428 -0
- package/dist/chunk-527WXITP.js.map +1 -0
- package/dist/chunk-6CYMVS3O.js +1245 -0
- package/dist/chunk-6CYMVS3O.js.map +1 -0
- package/dist/chunk-D2GWRRK5.cjs +1293 -0
- package/dist/chunk-D2GWRRK5.cjs.map +1 -0
- package/dist/chunk-DYVCCQHT.cjs +1400 -0
- package/dist/chunk-DYVCCQHT.cjs.map +1 -0
- package/dist/chunk-IFDLKZET.cjs +485 -0
- package/dist/chunk-IFDLKZET.cjs.map +1 -0
- package/dist/chunk-L3L3FSPJ.cjs +478 -0
- package/dist/chunk-L3L3FSPJ.cjs.map +1 -0
- package/dist/chunk-S367Y35J.cjs +39 -0
- package/dist/chunk-S367Y35J.cjs.map +1 -0
- package/dist/chunk-WUIZN7VI.js +1394 -0
- package/dist/chunk-WUIZN7VI.js.map +1 -0
- package/dist/cli.js +67 -0
- package/dist/define-cli.cjs +12 -0
- package/dist/define-cli.cjs.map +1 -0
- package/dist/define-cli.d.cts +42 -0
- package/dist/define-cli.d.ts +42 -0
- package/dist/define-cli.js +10 -0
- package/dist/define-cli.js.map +1 -0
- package/dist/index.cjs +154 -2365
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +109 -2303
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +235 -1591
- package/dist/next.cjs.map +1 -1
- package/dist/next.js +7 -1482
- package/dist/next.js.map +1 -1
- package/dist/schema/next.cjs +200 -1542
- package/dist/schema/next.cjs.map +1 -1
- package/dist/schema/next.js +4 -1475
- package/dist/schema/next.js.map +1 -1
- package/dist/schema.cjs +252 -1514
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js +58 -1391
- package/dist/schema.js.map +1 -1
- package/package.json +21 -5
package/dist/index.cjs
CHANGED
|
@@ -1,2182 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __defProps = Object.defineProperties;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
7
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
9
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
10
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
11
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
12
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
13
|
-
var __spreadValues = (a, b) => {
|
|
14
|
-
for (var prop in b || (b = {}))
|
|
15
|
-
if (__hasOwnProp.call(b, prop))
|
|
16
|
-
__defNormalProp(a, prop, b[prop]);
|
|
17
|
-
if (__getOwnPropSymbols)
|
|
18
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
19
|
-
if (__propIsEnum.call(b, prop))
|
|
20
|
-
__defNormalProp(a, prop, b[prop]);
|
|
21
|
-
}
|
|
22
|
-
return a;
|
|
23
|
-
};
|
|
24
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
-
var __objRest = (source, exclude) => {
|
|
26
|
-
var target = {};
|
|
27
|
-
for (var prop in source)
|
|
28
|
-
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
29
|
-
target[prop] = source[prop];
|
|
30
|
-
if (source != null && __getOwnPropSymbols)
|
|
31
|
-
for (var prop of __getOwnPropSymbols(source)) {
|
|
32
|
-
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
33
|
-
target[prop] = source[prop];
|
|
34
|
-
}
|
|
35
|
-
return target;
|
|
36
|
-
};
|
|
37
|
-
var __esm = (fn, res) => function __init() {
|
|
38
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
39
|
-
};
|
|
40
|
-
var __export = (target, all) => {
|
|
41
|
-
for (var name in all)
|
|
42
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
43
|
-
};
|
|
44
|
-
var __copyProps = (to, from, except, desc) => {
|
|
45
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
46
|
-
for (let key of __getOwnPropNames(from))
|
|
47
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
48
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
49
|
-
}
|
|
50
|
-
return to;
|
|
51
|
-
};
|
|
52
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
53
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
54
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
55
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
56
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
57
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
58
|
-
mod
|
|
59
|
-
));
|
|
60
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
61
|
-
|
|
62
|
-
// src/utils/seoUtils.ts
|
|
63
|
-
var stopWords, hasMatchingKeyword, hasKeywordOveruse, startsWithStopWord, truncate, hasExcessivePunctuation, getMetaTitleValidationMessages, getMetaDescriptionValidationMessages, getOgTitleValidation, getOgDescriptionValidation, getTwitterTitleValidation, getTwitterDescriptionValidation, isSubImageSet, isMetaImageSet, getMetaImageValidation, getOgImageValidation, getOgImageUrlValidation, getTwitterImageValidation, getTwitterImageUrlValidation;
|
|
64
|
-
var init_seoUtils = __esm({
|
|
65
|
-
"src/utils/seoUtils.ts"() {
|
|
66
|
-
"use strict";
|
|
67
|
-
stopWords = ["the", "a", "an", "and", "or", "but"];
|
|
68
|
-
hasMatchingKeyword = (title, keywordList) => {
|
|
69
|
-
if (!title || keywordList.length === 0) return false;
|
|
70
|
-
const lowerTitle = title.toLowerCase();
|
|
71
|
-
return keywordList.some((keyword) => keyword && lowerTitle.includes(keyword.toLowerCase()));
|
|
72
|
-
};
|
|
73
|
-
hasKeywordOveruse = (title, keywordList, maxOccurrences = 3) => {
|
|
74
|
-
if (!title || keywordList.length === 0) return false;
|
|
75
|
-
const lowerTitle = title.toLowerCase();
|
|
76
|
-
return keywordList.some((keyword) => {
|
|
77
|
-
if (!keyword) return false;
|
|
78
|
-
const matches = lowerTitle.match(new RegExp(keyword.toLowerCase(), "g"));
|
|
79
|
-
return matches ? matches.length > maxOccurrences : false;
|
|
80
|
-
});
|
|
81
|
-
};
|
|
82
|
-
startsWithStopWord = (title) => {
|
|
83
|
-
if (!title) return false;
|
|
84
|
-
const firstWord = title.trim().split(" ")[0].toLowerCase();
|
|
85
|
-
return stopWords.includes(firstWord);
|
|
86
|
-
};
|
|
87
|
-
truncate = (text, maxLength) => text.length > maxLength ? `${text.slice(0, maxLength)}\u2026` : text;
|
|
88
|
-
hasExcessivePunctuation = (title) => /[!@#$%^&*]{2,}/.test(title);
|
|
89
|
-
getMetaTitleValidationMessages = (title, keywords, isParentseoField) => {
|
|
90
|
-
const feedback = [];
|
|
91
|
-
const minChar = 50;
|
|
92
|
-
const maxChar = 60;
|
|
93
|
-
const charCount = (title == null ? void 0 : title.length) || 0;
|
|
94
|
-
if (!(title == null ? void 0 : title.trim())) {
|
|
95
|
-
feedback.push({ text: "Meta Title is empty. Add content to improve SEO.", color: "red" });
|
|
96
|
-
return feedback;
|
|
97
|
-
}
|
|
98
|
-
if (charCount < minChar)
|
|
99
|
-
feedback.push({
|
|
100
|
-
text: `Title is ${charCount} characters \u2014 below recommended ${minChar}.`,
|
|
101
|
-
color: "orange"
|
|
102
|
-
});
|
|
103
|
-
else if (charCount > maxChar)
|
|
104
|
-
feedback.push({
|
|
105
|
-
text: `Title is ${charCount} characters \u2014 exceeds recommended ${maxChar}.`,
|
|
106
|
-
color: "red"
|
|
107
|
-
});
|
|
108
|
-
else feedback.push({ text: `Title length (${charCount}) looks good for SEO.`, color: "green" });
|
|
109
|
-
if (isParentseoField) {
|
|
110
|
-
if (keywords.length > 0) {
|
|
111
|
-
const hasKeyword = hasMatchingKeyword(title, keywords);
|
|
112
|
-
feedback.push({
|
|
113
|
-
text: hasKeyword ? "Keyword found in title \u2014 good job!" : "Keywords defined but missing in title.",
|
|
114
|
-
color: hasKeyword ? "green" : "red"
|
|
115
|
-
});
|
|
116
|
-
if (hasKeywordOveruse(title, keywords)) {
|
|
117
|
-
feedback.push({
|
|
118
|
-
text: "Keyword appears too many times \u2014 avoid keyword stuffing.",
|
|
119
|
-
color: "orange"
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
} else {
|
|
123
|
-
feedback.push({
|
|
124
|
-
text: "No keywords defined. Consider adding relevant keywords.",
|
|
125
|
-
color: "orange"
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (startsWithStopWord(title))
|
|
130
|
-
feedback.push({ text: "Title starts with a stop word \u2014 consider rephrasing.", color: "orange" });
|
|
131
|
-
if (hasExcessivePunctuation(title))
|
|
132
|
-
feedback.push({ text: "Title contains excessive punctuation \u2014 simplify it.", color: "orange" });
|
|
133
|
-
return feedback;
|
|
134
|
-
};
|
|
135
|
-
getMetaDescriptionValidationMessages = (description, keywords, isParentseoField) => {
|
|
136
|
-
const feedback = [];
|
|
137
|
-
const minChar = 120;
|
|
138
|
-
const maxChar = 160;
|
|
139
|
-
const charCount = (description == null ? void 0 : description.length) || 0;
|
|
140
|
-
if (!(description == null ? void 0 : description.trim())) {
|
|
141
|
-
feedback.push({ text: "Meta description is empty. Add content to improve SEO.", color: "red" });
|
|
142
|
-
return feedback;
|
|
143
|
-
}
|
|
144
|
-
if (charCount < minChar)
|
|
145
|
-
feedback.push({
|
|
146
|
-
text: `Description is ${charCount} chars \u2014 below recommended ${minChar}.`,
|
|
147
|
-
color: "orange"
|
|
148
|
-
});
|
|
149
|
-
else if (charCount > maxChar)
|
|
150
|
-
feedback.push({
|
|
151
|
-
text: `Description is ${charCount} chars \u2014 exceeds recommended ${maxChar}.`,
|
|
152
|
-
color: "red"
|
|
153
|
-
});
|
|
154
|
-
else
|
|
155
|
-
feedback.push({ text: `Description length (${charCount}) looks good for SEO.`, color: "green" });
|
|
156
|
-
if (isParentseoField) {
|
|
157
|
-
if (keywords.length > 0) {
|
|
158
|
-
const hasKeyword = hasMatchingKeyword(description, keywords);
|
|
159
|
-
feedback.push({
|
|
160
|
-
text: hasKeyword ? "Keyword found in description \u2014 good job!" : "Keywords defined but missing in description.",
|
|
161
|
-
color: hasKeyword ? "green" : "red"
|
|
162
|
-
});
|
|
163
|
-
if (hasKeywordOveruse(description, keywords)) {
|
|
164
|
-
feedback.push({
|
|
165
|
-
text: "Keyword appears too many times \u2014 avoid keyword stuffing.",
|
|
166
|
-
color: "orange"
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
} else {
|
|
170
|
-
feedback.push({
|
|
171
|
-
text: "No keywords defined. Consider adding relevant keywords.",
|
|
172
|
-
color: "orange"
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
if (startsWithStopWord(description))
|
|
177
|
-
feedback.push({
|
|
178
|
-
text: "Description starts with a stop word \u2014 consider rephrasing.",
|
|
179
|
-
color: "orange"
|
|
180
|
-
});
|
|
181
|
-
if (hasExcessivePunctuation(description))
|
|
182
|
-
feedback.push({
|
|
183
|
-
text: "Description contains excessive punctuation \u2014 simplify it.",
|
|
184
|
-
color: "orange"
|
|
185
|
-
});
|
|
186
|
-
return feedback;
|
|
187
|
-
};
|
|
188
|
-
getOgTitleValidation = (title, keywords = [], isParentseoField) => {
|
|
189
|
-
const feedback = [];
|
|
190
|
-
const min = 40;
|
|
191
|
-
const max = 60;
|
|
192
|
-
const count = (title == null ? void 0 : title.length) || 0;
|
|
193
|
-
if (!(title == null ? void 0 : title.trim())) {
|
|
194
|
-
feedback.push({ text: "OG Title is empty. Add content for better social preview.", color: "red" });
|
|
195
|
-
return feedback;
|
|
196
|
-
}
|
|
197
|
-
if (count < min)
|
|
198
|
-
feedback.push({
|
|
199
|
-
text: `OG Title is ${count} chars \u2014 shorter than recommended ${min}.`,
|
|
200
|
-
color: "orange"
|
|
201
|
-
});
|
|
202
|
-
else if (count > max)
|
|
203
|
-
feedback.push({ text: `OG Title is ${count} chars \u2014 exceeds recommended ${max}.`, color: "red" });
|
|
204
|
-
else feedback.push({ text: `OG Title length (${count}) looks good.`, color: "green" });
|
|
205
|
-
if (isParentseoField) {
|
|
206
|
-
if (keywords.length > 0) {
|
|
207
|
-
const hasKeyword = hasMatchingKeyword(title, keywords);
|
|
208
|
-
feedback.push({
|
|
209
|
-
text: hasKeyword ? "Keyword found in OG title \u2014 good job!" : "Keywords defined but missing in OG title.",
|
|
210
|
-
color: hasKeyword ? "green" : "red"
|
|
211
|
-
});
|
|
212
|
-
if (hasKeywordOveruse(title, keywords)) {
|
|
213
|
-
feedback.push({
|
|
214
|
-
text: "Keyword appears too many times in OG title \u2014 avoid keyword stuffing.",
|
|
215
|
-
color: "orange"
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
} else {
|
|
219
|
-
feedback.push({
|
|
220
|
-
text: "No keywords defined. Consider adding relevant keywords.",
|
|
221
|
-
color: "orange"
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
if (startsWithStopWord(title))
|
|
226
|
-
feedback.push({
|
|
227
|
-
text: "OG Title starts with a stop word \u2014 consider rephrasing.",
|
|
228
|
-
color: "orange"
|
|
229
|
-
});
|
|
230
|
-
if (hasExcessivePunctuation(title))
|
|
231
|
-
feedback.push({ text: "OG Title contains excessive punctuation \u2014 simplify it.", color: "orange" });
|
|
232
|
-
return feedback;
|
|
233
|
-
};
|
|
234
|
-
getOgDescriptionValidation = (desc, keywords = [], isParentseoField) => {
|
|
235
|
-
const feedback = [];
|
|
236
|
-
const min = 90;
|
|
237
|
-
const max = 120;
|
|
238
|
-
const count = (desc == null ? void 0 : desc.length) || 0;
|
|
239
|
-
if (!(desc == null ? void 0 : desc.trim())) {
|
|
240
|
-
feedback.push({
|
|
241
|
-
text: "OG Description is empty. Add content for better social preview.",
|
|
242
|
-
color: "red"
|
|
243
|
-
});
|
|
244
|
-
return feedback;
|
|
245
|
-
}
|
|
246
|
-
if (count < min)
|
|
247
|
-
feedback.push({
|
|
248
|
-
text: `OG Description is ${count} chars \u2014 shorter than recommended ${min}.`,
|
|
249
|
-
color: "orange"
|
|
250
|
-
});
|
|
251
|
-
else if (count > max)
|
|
252
|
-
feedback.push({
|
|
253
|
-
text: `OG Description is ${count} chars \u2014 exceeds recommended ${max}.`,
|
|
254
|
-
color: "red"
|
|
255
|
-
});
|
|
256
|
-
else feedback.push({ text: `OG Description length (${count}) looks good.`, color: "green" });
|
|
257
|
-
if (isParentseoField) {
|
|
258
|
-
if (keywords.length > 0) {
|
|
259
|
-
const hasKeyword = hasMatchingKeyword(desc, keywords);
|
|
260
|
-
feedback.push({
|
|
261
|
-
text: hasKeyword ? "Keyword found in OG description \u2014 good job!" : "Keywords defined but missing in OG description.",
|
|
262
|
-
color: hasKeyword ? "green" : "red"
|
|
263
|
-
});
|
|
264
|
-
if (hasKeywordOveruse(desc, keywords)) {
|
|
265
|
-
feedback.push({
|
|
266
|
-
text: "Keyword appears too many times in OG description \u2014 avoid keyword stuffing.",
|
|
267
|
-
color: "orange"
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
} else {
|
|
271
|
-
feedback.push({
|
|
272
|
-
text: "No keywords defined. Consider adding relevant keywords.",
|
|
273
|
-
color: "orange"
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
if (startsWithStopWord(desc))
|
|
278
|
-
feedback.push({
|
|
279
|
-
text: "OG Description starts with a stop word \u2014 consider rephrasing.",
|
|
280
|
-
color: "orange"
|
|
281
|
-
});
|
|
282
|
-
if (hasExcessivePunctuation(desc))
|
|
283
|
-
feedback.push({
|
|
284
|
-
text: "OG Description contains excessive punctuation \u2014 simplify it.",
|
|
285
|
-
color: "orange"
|
|
286
|
-
});
|
|
287
|
-
return feedback;
|
|
288
|
-
};
|
|
289
|
-
getTwitterTitleValidation = (title, keywords = [], isParentseoField) => {
|
|
290
|
-
const feedback = [];
|
|
291
|
-
const min = 30;
|
|
292
|
-
const max = 70;
|
|
293
|
-
const count = (title == null ? void 0 : title.length) || 0;
|
|
294
|
-
if (!(title == null ? void 0 : title.trim())) {
|
|
295
|
-
feedback.push({ text: "X Title is empty. Add content for better SEO.", color: "red" });
|
|
296
|
-
return feedback;
|
|
297
|
-
}
|
|
298
|
-
if (count < min)
|
|
299
|
-
feedback.push({
|
|
300
|
-
text: `X Title is ${count} chars \u2014 shorter than recommended ${min}.`,
|
|
301
|
-
color: "orange"
|
|
302
|
-
});
|
|
303
|
-
else if (count > max)
|
|
304
|
-
feedback.push({
|
|
305
|
-
text: `X Title is ${count} chars \u2014 exceeds recommended ${max}.`,
|
|
306
|
-
color: "red"
|
|
307
|
-
});
|
|
308
|
-
else feedback.push({ text: `X Title length (${count}) looks good.`, color: "green" });
|
|
309
|
-
if (isParentseoField) {
|
|
310
|
-
if (keywords.length > 0) {
|
|
311
|
-
const hasKeyword = hasMatchingKeyword(title, keywords);
|
|
312
|
-
feedback.push({
|
|
313
|
-
text: hasKeyword ? "Keyword found in X title \u2014 good job!" : "Keywords defined but missing in X title.",
|
|
314
|
-
color: hasKeyword ? "green" : "red"
|
|
315
|
-
});
|
|
316
|
-
} else {
|
|
317
|
-
feedback.push({
|
|
318
|
-
text: "No keywords defined. Consider adding relevant keywords.",
|
|
319
|
-
color: "orange"
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
if (/[!@#$%^&*]{2,}/.test(title))
|
|
324
|
-
feedback.push({ text: "X Title has excessive punctuation \u2014 simplify it.", color: "orange" });
|
|
325
|
-
return feedback;
|
|
326
|
-
};
|
|
327
|
-
getTwitterDescriptionValidation = (desc, keywords = [], isParentseoField) => {
|
|
328
|
-
const feedback = [];
|
|
329
|
-
const min = 50;
|
|
330
|
-
const max = 200;
|
|
331
|
-
const count = (desc == null ? void 0 : desc.length) || 0;
|
|
332
|
-
if (!(desc == null ? void 0 : desc.trim())) {
|
|
333
|
-
feedback.push({ text: "X Description is empty. Add content for better SEO.", color: "red" });
|
|
334
|
-
return feedback;
|
|
335
|
-
}
|
|
336
|
-
if (count < min)
|
|
337
|
-
feedback.push({
|
|
338
|
-
text: `X Description is ${count} chars \u2014 shorter than recommended ${min}.`,
|
|
339
|
-
color: "orange"
|
|
340
|
-
});
|
|
341
|
-
else if (count > max)
|
|
342
|
-
feedback.push({
|
|
343
|
-
text: `X Description is ${count} chars \u2014 exceeds recommended ${max}.`,
|
|
344
|
-
color: "red"
|
|
345
|
-
});
|
|
346
|
-
else feedback.push({ text: `X Description length (${count}) looks good.`, color: "green" });
|
|
347
|
-
if (isParentseoField) {
|
|
348
|
-
if (keywords.length > 0) {
|
|
349
|
-
const hasKeyword = hasMatchingKeyword(desc, keywords);
|
|
350
|
-
feedback.push({
|
|
351
|
-
text: hasKeyword ? "Keyword found in X description \u2014 good job!" : "Keywords defined but missing in X description.",
|
|
352
|
-
color: hasKeyword ? "green" : "red"
|
|
353
|
-
});
|
|
354
|
-
} else {
|
|
355
|
-
feedback.push({
|
|
356
|
-
text: "No keywords defined. Consider adding relevant keywords.",
|
|
357
|
-
color: "orange"
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
if (/[!@#$%^&*]{2,}/.test(desc))
|
|
362
|
-
feedback.push({
|
|
363
|
-
text: "X Description has excessive punctuation \u2014 simplify it.",
|
|
364
|
-
color: "orange"
|
|
365
|
-
});
|
|
366
|
-
return feedback;
|
|
367
|
-
};
|
|
368
|
-
isSubImageSet = (subObj) => {
|
|
369
|
-
var _a;
|
|
370
|
-
if (!subObj) return false;
|
|
371
|
-
if (subObj.imageType === "url") return !!((_a = subObj.imageUrl) == null ? void 0 : _a.trim());
|
|
372
|
-
const img = subObj.image;
|
|
373
|
-
return !!(img == null ? void 0 : img.asset);
|
|
374
|
-
};
|
|
375
|
-
isMetaImageSet = (seoParent) => {
|
|
376
|
-
if (!seoParent) return false;
|
|
377
|
-
const metaImage = seoParent.metaImage;
|
|
378
|
-
return !!(metaImage == null ? void 0 : metaImage.asset);
|
|
379
|
-
};
|
|
380
|
-
getMetaImageValidation = (hasImage, seoParent) => {
|
|
381
|
-
const feedback = [];
|
|
382
|
-
if (!hasImage) {
|
|
383
|
-
feedback.push({
|
|
384
|
-
text: "No meta image provided. Adding an image improves click-through rates.",
|
|
385
|
-
color: "red"
|
|
386
|
-
});
|
|
387
|
-
return feedback;
|
|
388
|
-
}
|
|
389
|
-
feedback.push({ text: "Meta image is set \u2014 great for SEO and social sharing.", color: "green" });
|
|
390
|
-
const ogSet = isSubImageSet(seoParent == null ? void 0 : seoParent.openGraph);
|
|
391
|
-
const twSet = isSubImageSet(seoParent == null ? void 0 : seoParent.twitter);
|
|
392
|
-
if (!ogSet && !twSet) {
|
|
393
|
-
feedback.push({
|
|
394
|
-
text: "OG and Twitter images are missing \u2014 add them for full social coverage.",
|
|
395
|
-
color: "orange"
|
|
396
|
-
});
|
|
397
|
-
} else if (!ogSet) {
|
|
398
|
-
feedback.push({
|
|
399
|
-
text: "OG image is missing \u2014 add it for better Facebook/LinkedIn previews.",
|
|
400
|
-
color: "orange"
|
|
401
|
-
});
|
|
402
|
-
} else if (twSet) {
|
|
403
|
-
feedback.push({ text: "All images set (Meta, OG, Twitter) \u2014 full coverage!", color: "green" });
|
|
404
|
-
} else {
|
|
405
|
-
feedback.push({
|
|
406
|
-
text: "Twitter image is missing \u2014 add it for better X (Twitter) cards.",
|
|
407
|
-
color: "orange"
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
return feedback;
|
|
411
|
-
};
|
|
412
|
-
getOgImageValidation = (hasImage, altText, seoParent) => {
|
|
413
|
-
const feedback = [];
|
|
414
|
-
if (!hasImage) {
|
|
415
|
-
feedback.push({
|
|
416
|
-
text: "No OG image provided. Social shares will lack a visual preview.",
|
|
417
|
-
color: "red"
|
|
418
|
-
});
|
|
419
|
-
return feedback;
|
|
420
|
-
}
|
|
421
|
-
feedback.push({ text: "OG image is set \u2014 good for social sharing.", color: "green" });
|
|
422
|
-
if (altText == null ? void 0 : altText.trim()) {
|
|
423
|
-
feedback.push({ text: "Alt text is set \u2014 good for accessibility.", color: "green" });
|
|
424
|
-
} else {
|
|
425
|
-
feedback.push({ text: "Consider adding alt text for better accessibility.", color: "orange" });
|
|
426
|
-
}
|
|
427
|
-
const metaSet = isMetaImageSet(seoParent);
|
|
428
|
-
const twSet = isSubImageSet(seoParent == null ? void 0 : seoParent.twitter);
|
|
429
|
-
if (metaSet && twSet) {
|
|
430
|
-
feedback.push({ text: "All images set (Meta, OG, Twitter) \u2014 full coverage!", color: "green" });
|
|
431
|
-
} else {
|
|
432
|
-
if (!metaSet)
|
|
433
|
-
feedback.push({
|
|
434
|
-
text: "Meta image is missing \u2014 add it for search engine results.",
|
|
435
|
-
color: "orange"
|
|
436
|
-
});
|
|
437
|
-
if (!twSet)
|
|
438
|
-
feedback.push({
|
|
439
|
-
text: "Twitter image is missing \u2014 add it for X (Twitter) cards.",
|
|
440
|
-
color: "orange"
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
return feedback;
|
|
444
|
-
};
|
|
445
|
-
getOgImageUrlValidation = (imageUrl, seoParent) => {
|
|
446
|
-
const feedback = [];
|
|
447
|
-
if (!(imageUrl == null ? void 0 : imageUrl.trim())) {
|
|
448
|
-
feedback.push({
|
|
449
|
-
text: "No OG image URL provided. Social shares will lack a visual preview.",
|
|
450
|
-
color: "red"
|
|
451
|
-
});
|
|
452
|
-
return feedback;
|
|
453
|
-
}
|
|
454
|
-
feedback.push({ text: "OG image URL is set \u2014 good for social sharing.", color: "green" });
|
|
455
|
-
const metaSet = isMetaImageSet(seoParent);
|
|
456
|
-
const twSet = isSubImageSet(seoParent == null ? void 0 : seoParent.twitter);
|
|
457
|
-
if (metaSet && twSet) {
|
|
458
|
-
feedback.push({ text: "All images set (Meta, OG, Twitter) \u2014 full coverage!", color: "green" });
|
|
459
|
-
} else {
|
|
460
|
-
if (!metaSet)
|
|
461
|
-
feedback.push({
|
|
462
|
-
text: "Meta image is missing \u2014 add it for search engine results.",
|
|
463
|
-
color: "orange"
|
|
464
|
-
});
|
|
465
|
-
if (!twSet)
|
|
466
|
-
feedback.push({
|
|
467
|
-
text: "Twitter image is missing \u2014 add it for X (Twitter) cards.",
|
|
468
|
-
color: "orange"
|
|
469
|
-
});
|
|
470
|
-
}
|
|
471
|
-
return feedback;
|
|
472
|
-
};
|
|
473
|
-
getTwitterImageValidation = (hasImage, altText, seoParent) => {
|
|
474
|
-
const feedback = [];
|
|
475
|
-
if (!hasImage) {
|
|
476
|
-
feedback.push({
|
|
477
|
-
text: "No Twitter image provided. Posts on X will lack a visual.",
|
|
478
|
-
color: "red"
|
|
479
|
-
});
|
|
480
|
-
return feedback;
|
|
481
|
-
}
|
|
482
|
-
feedback.push({ text: "Twitter image is set \u2014 good for X sharing.", color: "green" });
|
|
483
|
-
if (altText == null ? void 0 : altText.trim()) {
|
|
484
|
-
feedback.push({ text: "Alt text is set \u2014 good for accessibility.", color: "green" });
|
|
485
|
-
} else {
|
|
486
|
-
feedback.push({ text: "Consider adding alt text for better accessibility.", color: "orange" });
|
|
487
|
-
}
|
|
488
|
-
const metaSet = isMetaImageSet(seoParent);
|
|
489
|
-
const ogSet = isSubImageSet(seoParent == null ? void 0 : seoParent.openGraph);
|
|
490
|
-
if (metaSet && ogSet) {
|
|
491
|
-
feedback.push({ text: "All images set (Meta, OG, Twitter) \u2014 full coverage!", color: "green" });
|
|
492
|
-
} else {
|
|
493
|
-
if (!metaSet)
|
|
494
|
-
feedback.push({
|
|
495
|
-
text: "Meta image is missing \u2014 add it for search engine results.",
|
|
496
|
-
color: "orange"
|
|
497
|
-
});
|
|
498
|
-
if (!ogSet)
|
|
499
|
-
feedback.push({
|
|
500
|
-
text: "OG image is missing \u2014 add it for Facebook/LinkedIn sharing.",
|
|
501
|
-
color: "orange"
|
|
502
|
-
});
|
|
503
|
-
}
|
|
504
|
-
return feedback;
|
|
505
|
-
};
|
|
506
|
-
getTwitterImageUrlValidation = (imageUrl, seoParent) => {
|
|
507
|
-
const feedback = [];
|
|
508
|
-
if (!(imageUrl == null ? void 0 : imageUrl.trim())) {
|
|
509
|
-
feedback.push({
|
|
510
|
-
text: "No Twitter image URL provided. Posts on X will lack a visual.",
|
|
511
|
-
color: "red"
|
|
512
|
-
});
|
|
513
|
-
return feedback;
|
|
514
|
-
}
|
|
515
|
-
feedback.push({ text: "Twitter image URL is set \u2014 good for X sharing.", color: "green" });
|
|
516
|
-
const metaSet = isMetaImageSet(seoParent);
|
|
517
|
-
const ogSet = isSubImageSet(seoParent == null ? void 0 : seoParent.openGraph);
|
|
518
|
-
if (metaSet && ogSet) {
|
|
519
|
-
feedback.push({ text: "All images set (Meta, OG, Twitter) \u2014 full coverage!", color: "green" });
|
|
520
|
-
} else {
|
|
521
|
-
if (!metaSet)
|
|
522
|
-
feedback.push({
|
|
523
|
-
text: "Meta image is missing \u2014 add it for search engine results.",
|
|
524
|
-
color: "orange"
|
|
525
|
-
});
|
|
526
|
-
if (!ogSet)
|
|
527
|
-
feedback.push({
|
|
528
|
-
text: "OG image is missing \u2014 add it for Facebook/LinkedIn sharing.",
|
|
529
|
-
color: "orange"
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
|
-
return feedback;
|
|
533
|
-
};
|
|
534
|
-
}
|
|
535
|
-
});
|
|
536
|
-
|
|
537
|
-
// src/components/SeoPreview.tsx
|
|
538
|
-
var SeoPreview_exports = {};
|
|
539
|
-
__export(SeoPreview_exports, {
|
|
540
|
-
default: () => SeoPreview_default
|
|
541
|
-
});
|
|
542
|
-
var import_ui12, import_sanity14, import_styled_components, import_jsx_runtime12, PreviewContainer, PreviewHeader, PreviewBody, SerpUrl, SerpTitle, SerpDescription, LiveIndicator, SeoPreview, SeoPreview_default;
|
|
543
|
-
var init_SeoPreview = __esm({
|
|
544
|
-
"src/components/SeoPreview.tsx"() {
|
|
545
|
-
"use strict";
|
|
546
|
-
import_ui12 = require("@sanity/ui");
|
|
547
|
-
import_sanity14 = require("sanity");
|
|
548
|
-
import_styled_components = __toESM(require("styled-components"), 1);
|
|
549
|
-
init_seoUtils();
|
|
550
|
-
import_jsx_runtime12 = require("react/jsx-runtime");
|
|
551
|
-
PreviewContainer = import_styled_components.default.div`
|
|
552
|
-
max-width: 600px;
|
|
553
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
554
|
-
background: #ffffff;
|
|
555
|
-
border: 1px solid #dadce0;
|
|
556
|
-
border-radius: 8px;
|
|
557
|
-
overflow: hidden;
|
|
558
|
-
`;
|
|
559
|
-
PreviewHeader = import_styled_components.default.div`
|
|
560
|
-
background: #f8f9fa;
|
|
561
|
-
padding: 12px 16px;
|
|
562
|
-
border-bottom: 1px solid #dadce0;
|
|
563
|
-
display: flex;
|
|
564
|
-
align-items: center;
|
|
565
|
-
justify-content: space-between;
|
|
566
|
-
gap: 8px;
|
|
567
|
-
`;
|
|
568
|
-
PreviewBody = import_styled_components.default.div`
|
|
569
|
-
padding: 16px;
|
|
570
|
-
`;
|
|
571
|
-
SerpUrl = import_styled_components.default.p`
|
|
572
|
-
margin: 0 0 4px;
|
|
573
|
-
color: #006621;
|
|
574
|
-
font-size: 13px;
|
|
575
|
-
line-height: 1.4;
|
|
576
|
-
word-break: break-word;
|
|
577
|
-
`;
|
|
578
|
-
SerpTitle = import_styled_components.default.h3`
|
|
579
|
-
margin: 0 0 8px;
|
|
580
|
-
color: #1a0dab;
|
|
581
|
-
font-size: 18px;
|
|
582
|
-
font-weight: 500;
|
|
583
|
-
line-height: 1.4;
|
|
584
|
-
word-break: break-word;
|
|
585
|
-
|
|
586
|
-
&:hover {
|
|
587
|
-
text-decoration: underline;
|
|
588
|
-
}
|
|
589
|
-
`;
|
|
590
|
-
SerpDescription = import_styled_components.default.p`
|
|
591
|
-
margin: 0;
|
|
592
|
-
color: #545454;
|
|
593
|
-
font-size: 14px;
|
|
594
|
-
line-height: 1.6;
|
|
595
|
-
word-break: break-word;
|
|
596
|
-
display: -webkit-box;
|
|
597
|
-
-webkit-line-clamp: 2;
|
|
598
|
-
-webkit-box-orient: vertical;
|
|
599
|
-
overflow: hidden;
|
|
600
|
-
`;
|
|
601
|
-
LiveIndicator = import_styled_components.default.span`
|
|
602
|
-
display: inline-flex;
|
|
603
|
-
align-items: center;
|
|
604
|
-
gap: 4px;
|
|
605
|
-
font-size: 11px;
|
|
606
|
-
font-weight: 600;
|
|
607
|
-
text-transform: uppercase;
|
|
608
|
-
letter-spacing: 0.05em;
|
|
609
|
-
color: #4f46e5;
|
|
610
|
-
background: #f0f4ff;
|
|
611
|
-
padding: 4px 8px;
|
|
612
|
-
border-radius: 4px;
|
|
613
|
-
`;
|
|
614
|
-
SeoPreview = (props) => {
|
|
615
|
-
var _a, _b;
|
|
616
|
-
const { path, schemaType } = props;
|
|
617
|
-
const { options } = schemaType;
|
|
618
|
-
const baseUrl = (options == null ? void 0 : options.baseUrl) || "https://www.example.com";
|
|
619
|
-
const prefixFunction = options == null ? void 0 : options.prefix;
|
|
620
|
-
const parent = (0, import_sanity14.useFormValue)([path[0]]) || {
|
|
621
|
-
title: "",
|
|
622
|
-
description: "",
|
|
623
|
-
canonicalUrl: ""
|
|
624
|
-
};
|
|
625
|
-
const rootDoc = (0, import_sanity14.useFormValue)([]) || {
|
|
626
|
-
slug: { current: "" }
|
|
627
|
-
};
|
|
628
|
-
const slug = ((_a = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _a.current) || "";
|
|
629
|
-
const {
|
|
630
|
-
title,
|
|
631
|
-
description,
|
|
632
|
-
canonicalUrl: url
|
|
633
|
-
} = parent;
|
|
634
|
-
const base = (_b = url || baseUrl) == null ? void 0 : _b.replace(/\/+$/, "");
|
|
635
|
-
const slugStr = String(slug || "").replace(/^\/+/, "");
|
|
636
|
-
const pref = String(
|
|
637
|
-
prefixFunction ? prefixFunction(rootDoc) : ""
|
|
638
|
-
).replace(/^\/+|\/+$/g, "");
|
|
639
|
-
const urlPath = [pref, slugStr].filter(Boolean).join("/");
|
|
640
|
-
const finalUrl = urlPath ? `${base}/${urlPath}` : base;
|
|
641
|
-
const domain = (() => {
|
|
642
|
-
try {
|
|
643
|
-
const u = new URL(finalUrl || base);
|
|
644
|
-
return u.hostname;
|
|
645
|
-
} catch (e) {
|
|
646
|
-
return "example.com";
|
|
647
|
-
}
|
|
648
|
-
})();
|
|
649
|
-
const urlDisplay = `${domain}${urlPath ? ` \u203A ${urlPath.split("/").slice(-1)[0]}` : ""}`;
|
|
650
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ui12.Box, { padding: 3, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(PreviewContainer, { children: [
|
|
651
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(PreviewHeader, { children: [
|
|
652
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
653
|
-
"span",
|
|
654
|
-
{
|
|
655
|
-
style: {
|
|
656
|
-
fontSize: "11px",
|
|
657
|
-
color: "#5f6368",
|
|
658
|
-
textTransform: "uppercase",
|
|
659
|
-
letterSpacing: "0.05em"
|
|
660
|
-
},
|
|
661
|
-
children: "Search Preview"
|
|
662
|
-
}
|
|
663
|
-
),
|
|
664
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(LiveIndicator, { children: [
|
|
665
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
666
|
-
"span",
|
|
667
|
-
{
|
|
668
|
-
style: {
|
|
669
|
-
width: "4px",
|
|
670
|
-
height: "4px",
|
|
671
|
-
borderRadius: "50%",
|
|
672
|
-
backgroundColor: "#4f46e5",
|
|
673
|
-
display: "inline-block"
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
),
|
|
677
|
-
"Live"
|
|
678
|
-
] })
|
|
679
|
-
] }),
|
|
680
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(PreviewBody, { children: [
|
|
681
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SerpUrl, { children: finalUrl ? urlDisplay : "example.com \u203A page-url" }),
|
|
682
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SerpTitle, { children: title && title.length > 0 ? truncate(title, 60) : "Your SEO Title will appear here" }),
|
|
683
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SerpDescription, { children: description && description.length > 0 ? truncate(description, 160) : "Your meta description will show up here. Make it compelling!" })
|
|
684
|
-
] })
|
|
685
|
-
] }) });
|
|
686
|
-
};
|
|
687
|
-
SeoPreview_default = SeoPreview;
|
|
688
|
-
}
|
|
689
|
-
});
|
|
690
|
-
|
|
691
|
-
// src/components/SeoHealthDashboard.tsx
|
|
692
|
-
var SeoHealthDashboard_exports = {};
|
|
693
|
-
__export(SeoHealthDashboard_exports, {
|
|
694
|
-
default: () => SeoHealthDashboard_default
|
|
695
|
-
});
|
|
696
|
-
var import_react13, import_sanity19, import_router, import_structure, import_styled_components2, import_jsx_runtime13, DashboardContainer, PageHeader, PageTitle, PreviewBadge, PageSubtitle, StatsGrid, StatCard, StatLabel, StatValue, ControlsBar, SearchWrapper, SearchIconSvg, SearchInput, StyledSelect, TableCard, TableHeader, TableRow, ColTitle, TitleWrapper, TitleCell, ColType, ColScore, ColIssues, DocTitleLink, DocId, TypeBadge, TypeText, CustomBadge, ScoreBadge, IssueTag, NonStringTitleWarning, MoreIssues, MoreIssuesWrapper, IssuesPopover, PopoverIssueItem, UpgradeContainer, UpgradeBox, UpgradeLock, UpgradeTitle, UpgradeText, UpgradeCode, UpgradeButton, ReloadButton, spin, DashboardRefreshButton, DocTitleAnchor, PaneLinkWrapper, DocTitleAnchorPane, DocBadgeRenderer, Spinner, LoadingState, EmptyState, DeprecationBanner, DeprecationBannerLink, TYPE_COLOR_PALETTE, getTypeColor, getStatusCategory, scoreMetaTitle, scoreMetaDescription, scoreOpenGraph, scoreTwitterCard, calculateHealthScore, resolveTypeLabel, buildTitleProjection, generateDummyData, SeoHealthDashboard, SeoHealthDashboard_default;
|
|
697
|
-
var init_SeoHealthDashboard = __esm({
|
|
698
|
-
"src/components/SeoHealthDashboard.tsx"() {
|
|
699
|
-
"use strict";
|
|
700
|
-
import_react13 = require("react");
|
|
701
|
-
import_sanity19 = require("sanity");
|
|
702
|
-
import_router = require("sanity/router");
|
|
703
|
-
import_structure = require("sanity/structure");
|
|
704
|
-
import_styled_components2 = __toESM(require("styled-components"), 1);
|
|
705
|
-
import_jsx_runtime13 = require("react/jsx-runtime");
|
|
706
|
-
DashboardContainer = import_styled_components2.default.div`
|
|
707
|
-
width: 100%;
|
|
708
|
-
min-height: 100%;
|
|
709
|
-
background: #f0f2f5;
|
|
710
|
-
padding: 28px 32px;
|
|
711
|
-
box-sizing: border-box;
|
|
712
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
713
|
-
`;
|
|
714
|
-
PageHeader = import_styled_components2.default.div`
|
|
715
|
-
display: flex;
|
|
716
|
-
align-items: flex-start;
|
|
717
|
-
justify-content: space-between;
|
|
718
|
-
gap: 12px;
|
|
719
|
-
margin-bottom: 28px;
|
|
720
|
-
`;
|
|
721
|
-
PageTitle = import_styled_components2.default.h1`
|
|
722
|
-
margin: 0 0 6px 0;
|
|
723
|
-
font-size: 22px;
|
|
724
|
-
font-weight: 700;
|
|
725
|
-
color: #111827;
|
|
726
|
-
letter-spacing: -0.3px;
|
|
727
|
-
display: flex;
|
|
728
|
-
align-items: center;
|
|
729
|
-
gap: 10px;
|
|
730
|
-
`;
|
|
731
|
-
PreviewBadge = import_styled_components2.default.span`
|
|
732
|
-
display: inline-block;
|
|
733
|
-
background: #fef3c7;
|
|
734
|
-
color: #92400e;
|
|
735
|
-
font-size: 11px;
|
|
736
|
-
font-weight: 600;
|
|
737
|
-
padding: 4px 8px;
|
|
738
|
-
border-radius: 4px;
|
|
739
|
-
text-transform: uppercase;
|
|
740
|
-
letter-spacing: 0.5px;
|
|
741
|
-
margin-left: 8px;
|
|
742
|
-
`;
|
|
743
|
-
PageSubtitle = import_styled_components2.default.p`
|
|
744
|
-
margin: 0;
|
|
745
|
-
font-size: 13px;
|
|
746
|
-
color: #6b7280;
|
|
747
|
-
`;
|
|
748
|
-
StatsGrid = import_styled_components2.default.div`
|
|
749
|
-
display: grid;
|
|
750
|
-
grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
|
|
751
|
-
gap: 14px;
|
|
752
|
-
margin-bottom: 20px;
|
|
753
|
-
`;
|
|
754
|
-
StatCard = import_styled_components2.default.div`
|
|
755
|
-
background: #ffffff;
|
|
756
|
-
border-radius: 10px;
|
|
757
|
-
padding: 16px 18px;
|
|
758
|
-
box-shadow:
|
|
759
|
-
0 1px 3px rgba(0, 0, 0, 0.07),
|
|
760
|
-
0 1px 2px rgba(0, 0, 0, 0.05);
|
|
761
|
-
border-left: ${(p) => p.$accent ? `4px solid ${p.$accent}` : "4px solid transparent"};
|
|
762
|
-
transition: box-shadow 0.15s ease;
|
|
763
|
-
|
|
764
|
-
&:hover {
|
|
765
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
766
|
-
}
|
|
767
|
-
`;
|
|
768
|
-
StatLabel = import_styled_components2.default.div`
|
|
769
|
-
font-size: 11px;
|
|
770
|
-
font-weight: 500;
|
|
771
|
-
color: #9ca3af;
|
|
772
|
-
text-transform: uppercase;
|
|
773
|
-
letter-spacing: 0.5px;
|
|
774
|
-
margin-bottom: 8px;
|
|
775
|
-
`;
|
|
776
|
-
StatValue = import_styled_components2.default.div`
|
|
777
|
-
font-size: 26px;
|
|
778
|
-
font-weight: 700;
|
|
779
|
-
color: #111827;
|
|
780
|
-
line-height: 1;
|
|
781
|
-
`;
|
|
782
|
-
ControlsBar = import_styled_components2.default.div`
|
|
783
|
-
background: #ffffff;
|
|
784
|
-
border-radius: 10px;
|
|
785
|
-
padding: 14px 18px;
|
|
786
|
-
display: flex;
|
|
787
|
-
align-items: center;
|
|
788
|
-
gap: 12px;
|
|
789
|
-
flex-wrap: wrap;
|
|
790
|
-
margin-bottom: 20px;
|
|
791
|
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.07);
|
|
792
|
-
`;
|
|
793
|
-
SearchWrapper = import_styled_components2.default.div`
|
|
794
|
-
position: relative;
|
|
795
|
-
flex: 1;
|
|
796
|
-
min-width: 220px;
|
|
797
|
-
`;
|
|
798
|
-
SearchIconSvg = import_styled_components2.default.span`
|
|
799
|
-
position: absolute;
|
|
800
|
-
left: 11px;
|
|
801
|
-
top: 50%;
|
|
802
|
-
transform: translateY(-50%);
|
|
803
|
-
color: #9ca3af;
|
|
804
|
-
display: flex;
|
|
805
|
-
align-items: center;
|
|
806
|
-
pointer-events: none;
|
|
807
|
-
`;
|
|
808
|
-
SearchInput = import_styled_components2.default.input`
|
|
809
|
-
width: 100%;
|
|
810
|
-
height: 36px;
|
|
811
|
-
padding: 0 12px 0 34px;
|
|
812
|
-
border: 1px solid #e5e7eb;
|
|
813
|
-
border-radius: 7px;
|
|
814
|
-
font-size: 13px;
|
|
815
|
-
color: #111827;
|
|
816
|
-
background: #f9fafb;
|
|
817
|
-
box-sizing: border-box;
|
|
818
|
-
outline: none;
|
|
819
|
-
transition:
|
|
820
|
-
border-color 0.15s,
|
|
821
|
-
background 0.15s;
|
|
822
|
-
|
|
823
|
-
&::placeholder {
|
|
824
|
-
color: #9ca3af;
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
&:focus {
|
|
828
|
-
border-color: #6366f1;
|
|
829
|
-
background: #fff;
|
|
830
|
-
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
|
|
831
|
-
}
|
|
832
|
-
`;
|
|
833
|
-
StyledSelect = import_styled_components2.default.select`
|
|
834
|
-
height: 36px;
|
|
835
|
-
padding: 0 32px 0 12px;
|
|
836
|
-
border: 1px solid #e5e7eb;
|
|
837
|
-
border-radius: 7px;
|
|
838
|
-
font-size: 13px;
|
|
839
|
-
color: #374151;
|
|
840
|
-
background: #f9fafb
|
|
841
|
-
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236b7280' d='M6 8L1 3h10z'/%3E%3C/svg%3E")
|
|
842
|
-
no-repeat right 10px center;
|
|
843
|
-
appearance: none;
|
|
844
|
-
outline: none;
|
|
845
|
-
cursor: pointer;
|
|
846
|
-
transition: border-color 0.15s;
|
|
1
|
+
'use strict';
|
|
847
2
|
|
|
848
|
-
|
|
849
|
-
border-color: #6366f1;
|
|
850
|
-
background-color: #fff;
|
|
851
|
-
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
|
|
852
|
-
}
|
|
853
|
-
`;
|
|
854
|
-
TableCard = import_styled_components2.default.div`
|
|
855
|
-
background: #ffffff;
|
|
856
|
-
border-radius: 10px;
|
|
857
|
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.07);
|
|
858
|
-
overflow: hidden;
|
|
859
|
-
`;
|
|
860
|
-
TableHeader = import_styled_components2.default.div`
|
|
861
|
-
display: flex;
|
|
862
|
-
align-items: center;
|
|
863
|
-
padding: 11px 20px;
|
|
864
|
-
background: #f9fafb;
|
|
865
|
-
border-bottom: 1px solid #e5e7eb;
|
|
866
|
-
font-size: 11px;
|
|
867
|
-
font-weight: 600;
|
|
868
|
-
color: #6b7280;
|
|
869
|
-
text-transform: uppercase;
|
|
870
|
-
letter-spacing: 0.5px;
|
|
871
|
-
gap: 12px;
|
|
872
|
-
`;
|
|
873
|
-
TableRow = import_styled_components2.default.div`
|
|
874
|
-
display: flex;
|
|
875
|
-
align-items: center;
|
|
876
|
-
padding: 13px 20px;
|
|
877
|
-
border-bottom: 1px solid #f3f4f6;
|
|
878
|
-
gap: 12px;
|
|
879
|
-
transition: background 0.1s;
|
|
880
|
-
|
|
881
|
-
&:last-child {
|
|
882
|
-
border-bottom: none;
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
&:hover {
|
|
886
|
-
background: #fafafa;
|
|
887
|
-
}
|
|
888
|
-
`;
|
|
889
|
-
ColTitle = import_styled_components2.default.div`
|
|
890
|
-
flex: 2;
|
|
891
|
-
min-width: 0;
|
|
892
|
-
`;
|
|
893
|
-
TitleWrapper = import_styled_components2.default.div`
|
|
894
|
-
display: flex;
|
|
895
|
-
align-items: center;
|
|
896
|
-
gap: 4px;
|
|
897
|
-
flex-wrap: wrap;
|
|
898
|
-
min-width: 0;
|
|
899
|
-
`;
|
|
900
|
-
TitleCell = import_styled_components2.default.div`
|
|
901
|
-
min-width: 0;
|
|
902
|
-
overflow: hidden;
|
|
903
|
-
flex: 1;
|
|
904
|
-
`;
|
|
905
|
-
ColType = import_styled_components2.default.div`
|
|
906
|
-
flex: 0.8;
|
|
907
|
-
min-width: 80px;
|
|
908
|
-
`;
|
|
909
|
-
ColScore = import_styled_components2.default.div`
|
|
910
|
-
flex: 0.6;
|
|
911
|
-
min-width: 70px;
|
|
912
|
-
`;
|
|
913
|
-
ColIssues = import_styled_components2.default.div`
|
|
914
|
-
flex: 2;
|
|
915
|
-
min-width: 0;
|
|
916
|
-
`;
|
|
917
|
-
DocTitleLink = import_styled_components2.default.a`
|
|
918
|
-
font-size: 13px;
|
|
919
|
-
font-weight: 600;
|
|
920
|
-
color: #4f46e5;
|
|
921
|
-
white-space: nowrap;
|
|
922
|
-
overflow: hidden;
|
|
923
|
-
text-overflow: ellipsis;
|
|
924
|
-
text-decoration: none;
|
|
925
|
-
display: block;
|
|
926
|
-
transition: color 0.15s;
|
|
927
|
-
|
|
928
|
-
&:hover {
|
|
929
|
-
color: #4338ca;
|
|
930
|
-
text-decoration: underline;
|
|
931
|
-
}
|
|
932
|
-
`;
|
|
933
|
-
DocId = import_styled_components2.default.div`
|
|
934
|
-
font-size: 11px;
|
|
935
|
-
color: #9ca3af;
|
|
936
|
-
margin-top: 2px;
|
|
937
|
-
white-space: nowrap;
|
|
938
|
-
overflow: hidden;
|
|
939
|
-
text-overflow: ellipsis;
|
|
940
|
-
`;
|
|
941
|
-
TypeBadge = import_styled_components2.default.span`
|
|
942
|
-
display: inline-block;
|
|
943
|
-
padding: 3px 8px;
|
|
944
|
-
border-radius: 5px;
|
|
945
|
-
font-size: 11px;
|
|
946
|
-
font-weight: 500;
|
|
947
|
-
background: ${(p) => p.$bgColor || "#ede9fe"};
|
|
948
|
-
color: ${(p) => p.$textColor || "#5b21b6"};
|
|
949
|
-
`;
|
|
950
|
-
TypeText = import_styled_components2.default.span`
|
|
951
|
-
font-size: 12px;
|
|
952
|
-
font-weight: 500;
|
|
953
|
-
color: #374151;
|
|
954
|
-
`;
|
|
955
|
-
CustomBadge = import_styled_components2.default.span`
|
|
956
|
-
display: inline-block;
|
|
957
|
-
padding: 2px 6px;
|
|
958
|
-
border-radius: 4px;
|
|
959
|
-
font-size: ${(p) => p.$fontSize || "10px"};
|
|
960
|
-
font-weight: 600;
|
|
961
|
-
background: ${(p) => p.$bgColor || "#e0e7ff"};
|
|
962
|
-
color: ${(p) => p.$textColor || "#3730a3"};
|
|
963
|
-
white-space: nowrap;
|
|
964
|
-
`;
|
|
965
|
-
ScoreBadge = import_styled_components2.default.span`
|
|
966
|
-
display: inline-block;
|
|
967
|
-
padding: 4px 10px;
|
|
968
|
-
border-radius: 6px;
|
|
969
|
-
font-size: 12px;
|
|
970
|
-
font-weight: 700;
|
|
971
|
-
background: ${(p) => {
|
|
972
|
-
if (p.$score >= 80) return "#d1fae5";
|
|
973
|
-
if (p.$score >= 60) return "#fef3c7";
|
|
974
|
-
if (p.$score >= 40) return "#ffedd5";
|
|
975
|
-
return "#fee2e2";
|
|
976
|
-
}};
|
|
977
|
-
color: ${(p) => {
|
|
978
|
-
if (p.$score >= 80) return "#065f46";
|
|
979
|
-
if (p.$score >= 60) return "#92400e";
|
|
980
|
-
if (p.$score >= 40) return "#9a3412";
|
|
981
|
-
return "#991b1b";
|
|
982
|
-
}};
|
|
983
|
-
`;
|
|
984
|
-
IssueTag = import_styled_components2.default.div`
|
|
985
|
-
font-size: 11px;
|
|
986
|
-
color: #ef4444;
|
|
987
|
-
line-height: 1.5;
|
|
988
|
-
white-space: nowrap;
|
|
989
|
-
overflow: hidden;
|
|
990
|
-
text-overflow: ellipsis;
|
|
991
|
-
`;
|
|
992
|
-
NonStringTitleWarning = import_styled_components2.default.div`
|
|
993
|
-
display: inline-flex;
|
|
994
|
-
align-items: center;
|
|
995
|
-
gap: 4px;
|
|
996
|
-
margin-top: 4px;
|
|
997
|
-
padding: 2px 7px;
|
|
998
|
-
border-radius: 4px;
|
|
999
|
-
background: #fef3c7;
|
|
1000
|
-
border: 1px solid #fcd34d;
|
|
1001
|
-
font-size: 10px;
|
|
1002
|
-
font-weight: 600;
|
|
1003
|
-
color: #92400e;
|
|
1004
|
-
line-height: 1.4;
|
|
1005
|
-
cursor: default;
|
|
1006
|
-
white-space: normal;
|
|
1007
|
-
`;
|
|
1008
|
-
MoreIssues = import_styled_components2.default.div`
|
|
1009
|
-
font-size: 11px;
|
|
1010
|
-
color: #6b7280;
|
|
1011
|
-
cursor: pointer;
|
|
1012
|
-
transition: color 0.15s;
|
|
1013
|
-
|
|
1014
|
-
&:hover {
|
|
1015
|
-
color: #374151;
|
|
1016
|
-
}
|
|
1017
|
-
`;
|
|
1018
|
-
MoreIssuesWrapper = import_styled_components2.default.div`
|
|
1019
|
-
position: relative;
|
|
1020
|
-
display: inline-block;
|
|
1021
|
-
`;
|
|
1022
|
-
IssuesPopover = import_styled_components2.default.div`
|
|
1023
|
-
position: fixed;
|
|
1024
|
-
bottom: auto;
|
|
1025
|
-
left: 0;
|
|
1026
|
-
transform: translateY(calc(-100% - 14px));
|
|
1027
|
-
background: #1f2937;
|
|
1028
|
-
color: #ffffff;
|
|
1029
|
-
padding: 12px;
|
|
1030
|
-
border-radius: 8px;
|
|
1031
|
-
font-size: 12px;
|
|
1032
|
-
z-index: 50;
|
|
1033
|
-
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
|
1034
|
-
width: 280px;
|
|
1035
|
-
word-break: break-word;
|
|
1036
|
-
line-height: 1.5;
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
1037
4
|
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
height: 0;
|
|
1045
|
-
border-left: 6px solid transparent;
|
|
1046
|
-
border-right: 6px solid transparent;
|
|
1047
|
-
border-top: 6px solid #1f2937;
|
|
1048
|
-
}
|
|
1049
|
-
`;
|
|
1050
|
-
PopoverIssueItem = import_styled_components2.default.div`
|
|
1051
|
-
display: flex;
|
|
1052
|
-
gap: 6px;
|
|
1053
|
-
margin-bottom: 6px;
|
|
5
|
+
var chunkIFDLKZET_cjs = require('./chunk-IFDLKZET.cjs');
|
|
6
|
+
var chunkS367Y35J_cjs = require('./chunk-S367Y35J.cjs');
|
|
7
|
+
var React12 = require('react');
|
|
8
|
+
var sanity = require('sanity');
|
|
9
|
+
var ui = require('@sanity/ui');
|
|
10
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
1054
11
|
|
|
1055
|
-
|
|
1056
|
-
margin-bottom: 0;
|
|
1057
|
-
}
|
|
1058
|
-
`;
|
|
1059
|
-
UpgradeContainer = import_styled_components2.default.div`
|
|
1060
|
-
display: flex;
|
|
1061
|
-
align-items: center;
|
|
1062
|
-
justify-content: center;
|
|
1063
|
-
min-height: 100%;
|
|
1064
|
-
padding: 60px 24px;
|
|
1065
|
-
`;
|
|
1066
|
-
UpgradeBox = import_styled_components2.default.div`
|
|
1067
|
-
background: #ffffff;
|
|
1068
|
-
border-radius: 16px;
|
|
1069
|
-
padding: 48px 40px;
|
|
1070
|
-
max-width: 480px;
|
|
1071
|
-
width: 100%;
|
|
1072
|
-
text-align: center;
|
|
1073
|
-
box-shadow:
|
|
1074
|
-
0 4px 24px rgba(0, 0, 0, 0.08),
|
|
1075
|
-
0 1px 4px rgba(0, 0, 0, 0.05);
|
|
1076
|
-
border: 1px solid #e5e7eb;
|
|
1077
|
-
`;
|
|
1078
|
-
UpgradeLock = import_styled_components2.default.div`
|
|
1079
|
-
font-size: 40px;
|
|
1080
|
-
margin-bottom: 16px;
|
|
1081
|
-
`;
|
|
1082
|
-
UpgradeTitle = import_styled_components2.default.h2`
|
|
1083
|
-
margin: 0 0 10px;
|
|
1084
|
-
font-size: 20px;
|
|
1085
|
-
font-weight: 700;
|
|
1086
|
-
color: #111827;
|
|
1087
|
-
`;
|
|
1088
|
-
UpgradeText = import_styled_components2.default.p`
|
|
1089
|
-
margin: 0 0 20px;
|
|
1090
|
-
font-size: 14px;
|
|
1091
|
-
color: #6b7280;
|
|
1092
|
-
line-height: 1.6;
|
|
1093
|
-
`;
|
|
1094
|
-
UpgradeCode = import_styled_components2.default.pre`
|
|
1095
|
-
background: #f3f4f6;
|
|
1096
|
-
border-radius: 8px;
|
|
1097
|
-
padding: 14px 16px;
|
|
1098
|
-
font-size: 12px;
|
|
1099
|
-
color: #374151;
|
|
1100
|
-
text-align: left;
|
|
1101
|
-
margin: 0 0 24px;
|
|
1102
|
-
overflow-x: auto;
|
|
1103
|
-
line-height: 1.6;
|
|
1104
|
-
border: 1px solid #e5e7eb;
|
|
1105
|
-
`;
|
|
1106
|
-
UpgradeButton = import_styled_components2.default.a`
|
|
1107
|
-
display: inline-block;
|
|
1108
|
-
background: #4f46e5;
|
|
1109
|
-
color: #ffffff;
|
|
1110
|
-
font-size: 14px;
|
|
1111
|
-
font-weight: 600;
|
|
1112
|
-
padding: 10px 24px;
|
|
1113
|
-
border-radius: 8px;
|
|
1114
|
-
text-decoration: none;
|
|
1115
|
-
transition: background 0.15s;
|
|
12
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
1116
13
|
|
|
1117
|
-
|
|
1118
|
-
background: #4338ca;
|
|
1119
|
-
}
|
|
1120
|
-
`;
|
|
1121
|
-
ReloadButton = import_styled_components2.default.button`
|
|
1122
|
-
display: inline-block;
|
|
1123
|
-
background: transparent;
|
|
1124
|
-
color: #6b7280;
|
|
1125
|
-
font-size: 13px;
|
|
1126
|
-
font-weight: 500;
|
|
1127
|
-
padding: 8px 20px;
|
|
1128
|
-
border-radius: 8px;
|
|
1129
|
-
border: 1px solid #d1d5db;
|
|
1130
|
-
cursor: pointer;
|
|
1131
|
-
margin-top: 10px;
|
|
1132
|
-
transition:
|
|
1133
|
-
background 0.15s,
|
|
1134
|
-
color 0.15s,
|
|
1135
|
-
border-color 0.15s;
|
|
14
|
+
var React12__default = /*#__PURE__*/_interopDefault(React12);
|
|
1136
15
|
|
|
1137
|
-
&:hover {
|
|
1138
|
-
background: #f3f4f6;
|
|
1139
|
-
color: #374151;
|
|
1140
|
-
border-color: #9ca3af;
|
|
1141
|
-
}
|
|
1142
|
-
`;
|
|
1143
|
-
spin = import_styled_components2.keyframes`
|
|
1144
|
-
to { transform: rotate(360deg); }
|
|
1145
|
-
`;
|
|
1146
|
-
DashboardRefreshButton = import_styled_components2.default.button`
|
|
1147
|
-
display: inline-flex;
|
|
1148
|
-
align-items: center;
|
|
1149
|
-
gap: 6px;
|
|
1150
|
-
background: #ffffff;
|
|
1151
|
-
color: #374151;
|
|
1152
|
-
font-size: 13px;
|
|
1153
|
-
font-weight: 500;
|
|
1154
|
-
padding: 8px 14px;
|
|
1155
|
-
border-radius: 8px;
|
|
1156
|
-
border: 1px solid #d1d5db;
|
|
1157
|
-
cursor: pointer;
|
|
1158
|
-
flex-shrink: 0;
|
|
1159
|
-
transition:
|
|
1160
|
-
background 0.15s,
|
|
1161
|
-
color 0.15s,
|
|
1162
|
-
border-color 0.15s,
|
|
1163
|
-
box-shadow 0.15s;
|
|
1164
|
-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
1165
|
-
|
|
1166
|
-
svg {
|
|
1167
|
-
animation: ${(p) => p.$spinning ? import_styled_components2.css`
|
|
1168
|
-
${spin} 0.7s linear infinite
|
|
1169
|
-
` : "none"};
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
&:hover {
|
|
1173
|
-
background: #f3f4f6;
|
|
1174
|
-
border-color: #9ca3af;
|
|
1175
|
-
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
&:disabled {
|
|
1179
|
-
opacity: 0.6;
|
|
1180
|
-
cursor: not-allowed;
|
|
1181
|
-
}
|
|
1182
|
-
`;
|
|
1183
|
-
DocTitleAnchor = ({ id, type, structureTool, children }) => {
|
|
1184
|
-
const { basePath } = (0, import_sanity19.useWorkspace)();
|
|
1185
|
-
const { onClick: intentOnClick, href: intentHref } = (0, import_router.useIntentLink)({
|
|
1186
|
-
intent: "edit",
|
|
1187
|
-
params: { id, type }
|
|
1188
|
-
});
|
|
1189
|
-
const href = structureTool ? `${basePath}/${structureTool}/intent/edit/id=${id};type=${type}/` : intentHref;
|
|
1190
|
-
const onClick = structureTool ? void 0 : intentOnClick;
|
|
1191
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DocTitleLink, { href, onClick, title: "Open document", children });
|
|
1192
|
-
};
|
|
1193
|
-
PaneLinkWrapper = import_styled_components2.default.span`
|
|
1194
|
-
display: block;
|
|
1195
|
-
min-width: 0;
|
|
1196
|
-
overflow: hidden;
|
|
1197
|
-
|
|
1198
|
-
a {
|
|
1199
|
-
font-size: 13px;
|
|
1200
|
-
font-weight: 600;
|
|
1201
|
-
color: #4f46e5;
|
|
1202
|
-
white-space: nowrap;
|
|
1203
|
-
overflow: hidden;
|
|
1204
|
-
text-overflow: ellipsis;
|
|
1205
|
-
text-decoration: none;
|
|
1206
|
-
display: block;
|
|
1207
|
-
transition: color 0.15s;
|
|
1208
|
-
|
|
1209
|
-
&:hover {
|
|
1210
|
-
color: #4338ca;
|
|
1211
|
-
text-decoration: underline;
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
`;
|
|
1215
|
-
DocTitleAnchorPane = ({
|
|
1216
|
-
id,
|
|
1217
|
-
type,
|
|
1218
|
-
children
|
|
1219
|
-
}) => {
|
|
1220
|
-
const { ChildLink } = (0, import_structure.usePaneRouter)();
|
|
1221
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PaneLinkWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ChildLink, { childId: id, childParameters: { type }, children }) });
|
|
1222
|
-
};
|
|
1223
|
-
DocBadgeRenderer = ({ doc, docBadge }) => {
|
|
1224
|
-
const badge = docBadge(doc);
|
|
1225
|
-
if (!badge) return null;
|
|
1226
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CustomBadge, { $bgColor: badge.bgColor, $textColor: badge.textColor, $fontSize: badge.fontSize, children: badge.label });
|
|
1227
|
-
};
|
|
1228
|
-
Spinner = import_styled_components2.default.div`
|
|
1229
|
-
width: 28px;
|
|
1230
|
-
height: 28px;
|
|
1231
|
-
border: 3px solid #e5e7eb;
|
|
1232
|
-
border-top-color: #6366f1;
|
|
1233
|
-
border-radius: 50%;
|
|
1234
|
-
animation: ${spin} 0.7s linear infinite;
|
|
1235
|
-
margin: 0 auto 12px;
|
|
1236
|
-
`;
|
|
1237
|
-
LoadingState = import_styled_components2.default.div`
|
|
1238
|
-
padding: 48px 24px;
|
|
1239
|
-
text-align: center;
|
|
1240
|
-
color: #6b7280;
|
|
1241
|
-
font-size: 13px;
|
|
1242
|
-
`;
|
|
1243
|
-
EmptyState = import_styled_components2.default.div`
|
|
1244
|
-
padding: 48px 24px;
|
|
1245
|
-
text-align: center;
|
|
1246
|
-
color: #9ca3af;
|
|
1247
|
-
font-size: 13px;
|
|
1248
|
-
`;
|
|
1249
|
-
DeprecationBanner = import_styled_components2.default.div`
|
|
1250
|
-
background: #fffbeb;
|
|
1251
|
-
border: 1px solid #fcd34d;
|
|
1252
|
-
border-radius: 8px;
|
|
1253
|
-
padding: 10px 14px;
|
|
1254
|
-
font-size: 12px;
|
|
1255
|
-
color: #78350f;
|
|
1256
|
-
margin-bottom: 16px;
|
|
1257
|
-
line-height: 1.6;
|
|
1258
|
-
`;
|
|
1259
|
-
DeprecationBannerLink = import_styled_components2.default.a`
|
|
1260
|
-
color: #92400e;
|
|
1261
|
-
font-weight: 600;
|
|
1262
|
-
text-decoration: underline;
|
|
1263
|
-
&:hover {
|
|
1264
|
-
color: #78350f;
|
|
1265
|
-
}
|
|
1266
|
-
`;
|
|
1267
|
-
TYPE_COLOR_PALETTE = [
|
|
1268
|
-
{ bg: "#dbeafe", text: "#0c4a6e" },
|
|
1269
|
-
// Blue
|
|
1270
|
-
{ bg: "#dcfce7", text: "#14532d" },
|
|
1271
|
-
// Green
|
|
1272
|
-
{ bg: "#fce7f3", text: "#500724" },
|
|
1273
|
-
// Pink
|
|
1274
|
-
{ bg: "#fed7aa", text: "#7c2d12" },
|
|
1275
|
-
// Orange
|
|
1276
|
-
{ bg: "#e9d5ff", text: "#581c87" },
|
|
1277
|
-
// Purple
|
|
1278
|
-
{ bg: "#f3e8ff", text: "#3f0f5c" },
|
|
1279
|
-
// Deep Purple
|
|
1280
|
-
{ bg: "#ccfbf1", text: "#134e4a" },
|
|
1281
|
-
// Teal
|
|
1282
|
-
{ bg: "#ddd6fe", text: "#3730a3" },
|
|
1283
|
-
// Indigo
|
|
1284
|
-
{ bg: "#fca5a5", text: "#7f1d1d" },
|
|
1285
|
-
// Red
|
|
1286
|
-
{ bg: "#a7f3d0", text: "#065f46" },
|
|
1287
|
-
// Emerald
|
|
1288
|
-
{ bg: "#fbbf24", text: "#78350f" },
|
|
1289
|
-
// Amber
|
|
1290
|
-
{ bg: "#c4b5fd", text: "#3b0764" },
|
|
1291
|
-
// Violet
|
|
1292
|
-
{ bg: "#f0fdf4", text: "#15803d" },
|
|
1293
|
-
// Light Green
|
|
1294
|
-
{ bg: "#fef2f2", text: "#991b1b" },
|
|
1295
|
-
// Light Red
|
|
1296
|
-
{ bg: "#f5f3ff", text: "#5b21b6" },
|
|
1297
|
-
// Light Purple
|
|
1298
|
-
{ bg: "#fffbeb", text: "#92400e" }
|
|
1299
|
-
// Light Amber
|
|
1300
|
-
];
|
|
1301
|
-
getTypeColor = (type) => {
|
|
1302
|
-
let hash = 0;
|
|
1303
|
-
for (let i = 0; i < type.length; i += 1) {
|
|
1304
|
-
const char = type.charCodeAt(i);
|
|
1305
|
-
hash = Math.abs(hash * 31 + char);
|
|
1306
|
-
}
|
|
1307
|
-
const colorIndex = hash % TYPE_COLOR_PALETTE.length;
|
|
1308
|
-
return TYPE_COLOR_PALETTE[colorIndex];
|
|
1309
|
-
};
|
|
1310
|
-
getStatusCategory = (score) => {
|
|
1311
|
-
if (score >= 80) return "excellent";
|
|
1312
|
-
if (score >= 60) return "good";
|
|
1313
|
-
if (score >= 40) return "fair";
|
|
1314
|
-
if (score > 0) return "poor";
|
|
1315
|
-
return "missing";
|
|
1316
|
-
};
|
|
1317
|
-
scoreMetaTitle = (title) => {
|
|
1318
|
-
const issues = [];
|
|
1319
|
-
let score = 0;
|
|
1320
|
-
if (title && title.length >= 50 && title.length <= 60) {
|
|
1321
|
-
score = 15;
|
|
1322
|
-
} else if (title && title.length > 0) {
|
|
1323
|
-
score = 10;
|
|
1324
|
-
if (title.length < 50) issues.push("Meta title too short (< 50 chars)");
|
|
1325
|
-
if (title.length > 60) issues.push("Meta title too long (> 60 chars)");
|
|
1326
|
-
} else {
|
|
1327
|
-
issues.push("Missing meta title");
|
|
1328
|
-
}
|
|
1329
|
-
return { score, issues };
|
|
1330
|
-
};
|
|
1331
|
-
scoreMetaDescription = (description) => {
|
|
1332
|
-
const issues = [];
|
|
1333
|
-
let score = 0;
|
|
1334
|
-
if (description && description.length >= 120 && description.length <= 160) {
|
|
1335
|
-
score = 15;
|
|
1336
|
-
} else if (description && description.length > 0) {
|
|
1337
|
-
score = 10;
|
|
1338
|
-
if (description.length < 120) issues.push("Meta description too short (< 120 chars)");
|
|
1339
|
-
if (description.length > 160) issues.push("Meta description too long (> 160 chars)");
|
|
1340
|
-
} else {
|
|
1341
|
-
issues.push("Missing meta description");
|
|
1342
|
-
}
|
|
1343
|
-
return { score, issues };
|
|
1344
|
-
};
|
|
1345
|
-
scoreOpenGraph = (openGraph2) => {
|
|
1346
|
-
const issues = [];
|
|
1347
|
-
let score = 0;
|
|
1348
|
-
if (openGraph2) {
|
|
1349
|
-
if (openGraph2.title) score += 6;
|
|
1350
|
-
else issues.push("Missing OG title");
|
|
1351
|
-
if (openGraph2.description) score += 6;
|
|
1352
|
-
else issues.push("Missing OG description");
|
|
1353
|
-
if (openGraph2.image) score += 6;
|
|
1354
|
-
else issues.push("Missing OG image");
|
|
1355
|
-
if (openGraph2.type) score += 7;
|
|
1356
|
-
else issues.push("Missing OG type");
|
|
1357
|
-
} else {
|
|
1358
|
-
issues.push("Open Graph not configured");
|
|
1359
|
-
}
|
|
1360
|
-
return { score, issues };
|
|
1361
|
-
};
|
|
1362
|
-
scoreTwitterCard = (twitter2) => {
|
|
1363
|
-
const issues = [];
|
|
1364
|
-
let score = 0;
|
|
1365
|
-
if (twitter2) {
|
|
1366
|
-
if (twitter2.title) score += 5;
|
|
1367
|
-
else issues.push("Missing Twitter title");
|
|
1368
|
-
if (twitter2.description) score += 5;
|
|
1369
|
-
else issues.push("Missing Twitter description");
|
|
1370
|
-
if (twitter2.image) score += 5;
|
|
1371
|
-
else issues.push("Missing Twitter image");
|
|
1372
|
-
} else {
|
|
1373
|
-
issues.push("Twitter Card not configured");
|
|
1374
|
-
}
|
|
1375
|
-
return { score, issues };
|
|
1376
|
-
};
|
|
1377
|
-
calculateHealthScore = (doc) => {
|
|
1378
|
-
if (!doc.seo) {
|
|
1379
|
-
return { score: 0, status: "missing", issues: ["SEO fields not configured"] };
|
|
1380
|
-
}
|
|
1381
|
-
const { title, description, keywords, robots, canonicalUrl, openGraph: openGraph2, twitter: twitter2 } = doc.seo;
|
|
1382
|
-
let score = 0;
|
|
1383
|
-
const issues = [];
|
|
1384
|
-
const titleResult = scoreMetaTitle(title);
|
|
1385
|
-
score += titleResult.score;
|
|
1386
|
-
issues.push(...titleResult.issues);
|
|
1387
|
-
const descResult = scoreMetaDescription(description);
|
|
1388
|
-
score += descResult.score;
|
|
1389
|
-
issues.push(...descResult.issues);
|
|
1390
|
-
if (doc.seo.metaImage) score += 10;
|
|
1391
|
-
else issues.push("Missing meta image");
|
|
1392
|
-
if (keywords && keywords.length > 0) score += 10;
|
|
1393
|
-
else issues.push("No keywords defined");
|
|
1394
|
-
if (robots && !robots.noIndex) score += 5;
|
|
1395
|
-
else if (!robots) score += 5;
|
|
1396
|
-
if (canonicalUrl) score += 0;
|
|
1397
|
-
const ogResult = scoreOpenGraph(openGraph2);
|
|
1398
|
-
score += ogResult.score;
|
|
1399
|
-
issues.push(...ogResult.issues);
|
|
1400
|
-
const twResult = scoreTwitterCard(twitter2);
|
|
1401
|
-
score += twResult.score;
|
|
1402
|
-
issues.push(...twResult.issues);
|
|
1403
|
-
const hasMetaImage = !!doc.seo.metaImage;
|
|
1404
|
-
const hasOgImage = !!(openGraph2 && openGraph2.image);
|
|
1405
|
-
const hasTwitterImage = !!(twitter2 && twitter2.image);
|
|
1406
|
-
if (hasMetaImage && hasOgImage && hasTwitterImage) {
|
|
1407
|
-
score += 5;
|
|
1408
|
-
} else {
|
|
1409
|
-
const missingImages = [];
|
|
1410
|
-
if (!hasMetaImage) missingImages.push("meta image");
|
|
1411
|
-
if (!hasOgImage) missingImages.push("OG image");
|
|
1412
|
-
if (!hasTwitterImage) missingImages.push("Twitter image");
|
|
1413
|
-
issues.push(`Missing images for full score: ${missingImages.join(", ")}`);
|
|
1414
|
-
}
|
|
1415
|
-
const status = getStatusCategory(score);
|
|
1416
|
-
return { score, status, issues };
|
|
1417
|
-
};
|
|
1418
|
-
resolveTypeLabel = (type, typeLabels) => {
|
|
1419
|
-
var _a;
|
|
1420
|
-
return (_a = typeLabels == null ? void 0 : typeLabels[type]) != null ? _a : type;
|
|
1421
|
-
};
|
|
1422
|
-
buildTitleProjection = (titleField) => {
|
|
1423
|
-
if (!titleField || titleField === "title") return "title";
|
|
1424
|
-
if (typeof titleField === "string") return `"title": ${titleField}`;
|
|
1425
|
-
const cases = Object.entries(titleField).map(([type, field]) => `_type == "${type}" => ${field}`).join(", ");
|
|
1426
|
-
return `"title": select(${cases}, title)`;
|
|
1427
|
-
};
|
|
1428
|
-
generateDummyData = () => {
|
|
1429
|
-
const dummyDocs = [
|
|
1430
|
-
{
|
|
1431
|
-
_id: "preview-post-1",
|
|
1432
|
-
_type: "post",
|
|
1433
|
-
title: "Getting Started with SEO Best Practices",
|
|
1434
|
-
slug: { current: "getting-started-seo" },
|
|
1435
|
-
_updatedAt: new Date(Date.now() - 2 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
1436
|
-
seo: {
|
|
1437
|
-
title: "Getting Started with SEO Best Practices | My Blog",
|
|
1438
|
-
description: "Learn the fundamentals of SEO optimization to improve your website visibility and search rankings.",
|
|
1439
|
-
keywords: ["seo", "best practices", "optimization"],
|
|
1440
|
-
metaImage: { _type: "image", asset: { _ref: "image-123", _type: "reference" } },
|
|
1441
|
-
openGraph: {
|
|
1442
|
-
title: "SEO Best Practices Guide",
|
|
1443
|
-
description: "Master SEO optimization",
|
|
1444
|
-
image: { _type: "image", asset: { _ref: "image-123", _type: "reference" }, alt: "SEO Guide" },
|
|
1445
|
-
type: "article"
|
|
1446
|
-
},
|
|
1447
|
-
twitter: {
|
|
1448
|
-
title: "SEO Best Practices",
|
|
1449
|
-
description: "Learn SEO optimization",
|
|
1450
|
-
image: { _type: "image", asset: { _ref: "image-123", _type: "reference" }, alt: "Guide" },
|
|
1451
|
-
card: "summary_large_image"
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
},
|
|
1455
|
-
{
|
|
1456
|
-
_id: "preview-post-2",
|
|
1457
|
-
_type: "post",
|
|
1458
|
-
title: "Advanced Analytics Strategy",
|
|
1459
|
-
slug: { current: "advanced-analytics" },
|
|
1460
|
-
_updatedAt: new Date(Date.now() - 5 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
1461
|
-
seo: {
|
|
1462
|
-
title: "Advanced Analytics",
|
|
1463
|
-
description: "Strategy tips",
|
|
1464
|
-
keywords: ["analytics", "data"],
|
|
1465
|
-
openGraph: {
|
|
1466
|
-
title: "Analytics Guide"
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
},
|
|
1470
|
-
{
|
|
1471
|
-
_id: "preview-page-1",
|
|
1472
|
-
_type: "page",
|
|
1473
|
-
title: "About Us",
|
|
1474
|
-
slug: { current: "about" },
|
|
1475
|
-
_updatedAt: new Date(Date.now() - 10 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
1476
|
-
seo: {
|
|
1477
|
-
title: "About",
|
|
1478
|
-
keywords: ["company", "team"],
|
|
1479
|
-
metaImage: { _type: "image", asset: { _ref: "image-456", _type: "reference" } }
|
|
1480
|
-
}
|
|
1481
|
-
},
|
|
1482
|
-
{
|
|
1483
|
-
_id: "preview-post-3",
|
|
1484
|
-
_type: "post",
|
|
1485
|
-
title: "Content Marketing Trends for 2024",
|
|
1486
|
-
slug: { current: "content-marketing-trends" },
|
|
1487
|
-
_updatedAt: new Date(Date.now() - 1 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
1488
|
-
seo: {
|
|
1489
|
-
title: "Content Marketing Trends 2024",
|
|
1490
|
-
description: "Discover the latest content marketing trends and strategies to engage your audience effectively.",
|
|
1491
|
-
keywords: ["content marketing", "trends", "strategy", "engagement"],
|
|
1492
|
-
metaImage: { _type: "image", asset: { _ref: "image-789", _type: "reference" } },
|
|
1493
|
-
openGraph: {
|
|
1494
|
-
title: "Content Marketing Trends 2024",
|
|
1495
|
-
description: "Latest trends in content marketing",
|
|
1496
|
-
image: { _type: "image", asset: { _ref: "image-789", _type: "reference" }, alt: "Trends" },
|
|
1497
|
-
type: "article"
|
|
1498
|
-
},
|
|
1499
|
-
twitter: {
|
|
1500
|
-
title: "Content Marketing Trends",
|
|
1501
|
-
description: "Discover the latest trends",
|
|
1502
|
-
card: "summary"
|
|
1503
|
-
}
|
|
1504
|
-
}
|
|
1505
|
-
},
|
|
1506
|
-
{
|
|
1507
|
-
_id: "preview-post-4",
|
|
1508
|
-
_type: "product",
|
|
1509
|
-
title: "Pro Plan",
|
|
1510
|
-
slug: { current: "pro-plan" },
|
|
1511
|
-
_updatedAt: new Date(Date.now() - 15 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
1512
|
-
seo: {
|
|
1513
|
-
title: "Pro",
|
|
1514
|
-
keywords: ["pricing"]
|
|
1515
|
-
}
|
|
1516
|
-
},
|
|
1517
|
-
{
|
|
1518
|
-
_id: "preview-page-2",
|
|
1519
|
-
_type: "page",
|
|
1520
|
-
title: "Contact",
|
|
1521
|
-
slug: { current: "contact" },
|
|
1522
|
-
_updatedAt: new Date(Date.now() - 8 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
1523
|
-
seo: {
|
|
1524
|
-
openGraph: {
|
|
1525
|
-
title: "Get in Touch"
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
},
|
|
1529
|
-
{
|
|
1530
|
-
_id: "preview-post-5",
|
|
1531
|
-
_type: "post",
|
|
1532
|
-
title: "Mobile Optimization Guide",
|
|
1533
|
-
slug: { current: "mobile-optimization" },
|
|
1534
|
-
_updatedAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
1535
|
-
seo: {
|
|
1536
|
-
title: "Mobile Optimization Guide: Best Practices for Responsive Design",
|
|
1537
|
-
description: "Complete guide to mobile optimization including responsive design, performance tips, and user experience best practices for modern web development.",
|
|
1538
|
-
keywords: ["mobile", "optimization", "responsive", "performance"],
|
|
1539
|
-
metaImage: { _type: "image", asset: { _ref: "image-mobile", _type: "reference" } },
|
|
1540
|
-
openGraph: {
|
|
1541
|
-
title: "Mobile Optimization Best Practices",
|
|
1542
|
-
description: "Master mobile web optimization",
|
|
1543
|
-
image: { _type: "image", asset: { _ref: "image-mobile", _type: "reference" }, alt: "Mobile" },
|
|
1544
|
-
type: "article"
|
|
1545
|
-
},
|
|
1546
|
-
twitter: {
|
|
1547
|
-
title: "Mobile Optimization Tips",
|
|
1548
|
-
description: "Responsive design best practices",
|
|
1549
|
-
image: { _type: "image", asset: { _ref: "image-mobile", _type: "reference" }, alt: "Mobile" },
|
|
1550
|
-
card: "summary_large_image"
|
|
1551
|
-
}
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
];
|
|
1555
|
-
return dummyDocs.map((doc) => __spreadProps(__spreadValues({}, doc), {
|
|
1556
|
-
health: calculateHealthScore(doc)
|
|
1557
|
-
}));
|
|
1558
|
-
};
|
|
1559
|
-
SeoHealthDashboard = ({
|
|
1560
|
-
icon = "\u{1F4CA}",
|
|
1561
|
-
title = "SEO Health Dashboard",
|
|
1562
|
-
description = "Monitor and optimize SEO fields across all your documents",
|
|
1563
|
-
showTypeColumn = true,
|
|
1564
|
-
showDocumentId = true,
|
|
1565
|
-
queryTypes,
|
|
1566
|
-
queryRequireSeo = true,
|
|
1567
|
-
customQuery,
|
|
1568
|
-
apiVersion = "2023-01-01",
|
|
1569
|
-
licenseKey,
|
|
1570
|
-
typeDisplayLabels,
|
|
1571
|
-
typeColumnMode = "badge",
|
|
1572
|
-
titleField,
|
|
1573
|
-
getDocumentBadge,
|
|
1574
|
-
loadingLicense,
|
|
1575
|
-
loadingDocuments,
|
|
1576
|
-
noDocuments,
|
|
1577
|
-
previewMode = false,
|
|
1578
|
-
openInPane = false,
|
|
1579
|
-
structureTool,
|
|
1580
|
-
_deprecationWarnings
|
|
1581
|
-
}) => {
|
|
1582
|
-
const resolvedTypeLabels = typeDisplayLabels;
|
|
1583
|
-
const resolvedDocBadge = getDocumentBadge;
|
|
1584
|
-
const allDeprecationWarnings = (0, import_react13.useMemo)(() => _deprecationWarnings != null ? _deprecationWarnings : [], [_deprecationWarnings]);
|
|
1585
|
-
const deprecationGroups = (0, import_react13.useMemo)(() => {
|
|
1586
|
-
const groups = /* @__PURE__ */ new Map();
|
|
1587
|
-
for (const w of allDeprecationWarnings) {
|
|
1588
|
-
if (!groups.has(w.version)) {
|
|
1589
|
-
groups.set(w.version, { version: w.version, changelogUrl: w.changelogUrl, keys: [] });
|
|
1590
|
-
}
|
|
1591
|
-
groups.get(w.version).keys.push(w.key);
|
|
1592
|
-
}
|
|
1593
|
-
return Array.from(groups.values());
|
|
1594
|
-
}, [allDeprecationWarnings]);
|
|
1595
|
-
const client = (0, import_sanity19.useClient)({ apiVersion });
|
|
1596
|
-
const [licenseStatus, setLicenseStatus] = (0, import_react13.useState)("loading");
|
|
1597
|
-
const [documents, setDocuments] = (0, import_react13.useState)([]);
|
|
1598
|
-
const [loading, setLoading] = (0, import_react13.useState)(true);
|
|
1599
|
-
const [isRefreshing, setIsRefreshing] = (0, import_react13.useState)(false);
|
|
1600
|
-
const [searchQuery, setSearchQuery] = (0, import_react13.useState)("");
|
|
1601
|
-
const [filterStatus, setFilterStatus] = (0, import_react13.useState)("all");
|
|
1602
|
-
const [filterType, setFilterType] = (0, import_react13.useState)("all");
|
|
1603
|
-
const [sortBy, setSortBy] = (0, import_react13.useState)("score");
|
|
1604
|
-
const [activePopover, setActivePopover] = (0, import_react13.useState)(null);
|
|
1605
|
-
const VALIDATION_ENDPOINT = "https://sanity-plugin-seofields.thehardik.in/api/validate-license";
|
|
1606
|
-
const CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
1607
|
-
const validateLicense = (0, import_react13.useCallback)(
|
|
1608
|
-
async (forceRefresh = false) => {
|
|
1609
|
-
var _a;
|
|
1610
|
-
if (previewMode) {
|
|
1611
|
-
setLicenseStatus("valid");
|
|
1612
|
-
return;
|
|
1613
|
-
}
|
|
1614
|
-
if (!licenseKey) {
|
|
1615
|
-
setLicenseStatus("invalid");
|
|
1616
|
-
return;
|
|
1617
|
-
}
|
|
1618
|
-
const projectId = (_a = client.config().projectId) != null ? _a : "";
|
|
1619
|
-
const cacheKey = `seofields_license_${projectId}`;
|
|
1620
|
-
if (forceRefresh) {
|
|
1621
|
-
try {
|
|
1622
|
-
sessionStorage.removeItem(cacheKey);
|
|
1623
|
-
} catch (e) {
|
|
1624
|
-
}
|
|
1625
|
-
}
|
|
1626
|
-
if (!forceRefresh) {
|
|
1627
|
-
try {
|
|
1628
|
-
const cached = sessionStorage.getItem(cacheKey);
|
|
1629
|
-
if (cached) {
|
|
1630
|
-
const { valid, ts } = JSON.parse(cached);
|
|
1631
|
-
if (Date.now() - ts < CACHE_TTL_MS) {
|
|
1632
|
-
setLicenseStatus(valid ? "valid" : "invalid");
|
|
1633
|
-
return;
|
|
1634
|
-
}
|
|
1635
|
-
}
|
|
1636
|
-
} catch (e) {
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
setLicenseStatus("loading");
|
|
1640
|
-
try {
|
|
1641
|
-
const res = await fetch(VALIDATION_ENDPOINT, {
|
|
1642
|
-
method: "POST",
|
|
1643
|
-
headers: { "Content-Type": "application/json" },
|
|
1644
|
-
body: JSON.stringify({ licenseKey, projectId })
|
|
1645
|
-
});
|
|
1646
|
-
const valid = res.ok;
|
|
1647
|
-
setLicenseStatus(valid ? "valid" : "invalid");
|
|
1648
|
-
try {
|
|
1649
|
-
sessionStorage.setItem(cacheKey, JSON.stringify({ valid, ts: Date.now() }));
|
|
1650
|
-
} catch (e) {
|
|
1651
|
-
}
|
|
1652
|
-
} catch (e) {
|
|
1653
|
-
setLicenseStatus("valid");
|
|
1654
|
-
}
|
|
1655
|
-
},
|
|
1656
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1657
|
-
[licenseKey, previewMode]
|
|
1658
|
-
);
|
|
1659
|
-
(0, import_react13.useEffect)(() => {
|
|
1660
|
-
validateLicense();
|
|
1661
|
-
}, [licenseKey, previewMode]);
|
|
1662
|
-
const handleMouseEnterIssues = (el, issues) => {
|
|
1663
|
-
if (!el) return;
|
|
1664
|
-
const rect = el.getBoundingClientRect();
|
|
1665
|
-
const popoverWidth = 280;
|
|
1666
|
-
const viewportWidth = window.innerWidth;
|
|
1667
|
-
let left = rect.left;
|
|
1668
|
-
if (left + popoverWidth > viewportWidth - 10) left = viewportWidth - popoverWidth - 10;
|
|
1669
|
-
if (left < 10) left = 10;
|
|
1670
|
-
setActivePopover({ top: rect.top, left, issues });
|
|
1671
|
-
};
|
|
1672
|
-
const JSONStringifiedQueryTypes = JSON.stringify(queryTypes);
|
|
1673
|
-
const JSONStringifiedTitleField = JSON.stringify(titleField);
|
|
1674
|
-
const fetchDocuments = (0, import_react13.useCallback)(
|
|
1675
|
-
async (isManualRefresh = false) => {
|
|
1676
|
-
try {
|
|
1677
|
-
if (isManualRefresh) {
|
|
1678
|
-
setIsRefreshing(true);
|
|
1679
|
-
} else {
|
|
1680
|
-
setLoading(true);
|
|
1681
|
-
}
|
|
1682
|
-
if (previewMode) {
|
|
1683
|
-
setDocuments(generateDummyData());
|
|
1684
|
-
return;
|
|
1685
|
-
}
|
|
1686
|
-
let groqQuery;
|
|
1687
|
-
let params = {};
|
|
1688
|
-
if (customQuery) {
|
|
1689
|
-
groqQuery = customQuery;
|
|
1690
|
-
} else if (queryTypes && queryTypes.length > 0) {
|
|
1691
|
-
const seoFilter = queryRequireSeo ? " && seo != null" : "";
|
|
1692
|
-
const titleProj = buildTitleProjection(titleField);
|
|
1693
|
-
groqQuery = `*[_type in $types${seoFilter} && !(_id in path("drafts.**"))]{
|
|
1694
|
-
_id,
|
|
1695
|
-
_type,
|
|
1696
|
-
${titleProj},
|
|
1697
|
-
slug,
|
|
1698
|
-
seo,
|
|
1699
|
-
_updatedAt
|
|
1700
|
-
}`;
|
|
1701
|
-
params = { types: queryTypes };
|
|
1702
|
-
} else {
|
|
1703
|
-
const titleProj = buildTitleProjection(titleField);
|
|
1704
|
-
groqQuery = `*[seo != null && !(_id in path("drafts.**"))]{
|
|
1705
|
-
_id,
|
|
1706
|
-
_type,
|
|
1707
|
-
${titleProj},
|
|
1708
|
-
slug,
|
|
1709
|
-
seo,
|
|
1710
|
-
_updatedAt
|
|
1711
|
-
}`;
|
|
1712
|
-
}
|
|
1713
|
-
const result = await client.fetch(groqQuery, params, { perspective: "published" });
|
|
1714
|
-
const docsWithHealth = result.map((doc) => __spreadProps(__spreadValues({}, doc), {
|
|
1715
|
-
health: calculateHealthScore(doc)
|
|
1716
|
-
}));
|
|
1717
|
-
setDocuments(docsWithHealth);
|
|
1718
|
-
} catch (error) {
|
|
1719
|
-
console.error("Error fetching documents:", error);
|
|
1720
|
-
} finally {
|
|
1721
|
-
setLoading(false);
|
|
1722
|
-
setIsRefreshing(false);
|
|
1723
|
-
}
|
|
1724
|
-
},
|
|
1725
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1726
|
-
[
|
|
1727
|
-
client,
|
|
1728
|
-
customQuery,
|
|
1729
|
-
queryRequireSeo,
|
|
1730
|
-
JSONStringifiedQueryTypes,
|
|
1731
|
-
JSONStringifiedTitleField,
|
|
1732
|
-
previewMode
|
|
1733
|
-
]
|
|
1734
|
-
);
|
|
1735
|
-
(0, import_react13.useEffect)(() => {
|
|
1736
|
-
fetchDocuments();
|
|
1737
|
-
}, [
|
|
1738
|
-
client,
|
|
1739
|
-
customQuery,
|
|
1740
|
-
queryRequireSeo,
|
|
1741
|
-
JSONStringifiedQueryTypes,
|
|
1742
|
-
JSONStringifiedTitleField,
|
|
1743
|
-
previewMode
|
|
1744
|
-
]);
|
|
1745
|
-
const handleRefresh = (0, import_react13.useCallback)(() => {
|
|
1746
|
-
fetchDocuments(true);
|
|
1747
|
-
}, [fetchDocuments]);
|
|
1748
|
-
const uniqueDocumentTypes = (0, import_react13.useMemo)(() => {
|
|
1749
|
-
const types2 = new Set(documents.map((doc) => doc._type));
|
|
1750
|
-
return Array.from(types2).sort();
|
|
1751
|
-
}, [documents]);
|
|
1752
|
-
const filteredAndSortedDocs = (0, import_react13.useMemo)(() => {
|
|
1753
|
-
let filtered = documents;
|
|
1754
|
-
if (searchQuery) {
|
|
1755
|
-
filtered = filtered.filter(
|
|
1756
|
-
(doc) => {
|
|
1757
|
-
var _a, _b;
|
|
1758
|
-
return ((_a = doc.title) == null ? void 0 : _a.toLowerCase().includes(searchQuery.toLowerCase())) || ((_b = doc._id) == null ? void 0 : _b.toLowerCase().includes(searchQuery.toLowerCase()));
|
|
1759
|
-
}
|
|
1760
|
-
);
|
|
1761
|
-
}
|
|
1762
|
-
if (filterStatus !== "all") {
|
|
1763
|
-
filtered = filtered.filter((doc) => doc.health.status === filterStatus);
|
|
1764
|
-
}
|
|
1765
|
-
if (filterType !== "all") {
|
|
1766
|
-
filtered = filtered.filter((doc) => doc._type === filterType);
|
|
1767
|
-
}
|
|
1768
|
-
const sorted = [...filtered].sort((a, b) => {
|
|
1769
|
-
if (sortBy === "score") {
|
|
1770
|
-
return b.health.score - a.health.score;
|
|
1771
|
-
}
|
|
1772
|
-
return (a.title || "").localeCompare(b.title || "");
|
|
1773
|
-
});
|
|
1774
|
-
return sorted;
|
|
1775
|
-
}, [documents, searchQuery, filterStatus, filterType, sortBy]);
|
|
1776
|
-
const stats = (0, import_react13.useMemo)(() => {
|
|
1777
|
-
const total = documents.length;
|
|
1778
|
-
const excellent = documents.filter((d) => d.health.score >= 80).length;
|
|
1779
|
-
const good = documents.filter((d) => d.health.score >= 60 && d.health.score < 80).length;
|
|
1780
|
-
const fair = documents.filter((d) => d.health.score >= 40 && d.health.score < 60).length;
|
|
1781
|
-
const poor = documents.filter((d) => d.health.score > 0 && d.health.score < 40).length;
|
|
1782
|
-
const missing = documents.filter((d) => d.health.score === 0).length;
|
|
1783
|
-
const avgScore = total > 0 ? Math.round(documents.reduce((sum, d) => sum + d.health.score, 0) / total) : 0;
|
|
1784
|
-
return { total, excellent, good, fair, poor, missing, avgScore };
|
|
1785
|
-
}, [documents]);
|
|
1786
|
-
const handleMouseLeave = (0, import_react13.useCallback)(() => {
|
|
1787
|
-
setActivePopover(null);
|
|
1788
|
-
}, []);
|
|
1789
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DashboardContainer, { children: [
|
|
1790
|
-
licenseStatus === "loading" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(LoadingState, { style: { padding: "80px 24px" }, children: [
|
|
1791
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Spinner, {}),
|
|
1792
|
-
loadingLicense != null ? loadingLicense : "Verifying license\u2026"
|
|
1793
|
-
] }),
|
|
1794
|
-
licenseStatus === "invalid" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UpgradeContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UpgradeBox, { children: licenseKey ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1795
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UpgradeLock, { children: "\u274C" }),
|
|
1796
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UpgradeTitle, { children: "Invalid License Key" }),
|
|
1797
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UpgradeText, { children: "The license key you provided is invalid or has been revoked. Please check your key and update it in the plugin config." }),
|
|
1798
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UpgradeCode, { children: `seofields({
|
|
1799
|
-
healthDashboard: {
|
|
1800
|
-
licenseKey: 'YOUR_LICENSE_KEY', // \u2190 replace with a valid key
|
|
1801
|
-
},
|
|
1802
|
-
})` }),
|
|
1803
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1804
|
-
UpgradeButton,
|
|
1805
|
-
{
|
|
1806
|
-
href: "https://sanity-plugin-seofields.thehardik.in",
|
|
1807
|
-
target: "_blank",
|
|
1808
|
-
rel: "noopener noreferrer",
|
|
1809
|
-
children: "Get a New License Key \u2192"
|
|
1810
|
-
}
|
|
1811
|
-
),
|
|
1812
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("br", {}),
|
|
1813
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ReloadButton, { onClick: () => validateLicense(true), children: "Click here If You Just Updated Your Key" })
|
|
1814
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1815
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UpgradeLock, { children: "\u{1F512}" }),
|
|
1816
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UpgradeTitle, { children: "SEO Health Dashboard" }),
|
|
1817
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UpgradeText, { children: "This feature requires a license key. Add your key to the plugin config to unlock the full dashboard." }),
|
|
1818
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UpgradeCode, { children: `// sanity.config.ts
|
|
1819
|
-
import { seofields } from 'sanity-plugin-seofields'
|
|
1820
|
-
|
|
1821
|
-
export default defineConfig({
|
|
1822
|
-
plugins: [
|
|
1823
|
-
seofields({
|
|
1824
|
-
healthDashboard: {
|
|
1825
|
-
licenseKey: 'SEOF-XXXX-XXXX-XXXX',
|
|
1826
|
-
},
|
|
1827
|
-
}),
|
|
1828
|
-
],
|
|
1829
|
-
})` }),
|
|
1830
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1831
|
-
UpgradeButton,
|
|
1832
|
-
{
|
|
1833
|
-
href: "https://sanity-plugin-seofields.thehardik.in",
|
|
1834
|
-
target: "_blank",
|
|
1835
|
-
rel: "noopener noreferrer",
|
|
1836
|
-
children: "Get a License Key \u2192"
|
|
1837
|
-
}
|
|
1838
|
-
)
|
|
1839
|
-
] }) }) }),
|
|
1840
|
-
licenseStatus === "valid" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1841
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(PageHeader, { children: [
|
|
1842
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
|
|
1843
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(PageTitle, { children: [
|
|
1844
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
|
|
1845
|
-
icon,
|
|
1846
|
-
" ",
|
|
1847
|
-
title
|
|
1848
|
-
] }),
|
|
1849
|
-
previewMode && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PreviewBadge, { children: "Preview Mode" })
|
|
1850
|
-
] }),
|
|
1851
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PageSubtitle, { children: description })
|
|
1852
|
-
] }),
|
|
1853
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1854
|
-
DashboardRefreshButton,
|
|
1855
|
-
{
|
|
1856
|
-
onClick: handleRefresh,
|
|
1857
|
-
disabled: loading || isRefreshing,
|
|
1858
|
-
$spinning: isRefreshing,
|
|
1859
|
-
title: "Refresh documents",
|
|
1860
|
-
children: [
|
|
1861
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1862
|
-
"svg",
|
|
1863
|
-
{
|
|
1864
|
-
width: "14",
|
|
1865
|
-
height: "14",
|
|
1866
|
-
viewBox: "0 0 24 24",
|
|
1867
|
-
fill: "none",
|
|
1868
|
-
stroke: "currentColor",
|
|
1869
|
-
strokeWidth: "2.2",
|
|
1870
|
-
strokeLinecap: "round",
|
|
1871
|
-
strokeLinejoin: "round",
|
|
1872
|
-
children: [
|
|
1873
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("polyline", { points: "23 4 23 10 17 10" }),
|
|
1874
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("polyline", { points: "1 20 1 14 7 14" }),
|
|
1875
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" })
|
|
1876
|
-
]
|
|
1877
|
-
}
|
|
1878
|
-
),
|
|
1879
|
-
"Refresh"
|
|
1880
|
-
]
|
|
1881
|
-
}
|
|
1882
|
-
)
|
|
1883
|
-
] }),
|
|
1884
|
-
deprecationGroups.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DeprecationBanner, { children: [
|
|
1885
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { children: "\u26A0\uFE0F Deprecated config keys detected:" }),
|
|
1886
|
-
" ",
|
|
1887
|
-
deprecationGroups.map((group, gi) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
|
|
1888
|
-
group.keys.map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
|
|
1889
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("code", { style: { background: "#fef9c3", padding: "1px 4px", borderRadius: 3 }, children: w.split("\u2192")[0].trim() }),
|
|
1890
|
-
" \u2192 ",
|
|
1891
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("code", { style: { background: "#dcfce7", padding: "1px 4px", borderRadius: 3 }, children: w.split("\u2192")[1].trim() }),
|
|
1892
|
-
i < group.keys.length - 1 ? " \xB7 " : ""
|
|
1893
|
-
] }, w)),
|
|
1894
|
-
" ",
|
|
1895
|
-
"(",
|
|
1896
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1897
|
-
DeprecationBannerLink,
|
|
1898
|
-
{
|
|
1899
|
-
href: group.changelogUrl,
|
|
1900
|
-
target: "_blank",
|
|
1901
|
-
rel: "noopener noreferrer",
|
|
1902
|
-
children: [
|
|
1903
|
-
group.version,
|
|
1904
|
-
" changelog"
|
|
1905
|
-
]
|
|
1906
|
-
}
|
|
1907
|
-
),
|
|
1908
|
-
")",
|
|
1909
|
-
gi < deprecationGroups.length - 1 ? " \xB7 " : ""
|
|
1910
|
-
] }, group.version)),
|
|
1911
|
-
" ",
|
|
1912
|
-
"\u2014 Please update your config."
|
|
1913
|
-
] }),
|
|
1914
|
-
!loading && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(StatsGrid, { children: [
|
|
1915
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(StatCard, { children: [
|
|
1916
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatLabel, { children: "Total Docs" }),
|
|
1917
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatValue, { children: stats.total })
|
|
1918
|
-
] }),
|
|
1919
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(StatCard, { children: [
|
|
1920
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatLabel, { children: "Avg Score" }),
|
|
1921
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(StatValue, { children: [
|
|
1922
|
-
stats.avgScore,
|
|
1923
|
-
"%"
|
|
1924
|
-
] })
|
|
1925
|
-
] }),
|
|
1926
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(StatCard, { $accent: "#10b981", children: [
|
|
1927
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatLabel, { children: "Excellent (80+)" }),
|
|
1928
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatValue, { children: stats.excellent })
|
|
1929
|
-
] }),
|
|
1930
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(StatCard, { $accent: "#f59e0b", children: [
|
|
1931
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatLabel, { children: "Good (60\u201379)" }),
|
|
1932
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatValue, { children: stats.good })
|
|
1933
|
-
] }),
|
|
1934
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(StatCard, { $accent: "#f97316", children: [
|
|
1935
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatLabel, { children: "Fair (40\u201359)" }),
|
|
1936
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatValue, { children: stats.fair })
|
|
1937
|
-
] }),
|
|
1938
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(StatCard, { $accent: "#ef4444", children: [
|
|
1939
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatLabel, { children: "Poor / Missing" }),
|
|
1940
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatValue, { children: stats.poor + stats.missing })
|
|
1941
|
-
] })
|
|
1942
|
-
] }),
|
|
1943
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(ControlsBar, { children: [
|
|
1944
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(SearchWrapper, { children: [
|
|
1945
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SearchIconSvg, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1946
|
-
"path",
|
|
1947
|
-
{
|
|
1948
|
-
fillRule: "evenodd",
|
|
1949
|
-
d: "M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z",
|
|
1950
|
-
clipRule: "evenodd"
|
|
1951
|
-
}
|
|
1952
|
-
) }) }),
|
|
1953
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1954
|
-
SearchInput,
|
|
1955
|
-
{
|
|
1956
|
-
placeholder: "Search documents...",
|
|
1957
|
-
value: searchQuery,
|
|
1958
|
-
onChange: (e) => setSearchQuery(e.currentTarget.value)
|
|
1959
|
-
}
|
|
1960
|
-
)
|
|
1961
|
-
] }),
|
|
1962
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1963
|
-
StyledSelect,
|
|
1964
|
-
{
|
|
1965
|
-
value: filterStatus,
|
|
1966
|
-
onChange: (e) => setFilterStatus(e.currentTarget.value),
|
|
1967
|
-
children: [
|
|
1968
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "all", children: "All Status" }),
|
|
1969
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "excellent", children: "Excellent" }),
|
|
1970
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "good", children: "Good" }),
|
|
1971
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "fair", children: "Fair" }),
|
|
1972
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "poor", children: "Poor" }),
|
|
1973
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "missing", children: "Missing" })
|
|
1974
|
-
]
|
|
1975
|
-
}
|
|
1976
|
-
),
|
|
1977
|
-
uniqueDocumentTypes.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1978
|
-
StyledSelect,
|
|
1979
|
-
{
|
|
1980
|
-
value: filterType,
|
|
1981
|
-
onChange: (e) => setFilterType(e.currentTarget.value),
|
|
1982
|
-
children: [
|
|
1983
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "all", children: "All Types" }),
|
|
1984
|
-
uniqueDocumentTypes.map((type) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: type, children: resolveTypeLabel(type, resolvedTypeLabels) }, type))
|
|
1985
|
-
]
|
|
1986
|
-
}
|
|
1987
|
-
),
|
|
1988
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1989
|
-
StyledSelect,
|
|
1990
|
-
{
|
|
1991
|
-
value: sortBy,
|
|
1992
|
-
onChange: (e) => setSortBy(e.currentTarget.value),
|
|
1993
|
-
children: [
|
|
1994
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "score", children: "Sort by Score" }),
|
|
1995
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "title", children: "Sort by Title" })
|
|
1996
|
-
]
|
|
1997
|
-
}
|
|
1998
|
-
)
|
|
1999
|
-
] }),
|
|
2000
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(TableCard, { children: [
|
|
2001
|
-
loading && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(LoadingState, { children: [
|
|
2002
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Spinner, {}),
|
|
2003
|
-
loadingDocuments != null ? loadingDocuments : "Loading documents\u2026"
|
|
2004
|
-
] }),
|
|
2005
|
-
!loading && (filteredAndSortedDocs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EmptyState, { children: noDocuments != null ? noDocuments : "No documents found" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
2006
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(TableHeader, { children: [
|
|
2007
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ColTitle, { children: "Title" }),
|
|
2008
|
-
showTypeColumn && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ColType, { children: "Type" }),
|
|
2009
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ColScore, { children: "Score" }),
|
|
2010
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ColIssues, { children: "Top Issues" })
|
|
2011
|
-
] }),
|
|
2012
|
-
filteredAndSortedDocs.map((doc) => {
|
|
2013
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(TableRow, { children: [
|
|
2014
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ColTitle, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TitleWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(TitleCell, { children: [
|
|
2015
|
-
doc.title !== null && typeof doc.title !== "string" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NonStringTitleWarning, { title: "title is not a string \u2014 use pt::text(title) in your query.groq projection to convert Portable Text to a plain string", children: "\u26A0 title is not a string \u2014 use pt::text(title) in query.groq" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children: openInPane ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DocTitleAnchorPane, { id: doc._id, type: doc._type, children: typeof doc.title === "string" ? doc.title || "Untitled" : "Untitled" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2016
|
-
DocTitleAnchor,
|
|
2017
|
-
{
|
|
2018
|
-
id: doc._id,
|
|
2019
|
-
type: doc._type,
|
|
2020
|
-
structureTool,
|
|
2021
|
-
children: typeof doc.title === "string" ? doc.title || "Untitled" : "Untitled"
|
|
2022
|
-
}
|
|
2023
|
-
) }),
|
|
2024
|
-
showDocumentId && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DocId, { children: doc._id }),
|
|
2025
|
-
resolvedDocBadge && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2026
|
-
DocBadgeRenderer,
|
|
2027
|
-
{
|
|
2028
|
-
doc,
|
|
2029
|
-
docBadge: resolvedDocBadge
|
|
2030
|
-
}
|
|
2031
|
-
)
|
|
2032
|
-
] }) }) }),
|
|
2033
|
-
showTypeColumn && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ColType, { children: typeColumnMode === "text" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TypeText, { children: resolveTypeLabel(doc._type, resolvedTypeLabels) }) : (() => {
|
|
2034
|
-
const typeColor = getTypeColor(doc._type);
|
|
2035
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TypeBadge, { $bgColor: typeColor.bg, $textColor: typeColor.text, children: resolveTypeLabel(doc._type, resolvedTypeLabels) });
|
|
2036
|
-
})() }),
|
|
2037
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ColScore, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(ScoreBadge, { $score: doc.health.score, children: [
|
|
2038
|
-
doc.health.score,
|
|
2039
|
-
"%"
|
|
2040
|
-
] }) }),
|
|
2041
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(ColIssues, { children: [
|
|
2042
|
-
doc.health.issues.slice(0, 2).map((issue) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(IssueTag, { children: [
|
|
2043
|
-
"\u2022 ",
|
|
2044
|
-
issue
|
|
2045
|
-
] }, `issue-${doc._id}-${issue}`)),
|
|
2046
|
-
doc.health.issues.length > 2 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2047
|
-
MoreIssuesWrapper,
|
|
2048
|
-
{
|
|
2049
|
-
onMouseEnter: function(e) {
|
|
2050
|
-
handleMouseEnterIssues(
|
|
2051
|
-
e.currentTarget,
|
|
2052
|
-
doc.health.issues.slice(2)
|
|
2053
|
-
);
|
|
2054
|
-
},
|
|
2055
|
-
onMouseLeave: handleMouseLeave,
|
|
2056
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(MoreIssues, { children: [
|
|
2057
|
-
"+",
|
|
2058
|
-
doc.health.issues.length - 2,
|
|
2059
|
-
" more issues"
|
|
2060
|
-
] })
|
|
2061
|
-
}
|
|
2062
|
-
)
|
|
2063
|
-
] })
|
|
2064
|
-
] }, doc._id);
|
|
2065
|
-
})
|
|
2066
|
-
] }))
|
|
2067
|
-
] }),
|
|
2068
|
-
activePopover && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2069
|
-
IssuesPopover,
|
|
2070
|
-
{
|
|
2071
|
-
style: {
|
|
2072
|
-
top: activePopover.top,
|
|
2073
|
-
left: activePopover.left,
|
|
2074
|
-
transform: "translateY(calc(-100% - 10px))"
|
|
2075
|
-
},
|
|
2076
|
-
children: activePopover.issues.map((issue) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(PopoverIssueItem, { children: [
|
|
2077
|
-
"\u26A0\uFE0F ",
|
|
2078
|
-
issue
|
|
2079
|
-
] }, issue))
|
|
2080
|
-
}
|
|
2081
|
-
),
|
|
2082
|
-
" "
|
|
2083
|
-
] }),
|
|
2084
|
-
" "
|
|
2085
|
-
] });
|
|
2086
|
-
};
|
|
2087
|
-
SeoHealthDashboard_default = SeoHealthDashboard;
|
|
2088
|
-
}
|
|
2089
|
-
});
|
|
2090
|
-
|
|
2091
|
-
// src/components/SeoHealthTool.tsx
|
|
2092
|
-
var SeoHealthTool_exports = {};
|
|
2093
|
-
__export(SeoHealthTool_exports, {
|
|
2094
|
-
default: () => SeoHealthTool_default
|
|
2095
|
-
});
|
|
2096
|
-
var import_jsx_runtime14, SeoHealthTool, SeoHealthTool_default;
|
|
2097
|
-
var init_SeoHealthTool = __esm({
|
|
2098
|
-
"src/components/SeoHealthTool.tsx"() {
|
|
2099
|
-
"use strict";
|
|
2100
|
-
init_SeoHealthDashboard();
|
|
2101
|
-
import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2102
|
-
SeoHealthTool = (props) => {
|
|
2103
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SeoHealthDashboard_default, __spreadValues({}, props));
|
|
2104
|
-
};
|
|
2105
|
-
SeoHealthTool_default = SeoHealthTool;
|
|
2106
|
-
}
|
|
2107
|
-
});
|
|
2108
|
-
|
|
2109
|
-
// src/index.ts
|
|
2110
|
-
var src_exports = {};
|
|
2111
|
-
__export(src_exports, {
|
|
2112
|
-
allSchemas: () => types,
|
|
2113
|
-
createSeoHealthPane: () => createSeoHealthPane,
|
|
2114
|
-
default: () => src_default,
|
|
2115
|
-
metaAttributeSchema: () => metaAttribute_default,
|
|
2116
|
-
metaTagSchema: () => metaTag_default,
|
|
2117
|
-
openGraphSchema: () => openGraph,
|
|
2118
|
-
robotsSchema: () => robots_default,
|
|
2119
|
-
seoFieldsSchema: () => seoFieldsSchema,
|
|
2120
|
-
twitterSchema: () => twitter
|
|
2121
|
-
});
|
|
2122
|
-
module.exports = __toCommonJS(src_exports);
|
|
2123
|
-
|
|
2124
|
-
// src/plugin.ts
|
|
2125
|
-
var import_react14 = __toESM(require("react"), 1);
|
|
2126
|
-
var import_sanity20 = require("sanity");
|
|
2127
|
-
|
|
2128
|
-
// src/schemas/index.ts
|
|
2129
|
-
var import_react12 = __toESM(require("react"), 1);
|
|
2130
|
-
var import_sanity15 = require("sanity");
|
|
2131
|
-
|
|
2132
|
-
// src/components/meta/MetaDescription.tsx
|
|
2133
|
-
var import_ui = require("@sanity/ui");
|
|
2134
|
-
var import_react = require("react");
|
|
2135
|
-
var import_sanity = require("sanity");
|
|
2136
|
-
init_seoUtils();
|
|
2137
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
2138
16
|
var MetaDescription = (props) => {
|
|
2139
17
|
const { value, renderDefault, path } = props;
|
|
2140
|
-
const parent =
|
|
18
|
+
const parent = sanity.useFormValue([path[0]]);
|
|
2141
19
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
2142
|
-
const keywords =
|
|
2143
|
-
const feedbackItems =
|
|
2144
|
-
() => getMetaDescriptionValidationMessages(value || "", keywords, isParentseoField),
|
|
20
|
+
const keywords = React12.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
21
|
+
const feedbackItems = React12.useMemo(
|
|
22
|
+
() => chunkIFDLKZET_cjs.getMetaDescriptionValidationMessages(value || "", keywords, isParentseoField),
|
|
2145
23
|
[value, keywords, isParentseoField]
|
|
2146
24
|
);
|
|
2147
|
-
return /* @__PURE__ */
|
|
25
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
2148
26
|
renderDefault(props),
|
|
2149
|
-
/* @__PURE__ */
|
|
2150
|
-
/* @__PURE__ */
|
|
27
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
28
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2151
29
|
"div",
|
|
2152
30
|
{
|
|
2153
31
|
style: { width: 10, height: 10, borderRadius: "50%", backgroundColor: item.color }
|
|
2154
32
|
}
|
|
2155
33
|
),
|
|
2156
|
-
/* @__PURE__ */
|
|
34
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
2157
35
|
] }, item.text)) })
|
|
2158
36
|
] });
|
|
2159
37
|
};
|
|
2160
38
|
var MetaDescription_default = MetaDescription;
|
|
2161
|
-
|
|
2162
|
-
// src/components/meta/MetaImage.tsx
|
|
2163
|
-
var import_ui2 = require("@sanity/ui");
|
|
2164
|
-
var import_react2 = require("react");
|
|
2165
|
-
var import_sanity2 = require("sanity");
|
|
2166
|
-
init_seoUtils();
|
|
2167
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
2168
39
|
var MetaImage = (props) => {
|
|
2169
40
|
const { value, renderDefault, path } = props;
|
|
2170
|
-
const seoParent =
|
|
41
|
+
const seoParent = sanity.useFormValue([path[0]]);
|
|
2171
42
|
const hasImage = !!(value == null ? void 0 : value.asset);
|
|
2172
|
-
const feedbackItems =
|
|
2173
|
-
() => getMetaImageValidation(hasImage, seoParent),
|
|
43
|
+
const feedbackItems = React12.useMemo(
|
|
44
|
+
() => chunkIFDLKZET_cjs.getMetaImageValidation(hasImage, seoParent),
|
|
2174
45
|
[hasImage, seoParent]
|
|
2175
46
|
);
|
|
2176
|
-
return /* @__PURE__ */
|
|
47
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
2177
48
|
renderDefault(props),
|
|
2178
|
-
/* @__PURE__ */
|
|
2179
|
-
/* @__PURE__ */
|
|
49
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
50
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2180
51
|
"div",
|
|
2181
52
|
{
|
|
2182
53
|
style: {
|
|
@@ -2187,31 +58,24 @@ var MetaImage = (props) => {
|
|
|
2187
58
|
}
|
|
2188
59
|
}
|
|
2189
60
|
),
|
|
2190
|
-
/* @__PURE__ */
|
|
61
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
2191
62
|
] }, item.text)) })
|
|
2192
63
|
] });
|
|
2193
64
|
};
|
|
2194
65
|
var MetaImage_default = MetaImage;
|
|
2195
|
-
|
|
2196
|
-
// src/components/meta/MetaTitle.tsx
|
|
2197
|
-
var import_ui3 = require("@sanity/ui");
|
|
2198
|
-
var import_react3 = require("react");
|
|
2199
|
-
var import_sanity3 = require("sanity");
|
|
2200
|
-
init_seoUtils();
|
|
2201
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
2202
66
|
var MetaTitle = (props) => {
|
|
2203
67
|
const { value, renderDefault, path } = props;
|
|
2204
|
-
const parent =
|
|
68
|
+
const parent = sanity.useFormValue([path[0]]);
|
|
2205
69
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
2206
|
-
const keywords =
|
|
2207
|
-
const feedbackItems =
|
|
2208
|
-
() => getMetaTitleValidationMessages(value || "", keywords, isParentseoField),
|
|
70
|
+
const keywords = React12.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
71
|
+
const feedbackItems = React12.useMemo(
|
|
72
|
+
() => chunkIFDLKZET_cjs.getMetaTitleValidationMessages(value || "", keywords, isParentseoField),
|
|
2209
73
|
[value, keywords, isParentseoField]
|
|
2210
74
|
);
|
|
2211
|
-
return /* @__PURE__ */
|
|
75
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
2212
76
|
renderDefault(props),
|
|
2213
|
-
/* @__PURE__ */
|
|
2214
|
-
/* @__PURE__ */
|
|
77
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
78
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2215
79
|
"div",
|
|
2216
80
|
{
|
|
2217
81
|
style: {
|
|
@@ -2222,7 +86,7 @@ var MetaTitle = (props) => {
|
|
|
2222
86
|
}
|
|
2223
87
|
}
|
|
2224
88
|
),
|
|
2225
|
-
/* @__PURE__ */
|
|
89
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
2226
90
|
] }, item.text)) })
|
|
2227
91
|
] });
|
|
2228
92
|
};
|
|
@@ -2350,29 +214,19 @@ var getFieldHiddenFunction = (fieldName, config) => {
|
|
|
2350
214
|
var isEmpty = (value) => {
|
|
2351
215
|
return value === null || value === void 0 || typeof value === "string" && value.trim() === "" || Array.isArray(value) && value.length === 0 || typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
|
|
2352
216
|
};
|
|
2353
|
-
|
|
2354
|
-
// src/schemas/types/openGraph/index.ts
|
|
2355
|
-
var import_sanity8 = require("sanity");
|
|
2356
|
-
|
|
2357
|
-
// src/components/openGraph/OgDescription.tsx
|
|
2358
|
-
var import_ui4 = require("@sanity/ui");
|
|
2359
|
-
var import_react4 = require("react");
|
|
2360
|
-
var import_sanity4 = require("sanity");
|
|
2361
|
-
init_seoUtils();
|
|
2362
|
-
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
2363
217
|
var OgDescription = (props) => {
|
|
2364
218
|
const { value, renderDefault, path } = props;
|
|
2365
|
-
const parent =
|
|
219
|
+
const parent = sanity.useFormValue([path[0]]);
|
|
2366
220
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
2367
|
-
const keywords =
|
|
2368
|
-
const feedbackItems =
|
|
2369
|
-
() => getOgDescriptionValidation(value || "", keywords, isParentseoField),
|
|
221
|
+
const keywords = React12.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
222
|
+
const feedbackItems = React12.useMemo(
|
|
223
|
+
() => chunkIFDLKZET_cjs.getOgDescriptionValidation(value || "", keywords, isParentseoField),
|
|
2370
224
|
[value, keywords, isParentseoField]
|
|
2371
225
|
);
|
|
2372
|
-
return /* @__PURE__ */
|
|
226
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
2373
227
|
renderDefault(props),
|
|
2374
|
-
/* @__PURE__ */
|
|
2375
|
-
/* @__PURE__ */
|
|
228
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
229
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2376
230
|
"div",
|
|
2377
231
|
{
|
|
2378
232
|
style: {
|
|
@@ -2383,32 +237,25 @@ var OgDescription = (props) => {
|
|
|
2383
237
|
}
|
|
2384
238
|
}
|
|
2385
239
|
),
|
|
2386
|
-
/* @__PURE__ */
|
|
240
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
2387
241
|
] }, item.text)) })
|
|
2388
242
|
] });
|
|
2389
243
|
};
|
|
2390
244
|
var OgDescription_default = OgDescription;
|
|
2391
|
-
|
|
2392
|
-
// src/components/openGraph/OgImage.tsx
|
|
2393
|
-
var import_ui5 = require("@sanity/ui");
|
|
2394
|
-
var import_react5 = require("react");
|
|
2395
|
-
var import_sanity5 = require("sanity");
|
|
2396
|
-
init_seoUtils();
|
|
2397
|
-
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
2398
245
|
var OgImage = (props) => {
|
|
2399
246
|
const { value, renderDefault, path } = props;
|
|
2400
|
-
const seoParent =
|
|
247
|
+
const seoParent = sanity.useFormValue([path[0]]);
|
|
2401
248
|
const imgValue = value;
|
|
2402
249
|
const hasImage = !!(imgValue == null ? void 0 : imgValue.asset);
|
|
2403
250
|
const altText = imgValue == null ? void 0 : imgValue.alt;
|
|
2404
|
-
const feedbackItems =
|
|
2405
|
-
() => getOgImageValidation(hasImage, altText, seoParent),
|
|
251
|
+
const feedbackItems = React12.useMemo(
|
|
252
|
+
() => chunkIFDLKZET_cjs.getOgImageValidation(hasImage, altText, seoParent),
|
|
2406
253
|
[hasImage, altText, seoParent]
|
|
2407
254
|
);
|
|
2408
|
-
return /* @__PURE__ */
|
|
255
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
2409
256
|
renderDefault(props),
|
|
2410
|
-
/* @__PURE__ */
|
|
2411
|
-
/* @__PURE__ */
|
|
257
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
258
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2412
259
|
"div",
|
|
2413
260
|
{
|
|
2414
261
|
style: {
|
|
@@ -2419,26 +266,19 @@ var OgImage = (props) => {
|
|
|
2419
266
|
}
|
|
2420
267
|
}
|
|
2421
268
|
),
|
|
2422
|
-
/* @__PURE__ */
|
|
269
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
2423
270
|
] }, item.text)) })
|
|
2424
271
|
] });
|
|
2425
272
|
};
|
|
2426
273
|
var OgImage_default = OgImage;
|
|
2427
|
-
|
|
2428
|
-
// src/components/openGraph/OgImageUrl.tsx
|
|
2429
|
-
var import_ui6 = require("@sanity/ui");
|
|
2430
|
-
var import_react6 = require("react");
|
|
2431
|
-
var import_sanity6 = require("sanity");
|
|
2432
|
-
init_seoUtils();
|
|
2433
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2434
274
|
var OgImageUrl = (props) => {
|
|
2435
275
|
const { value, renderDefault, path } = props;
|
|
2436
|
-
const seoParent =
|
|
2437
|
-
const feedbackItems =
|
|
2438
|
-
return /* @__PURE__ */
|
|
276
|
+
const seoParent = sanity.useFormValue([path[0]]);
|
|
277
|
+
const feedbackItems = React12.useMemo(() => chunkIFDLKZET_cjs.getOgImageUrlValidation(value, seoParent), [value, seoParent]);
|
|
278
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
2439
279
|
renderDefault(props),
|
|
2440
|
-
/* @__PURE__ */
|
|
2441
|
-
/* @__PURE__ */
|
|
280
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
281
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2442
282
|
"div",
|
|
2443
283
|
{
|
|
2444
284
|
style: {
|
|
@@ -2449,31 +289,24 @@ var OgImageUrl = (props) => {
|
|
|
2449
289
|
}
|
|
2450
290
|
}
|
|
2451
291
|
),
|
|
2452
|
-
/* @__PURE__ */
|
|
292
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
2453
293
|
] }, item.text)) })
|
|
2454
294
|
] });
|
|
2455
295
|
};
|
|
2456
296
|
var OgImageUrl_default = OgImageUrl;
|
|
2457
|
-
|
|
2458
|
-
// src/components/openGraph/OgTitle.tsx
|
|
2459
|
-
var import_ui7 = require("@sanity/ui");
|
|
2460
|
-
var import_react7 = require("react");
|
|
2461
|
-
var import_sanity7 = require("sanity");
|
|
2462
|
-
init_seoUtils();
|
|
2463
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2464
297
|
var OgTitle = (props) => {
|
|
2465
298
|
const { value, renderDefault, path } = props;
|
|
2466
|
-
const parent =
|
|
299
|
+
const parent = sanity.useFormValue([path[0]]);
|
|
2467
300
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
2468
|
-
const keywords =
|
|
2469
|
-
const feedbackItems =
|
|
2470
|
-
() => getOgTitleValidation(value || "", keywords, isParentseoField),
|
|
301
|
+
const keywords = React12.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
302
|
+
const feedbackItems = React12.useMemo(
|
|
303
|
+
() => chunkIFDLKZET_cjs.getOgTitleValidation(value || "", keywords, isParentseoField),
|
|
2471
304
|
[value, keywords, isParentseoField]
|
|
2472
305
|
);
|
|
2473
|
-
return /* @__PURE__ */
|
|
306
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
2474
307
|
renderDefault(props),
|
|
2475
|
-
/* @__PURE__ */
|
|
2476
|
-
/* @__PURE__ */
|
|
308
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
309
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2477
310
|
"div",
|
|
2478
311
|
{
|
|
2479
312
|
style: {
|
|
@@ -2484,7 +317,7 @@ var OgTitle = (props) => {
|
|
|
2484
317
|
}
|
|
2485
318
|
}
|
|
2486
319
|
),
|
|
2487
|
-
/* @__PURE__ */
|
|
320
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
2488
321
|
] }, item.text)) })
|
|
2489
322
|
] });
|
|
2490
323
|
};
|
|
@@ -2492,19 +325,19 @@ var OgTitle_default = OgTitle;
|
|
|
2492
325
|
|
|
2493
326
|
// src/schemas/types/openGraph/index.ts
|
|
2494
327
|
function openGraph(config = {}) {
|
|
2495
|
-
return
|
|
328
|
+
return sanity.defineType({
|
|
2496
329
|
name: "openGraph",
|
|
2497
330
|
title: "Open Graph Settings",
|
|
2498
331
|
type: "object",
|
|
2499
332
|
fields: [
|
|
2500
|
-
|
|
333
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2501
334
|
name: "url",
|
|
2502
335
|
type: "url"
|
|
2503
336
|
}, getFieldInfo("openGraphUrl", config.fieldOverrides)), {
|
|
2504
337
|
hidden: getFieldHiddenFunction("openGraphUrl", config),
|
|
2505
338
|
description: "The canonical URL of the page. This should be the full URL including protocol (https://)."
|
|
2506
339
|
})),
|
|
2507
|
-
|
|
340
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2508
341
|
name: "title"
|
|
2509
342
|
}, getFieldInfo("openGraphTitle", config.fieldOverrides)), {
|
|
2510
343
|
type: "string",
|
|
@@ -2514,7 +347,7 @@ function openGraph(config = {}) {
|
|
|
2514
347
|
// Can also wrap with a string input + preview
|
|
2515
348
|
}
|
|
2516
349
|
})),
|
|
2517
|
-
|
|
350
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2518
351
|
name: "description"
|
|
2519
352
|
}, getFieldInfo("openGraphDescription", config.fieldOverrides)), {
|
|
2520
353
|
type: "text",
|
|
@@ -2525,13 +358,13 @@ function openGraph(config = {}) {
|
|
|
2525
358
|
// Can also wrap with a text area + preview
|
|
2526
359
|
}
|
|
2527
360
|
})),
|
|
2528
|
-
|
|
361
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2529
362
|
name: "siteName"
|
|
2530
363
|
}, getFieldInfo("openGraphSiteName", config.fieldOverrides)), {
|
|
2531
364
|
type: "string",
|
|
2532
365
|
hidden: getFieldHiddenFunction("openGraphSiteName", config)
|
|
2533
366
|
})),
|
|
2534
|
-
|
|
367
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2535
368
|
name: "type"
|
|
2536
369
|
}, getFieldInfo("openGraphType", config.fieldOverrides)), {
|
|
2537
370
|
type: "string",
|
|
@@ -2550,7 +383,7 @@ function openGraph(config = {}) {
|
|
|
2550
383
|
hidden: getFieldHiddenFunction("openGraphType", config),
|
|
2551
384
|
initialValue: "website"
|
|
2552
385
|
})),
|
|
2553
|
-
|
|
386
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2554
387
|
name: "imageType"
|
|
2555
388
|
}, getFieldInfo("openGraphImageType", config.fieldOverrides)), {
|
|
2556
389
|
type: "string",
|
|
@@ -2563,7 +396,7 @@ function openGraph(config = {}) {
|
|
|
2563
396
|
hidden: getFieldHiddenFunction("openGraphImage", config),
|
|
2564
397
|
initialValue: "upload"
|
|
2565
398
|
})),
|
|
2566
|
-
|
|
399
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2567
400
|
name: "image"
|
|
2568
401
|
}, getFieldInfo("openGraphImage", config.fieldOverrides)), {
|
|
2569
402
|
type: "image",
|
|
@@ -2574,7 +407,7 @@ function openGraph(config = {}) {
|
|
|
2574
407
|
input: OgImage_default
|
|
2575
408
|
},
|
|
2576
409
|
fields: [
|
|
2577
|
-
|
|
410
|
+
sanity.defineField({
|
|
2578
411
|
name: "alt",
|
|
2579
412
|
title: "Image Alt Text",
|
|
2580
413
|
type: "string",
|
|
@@ -2588,7 +421,7 @@ function openGraph(config = {}) {
|
|
|
2588
421
|
return typeof hiddenFn === "function" ? hiddenFn(context) : hiddenFn;
|
|
2589
422
|
}
|
|
2590
423
|
})),
|
|
2591
|
-
|
|
424
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2592
425
|
name: "imageUrl"
|
|
2593
426
|
}, getFieldInfo("openGraphImageUrl", config.fieldOverrides)), {
|
|
2594
427
|
type: "url",
|
|
@@ -2605,29 +438,19 @@ function openGraph(config = {}) {
|
|
|
2605
438
|
]
|
|
2606
439
|
});
|
|
2607
440
|
}
|
|
2608
|
-
|
|
2609
|
-
// src/schemas/types/twitter/index.ts
|
|
2610
|
-
var import_sanity13 = require("sanity");
|
|
2611
|
-
|
|
2612
|
-
// src/components/twitter/twitterDescription.tsx
|
|
2613
|
-
var import_ui8 = require("@sanity/ui");
|
|
2614
|
-
var import_react8 = require("react");
|
|
2615
|
-
var import_sanity9 = require("sanity");
|
|
2616
|
-
init_seoUtils();
|
|
2617
|
-
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2618
441
|
var TwitterDescription = (props) => {
|
|
2619
442
|
const { value, renderDefault, path } = props;
|
|
2620
|
-
const parent =
|
|
443
|
+
const parent = sanity.useFormValue([path[0]]);
|
|
2621
444
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
2622
|
-
const keywords =
|
|
2623
|
-
const feedbackItems =
|
|
2624
|
-
() => getTwitterDescriptionValidation(value || "", keywords, isParentseoField),
|
|
445
|
+
const keywords = React12.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
446
|
+
const feedbackItems = React12.useMemo(
|
|
447
|
+
() => chunkIFDLKZET_cjs.getTwitterDescriptionValidation(value || "", keywords, isParentseoField),
|
|
2625
448
|
[value, keywords, isParentseoField]
|
|
2626
449
|
);
|
|
2627
|
-
return /* @__PURE__ */
|
|
450
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
2628
451
|
renderDefault(props),
|
|
2629
|
-
/* @__PURE__ */
|
|
2630
|
-
/* @__PURE__ */
|
|
452
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
453
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2631
454
|
"div",
|
|
2632
455
|
{
|
|
2633
456
|
style: {
|
|
@@ -2638,32 +461,25 @@ var TwitterDescription = (props) => {
|
|
|
2638
461
|
}
|
|
2639
462
|
}
|
|
2640
463
|
),
|
|
2641
|
-
/* @__PURE__ */
|
|
464
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
2642
465
|
] }, item.text)) })
|
|
2643
466
|
] });
|
|
2644
467
|
};
|
|
2645
468
|
var twitterDescription_default = TwitterDescription;
|
|
2646
|
-
|
|
2647
|
-
// src/components/twitter/TwitterImage.tsx
|
|
2648
|
-
var import_ui9 = require("@sanity/ui");
|
|
2649
|
-
var import_react9 = require("react");
|
|
2650
|
-
var import_sanity10 = require("sanity");
|
|
2651
|
-
init_seoUtils();
|
|
2652
|
-
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2653
469
|
var TwitterImage = (props) => {
|
|
2654
470
|
const { value, renderDefault, path } = props;
|
|
2655
|
-
const seoParent =
|
|
471
|
+
const seoParent = sanity.useFormValue([path[0]]);
|
|
2656
472
|
const imgValue = value;
|
|
2657
473
|
const hasImage = !!(imgValue == null ? void 0 : imgValue.asset);
|
|
2658
474
|
const altText = imgValue == null ? void 0 : imgValue.alt;
|
|
2659
|
-
const feedbackItems =
|
|
2660
|
-
() => getTwitterImageValidation(hasImage, altText, seoParent),
|
|
475
|
+
const feedbackItems = React12.useMemo(
|
|
476
|
+
() => chunkIFDLKZET_cjs.getTwitterImageValidation(hasImage, altText, seoParent),
|
|
2661
477
|
[hasImage, altText, seoParent]
|
|
2662
478
|
);
|
|
2663
|
-
return /* @__PURE__ */
|
|
479
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
2664
480
|
renderDefault(props),
|
|
2665
|
-
/* @__PURE__ */
|
|
2666
|
-
/* @__PURE__ */
|
|
481
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
482
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2667
483
|
"div",
|
|
2668
484
|
{
|
|
2669
485
|
style: {
|
|
@@ -2674,29 +490,22 @@ var TwitterImage = (props) => {
|
|
|
2674
490
|
}
|
|
2675
491
|
}
|
|
2676
492
|
),
|
|
2677
|
-
/* @__PURE__ */
|
|
493
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
2678
494
|
] }, item.text)) })
|
|
2679
495
|
] });
|
|
2680
496
|
};
|
|
2681
497
|
var TwitterImage_default = TwitterImage;
|
|
2682
|
-
|
|
2683
|
-
// src/components/twitter/TwitterImageUrl.tsx
|
|
2684
|
-
var import_ui10 = require("@sanity/ui");
|
|
2685
|
-
var import_react10 = require("react");
|
|
2686
|
-
var import_sanity11 = require("sanity");
|
|
2687
|
-
init_seoUtils();
|
|
2688
|
-
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2689
498
|
var TwitterImageUrl = (props) => {
|
|
2690
499
|
const { value, renderDefault, path } = props;
|
|
2691
|
-
const seoParent =
|
|
2692
|
-
const feedbackItems =
|
|
2693
|
-
() => getTwitterImageUrlValidation(value, seoParent),
|
|
500
|
+
const seoParent = sanity.useFormValue([path[0]]);
|
|
501
|
+
const feedbackItems = React12.useMemo(
|
|
502
|
+
() => chunkIFDLKZET_cjs.getTwitterImageUrlValidation(value, seoParent),
|
|
2694
503
|
[value, seoParent]
|
|
2695
504
|
);
|
|
2696
|
-
return /* @__PURE__ */
|
|
505
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
2697
506
|
renderDefault(props),
|
|
2698
|
-
/* @__PURE__ */
|
|
2699
|
-
/* @__PURE__ */
|
|
507
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
508
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2700
509
|
"div",
|
|
2701
510
|
{
|
|
2702
511
|
style: {
|
|
@@ -2707,31 +516,24 @@ var TwitterImageUrl = (props) => {
|
|
|
2707
516
|
}
|
|
2708
517
|
}
|
|
2709
518
|
),
|
|
2710
|
-
/* @__PURE__ */
|
|
519
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
2711
520
|
] }, item.text)) })
|
|
2712
521
|
] });
|
|
2713
522
|
};
|
|
2714
523
|
var TwitterImageUrl_default = TwitterImageUrl;
|
|
2715
|
-
|
|
2716
|
-
// src/components/twitter/twitterTitle.tsx
|
|
2717
|
-
var import_ui11 = require("@sanity/ui");
|
|
2718
|
-
var import_react11 = require("react");
|
|
2719
|
-
var import_sanity12 = require("sanity");
|
|
2720
|
-
init_seoUtils();
|
|
2721
|
-
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2722
524
|
var TwitterTitle = (props) => {
|
|
2723
525
|
const { value, renderDefault, path } = props;
|
|
2724
|
-
const parent =
|
|
526
|
+
const parent = sanity.useFormValue([path[0]]);
|
|
2725
527
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
2726
|
-
const keywords =
|
|
2727
|
-
const feedbackItems =
|
|
2728
|
-
() => getTwitterTitleValidation(value || "", keywords, isParentseoField),
|
|
528
|
+
const keywords = React12.useMemo(() => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
529
|
+
const feedbackItems = React12.useMemo(
|
|
530
|
+
() => chunkIFDLKZET_cjs.getTwitterTitleValidation(value || "", keywords, isParentseoField),
|
|
2729
531
|
[value, keywords, isParentseoField]
|
|
2730
532
|
);
|
|
2731
|
-
return /* @__PURE__ */
|
|
533
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
2732
534
|
renderDefault(props),
|
|
2733
|
-
/* @__PURE__ */
|
|
2734
|
-
/* @__PURE__ */
|
|
535
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
536
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2735
537
|
"div",
|
|
2736
538
|
{
|
|
2737
539
|
style: {
|
|
@@ -2742,7 +544,7 @@ var TwitterTitle = (props) => {
|
|
|
2742
544
|
}
|
|
2743
545
|
}
|
|
2744
546
|
),
|
|
2745
|
-
/* @__PURE__ */
|
|
547
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
2746
548
|
] }, item.text)) })
|
|
2747
549
|
] });
|
|
2748
550
|
};
|
|
@@ -2750,12 +552,12 @@ var twitterTitle_default = TwitterTitle;
|
|
|
2750
552
|
|
|
2751
553
|
// src/schemas/types/twitter/index.ts
|
|
2752
554
|
function twitter(config = {}) {
|
|
2753
|
-
return
|
|
555
|
+
return sanity.defineType({
|
|
2754
556
|
name: "twitter",
|
|
2755
557
|
title: "X (Formerly Twitter)",
|
|
2756
558
|
type: "object",
|
|
2757
559
|
fields: [
|
|
2758
|
-
|
|
560
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2759
561
|
name: "card"
|
|
2760
562
|
}, getFieldInfo("twitterCard", config.fieldOverrides)), {
|
|
2761
563
|
type: "string",
|
|
@@ -2771,19 +573,19 @@ function twitter(config = {}) {
|
|
|
2771
573
|
initialValue: "summary_large_image"
|
|
2772
574
|
// good default
|
|
2773
575
|
})),
|
|
2774
|
-
|
|
576
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2775
577
|
name: "site"
|
|
2776
578
|
}, getFieldInfo("twitterSite", config.fieldOverrides)), {
|
|
2777
579
|
type: "string",
|
|
2778
580
|
hidden: getFieldHiddenFunction("twitterSite", config)
|
|
2779
581
|
})),
|
|
2780
|
-
|
|
582
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2781
583
|
name: "creator",
|
|
2782
584
|
type: "string"
|
|
2783
585
|
}, getFieldInfo("twitterCreator", config.fieldOverrides)), {
|
|
2784
586
|
hidden: getFieldHiddenFunction("twitterCreator", config)
|
|
2785
587
|
})),
|
|
2786
|
-
|
|
588
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2787
589
|
name: "title",
|
|
2788
590
|
type: "string"
|
|
2789
591
|
}, getFieldInfo("twitterTitle", config.fieldOverrides)), {
|
|
@@ -2792,7 +594,7 @@ function twitter(config = {}) {
|
|
|
2792
594
|
input: twitterTitle_default
|
|
2793
595
|
}
|
|
2794
596
|
})),
|
|
2795
|
-
|
|
597
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2796
598
|
name: "description",
|
|
2797
599
|
type: "text",
|
|
2798
600
|
rows: 3
|
|
@@ -2802,7 +604,7 @@ function twitter(config = {}) {
|
|
|
2802
604
|
input: twitterDescription_default
|
|
2803
605
|
}
|
|
2804
606
|
})),
|
|
2805
|
-
|
|
607
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2806
608
|
name: "imageType"
|
|
2807
609
|
}, getFieldInfo("twitterImageType", config.fieldOverrides)), {
|
|
2808
610
|
type: "string",
|
|
@@ -2815,7 +617,7 @@ function twitter(config = {}) {
|
|
|
2815
617
|
hidden: getFieldHiddenFunction("twitterImage", config),
|
|
2816
618
|
initialValue: "upload"
|
|
2817
619
|
})),
|
|
2818
|
-
|
|
620
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2819
621
|
name: "image"
|
|
2820
622
|
}, getFieldInfo("twitterImage", config.fieldOverrides)), {
|
|
2821
623
|
type: "image",
|
|
@@ -2826,7 +628,7 @@ function twitter(config = {}) {
|
|
|
2826
628
|
input: TwitterImage_default
|
|
2827
629
|
},
|
|
2828
630
|
fields: [
|
|
2829
|
-
|
|
631
|
+
sanity.defineField({
|
|
2830
632
|
name: "alt",
|
|
2831
633
|
title: "Image Alt Text",
|
|
2832
634
|
type: "string",
|
|
@@ -2840,7 +642,7 @@ function twitter(config = {}) {
|
|
|
2840
642
|
return typeof hiddenFn === "function" ? hiddenFn(context) : hiddenFn;
|
|
2841
643
|
}
|
|
2842
644
|
})),
|
|
2843
|
-
|
|
645
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2844
646
|
name: "imageUrl"
|
|
2845
647
|
}, getFieldInfo("twitterImageUrl", config.fieldOverrides)), {
|
|
2846
648
|
type: "url",
|
|
@@ -2859,15 +661,15 @@ function twitter(config = {}) {
|
|
|
2859
661
|
}
|
|
2860
662
|
|
|
2861
663
|
// src/schemas/index.ts
|
|
2862
|
-
var LazySeoPreview =
|
|
2863
|
-
var SeoPreviewWrapper = (props) =>
|
|
664
|
+
var LazySeoPreview = React12__default.default.lazy(() => import('./SeoPreview-Y3CFDVBR.cjs'));
|
|
665
|
+
var SeoPreviewWrapper = (props) => React12__default.default.createElement(React12__default.default.Suspense, { fallback: null }, React12__default.default.createElement(LazySeoPreview, props));
|
|
2864
666
|
function seoFieldsSchema(config = {}) {
|
|
2865
|
-
return
|
|
667
|
+
return sanity.defineType({
|
|
2866
668
|
name: "seoFields",
|
|
2867
669
|
title: "SEO Fields",
|
|
2868
670
|
type: "object",
|
|
2869
671
|
fields: [
|
|
2870
|
-
|
|
672
|
+
sanity.defineField({
|
|
2871
673
|
name: "robots",
|
|
2872
674
|
title: "Robots Settings",
|
|
2873
675
|
type: "robots",
|
|
@@ -2876,12 +678,12 @@ function seoFieldsSchema(config = {}) {
|
|
|
2876
678
|
}),
|
|
2877
679
|
// 👇 conditionally spread preview field
|
|
2878
680
|
...typeof config.seoPreview === "boolean" && config.seoPreview || typeof config.seoPreview === "object" && !isEmpty(config.seoPreview) ? [
|
|
2879
|
-
|
|
681
|
+
sanity.defineField({
|
|
2880
682
|
name: "preview",
|
|
2881
683
|
title: "SEO Preview",
|
|
2882
684
|
type: "string",
|
|
2883
685
|
components: { input: SeoPreviewWrapper },
|
|
2884
|
-
options: __spreadValues({
|
|
686
|
+
options: chunkS367Y35J_cjs.__spreadValues({
|
|
2885
687
|
baseUrl: config.baseUrl || "https://www.example.com"
|
|
2886
688
|
}, typeof config.seoPreview === "object" && config.seoPreview && config.seoPreview.prefix ? { prefix: config.seoPreview.prefix } : {}),
|
|
2887
689
|
// Use a readOnly field to prevent editing
|
|
@@ -2891,7 +693,7 @@ function seoFieldsSchema(config = {}) {
|
|
|
2891
693
|
readOnly: true
|
|
2892
694
|
})
|
|
2893
695
|
] : [],
|
|
2894
|
-
|
|
696
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2895
697
|
name: "title"
|
|
2896
698
|
}, getFieldInfo("title", config.fieldOverrides)), {
|
|
2897
699
|
// title: 'Meta Title',
|
|
@@ -2904,7 +706,7 @@ function seoFieldsSchema(config = {}) {
|
|
|
2904
706
|
// validation: (Rule) => Rule.max(60).warning('Meta title should be under 60 characters.'),
|
|
2905
707
|
hidden: getFieldHiddenFunction("title", config)
|
|
2906
708
|
})),
|
|
2907
|
-
|
|
709
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2908
710
|
name: "description"
|
|
2909
711
|
}, getFieldInfo("description", config.fieldOverrides)), {
|
|
2910
712
|
// title: 'Meta Description',
|
|
@@ -2918,7 +720,7 @@ function seoFieldsSchema(config = {}) {
|
|
|
2918
720
|
// validation: (Rule) => Rule.max(160).warning('Meta description should be under 160 characters.'),
|
|
2919
721
|
hidden: getFieldHiddenFunction("description", config)
|
|
2920
722
|
})),
|
|
2921
|
-
|
|
723
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2922
724
|
name: "metaImage"
|
|
2923
725
|
}, getFieldInfo("metaImage", config.fieldOverrides)), {
|
|
2924
726
|
// title: 'Meta Image',
|
|
@@ -2933,7 +735,7 @@ function seoFieldsSchema(config = {}) {
|
|
|
2933
735
|
},
|
|
2934
736
|
hidden: getFieldHiddenFunction("metaImage", config)
|
|
2935
737
|
})),
|
|
2936
|
-
|
|
738
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2937
739
|
name: "metaAttributes"
|
|
2938
740
|
}, getFieldInfo("metaAttributes", config.fieldOverrides)), {
|
|
2939
741
|
type: "array",
|
|
@@ -2942,7 +744,7 @@ function seoFieldsSchema(config = {}) {
|
|
|
2942
744
|
// 'Add custom meta attributes to the head of the document for additional SEO and social media integration.',
|
|
2943
745
|
hidden: getFieldHiddenFunction("metaAttributes", config)
|
|
2944
746
|
})),
|
|
2945
|
-
|
|
747
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2946
748
|
name: "keywords"
|
|
2947
749
|
}, getFieldInfo("keywords", config.fieldOverrides)), {
|
|
2948
750
|
title: "Keywords",
|
|
@@ -2951,7 +753,7 @@ function seoFieldsSchema(config = {}) {
|
|
|
2951
753
|
description: "Add relevant keywords for this page. These keywords will be used for SEO purposes.",
|
|
2952
754
|
hidden: getFieldHiddenFunction("keywords", config)
|
|
2953
755
|
})),
|
|
2954
|
-
|
|
756
|
+
sanity.defineField(chunkS367Y35J_cjs.__spreadProps(chunkS367Y35J_cjs.__spreadValues({
|
|
2955
757
|
name: "canonicalUrl"
|
|
2956
758
|
}, getFieldInfo("canonicalUrl", config.fieldOverrides)), {
|
|
2957
759
|
title: "Canonical URL",
|
|
@@ -2964,20 +766,17 @@ function seoFieldsSchema(config = {}) {
|
|
|
2964
766
|
]
|
|
2965
767
|
});
|
|
2966
768
|
}
|
|
2967
|
-
|
|
2968
|
-
// src/schemas/types/metaAttribute/index.ts
|
|
2969
|
-
var import_sanity16 = require("sanity");
|
|
2970
|
-
var metaAttribute_default = (0, import_sanity16.defineType)({
|
|
769
|
+
var metaAttribute_default = sanity.defineType({
|
|
2971
770
|
name: "metaAttribute",
|
|
2972
771
|
title: "Meta Attribute",
|
|
2973
772
|
type: "object",
|
|
2974
773
|
fields: [
|
|
2975
|
-
|
|
774
|
+
sanity.defineField({
|
|
2976
775
|
name: "key",
|
|
2977
776
|
title: "Attribute Name",
|
|
2978
777
|
type: "string"
|
|
2979
778
|
}),
|
|
2980
|
-
|
|
779
|
+
sanity.defineField({
|
|
2981
780
|
name: "type",
|
|
2982
781
|
title: "Attribute Value Type",
|
|
2983
782
|
type: "string",
|
|
@@ -2989,13 +788,13 @@ var metaAttribute_default = (0, import_sanity16.defineType)({
|
|
|
2989
788
|
},
|
|
2990
789
|
initialValue: "string"
|
|
2991
790
|
}),
|
|
2992
|
-
|
|
791
|
+
sanity.defineField({
|
|
2993
792
|
name: "value",
|
|
2994
793
|
title: "Attribute Value",
|
|
2995
794
|
type: "string",
|
|
2996
795
|
hidden: ({ parent }) => (parent == null ? void 0 : parent.type) === "image"
|
|
2997
796
|
}),
|
|
2998
|
-
|
|
797
|
+
sanity.defineField({
|
|
2999
798
|
name: "image",
|
|
3000
799
|
title: "Attribute Image Value",
|
|
3001
800
|
type: "image",
|
|
@@ -3025,10 +824,7 @@ var metaAttribute_default = (0, import_sanity16.defineType)({
|
|
|
3025
824
|
}
|
|
3026
825
|
}
|
|
3027
826
|
});
|
|
3028
|
-
|
|
3029
|
-
// src/schemas/types/metaTag/index.ts
|
|
3030
|
-
var import_sanity17 = require("sanity");
|
|
3031
|
-
var metaTag_default = (0, import_sanity17.defineType)({
|
|
827
|
+
var metaTag_default = sanity.defineType({
|
|
3032
828
|
name: "metaTag",
|
|
3033
829
|
title: "Meta Tag",
|
|
3034
830
|
type: "object",
|
|
@@ -3042,22 +838,19 @@ var metaTag_default = (0, import_sanity17.defineType)({
|
|
|
3042
838
|
}
|
|
3043
839
|
]
|
|
3044
840
|
});
|
|
3045
|
-
|
|
3046
|
-
// src/schemas/types/robots/index.ts
|
|
3047
|
-
var import_sanity18 = require("sanity");
|
|
3048
|
-
var robots_default = (0, import_sanity18.defineType)({
|
|
841
|
+
var robots_default = sanity.defineType({
|
|
3049
842
|
name: "robots",
|
|
3050
843
|
title: "Robots Settings",
|
|
3051
844
|
type: "object",
|
|
3052
845
|
fields: [
|
|
3053
|
-
|
|
846
|
+
sanity.defineField({
|
|
3054
847
|
name: "noIndex",
|
|
3055
848
|
title: "No Index",
|
|
3056
849
|
type: "boolean",
|
|
3057
850
|
initialValue: false,
|
|
3058
851
|
description: "Enable this to prevent search engines from indexing this page. The page will not appear in search results."
|
|
3059
852
|
}),
|
|
3060
|
-
|
|
853
|
+
sanity.defineField({
|
|
3061
854
|
name: "noFollow",
|
|
3062
855
|
title: "No Follow",
|
|
3063
856
|
type: "boolean",
|
|
@@ -3183,14 +976,14 @@ var resolveDashboardConfig = (healthDashboard) => {
|
|
|
3183
976
|
deprecationWarnings
|
|
3184
977
|
};
|
|
3185
978
|
};
|
|
3186
|
-
var seofields =
|
|
979
|
+
var seofields = sanity.definePlugin((config = {}) => {
|
|
3187
980
|
const { healthDashboard = true } = config;
|
|
3188
981
|
const dash = resolveDashboardConfig(healthDashboard);
|
|
3189
|
-
const LazySeoHealthTool =
|
|
3190
|
-
const BoundSeoHealthTool = () =>
|
|
3191
|
-
|
|
982
|
+
const LazySeoHealthTool = React12__default.default.lazy(() => import('./SeoHealthTool-4P6JST5S.cjs'));
|
|
983
|
+
const BoundSeoHealthTool = () => React12__default.default.createElement(
|
|
984
|
+
React12__default.default.Suspense,
|
|
3192
985
|
{ fallback: null },
|
|
3193
|
-
|
|
986
|
+
React12__default.default.createElement(LazySeoHealthTool, {
|
|
3194
987
|
icon: dash.icon,
|
|
3195
988
|
title: dash.title,
|
|
3196
989
|
description: dash.description,
|
|
@@ -3213,7 +1006,7 @@ var seofields = (0, import_sanity20.definePlugin)((config = {}) => {
|
|
|
3213
1006
|
_deprecationWarnings: dash.deprecationWarnings
|
|
3214
1007
|
})
|
|
3215
1008
|
);
|
|
3216
|
-
return __spreadValues({
|
|
1009
|
+
return chunkS367Y35J_cjs.__spreadValues({
|
|
3217
1010
|
name: "sanity-plugin-seofields",
|
|
3218
1011
|
schema: {
|
|
3219
1012
|
types: types(config)
|
|
@@ -3230,17 +1023,13 @@ var seofields = (0, import_sanity20.definePlugin)((config = {}) => {
|
|
|
3230
1023
|
});
|
|
3231
1024
|
});
|
|
3232
1025
|
var plugin_default = seofields;
|
|
3233
|
-
|
|
3234
|
-
// src/components/SeoHealthPane.tsx
|
|
3235
|
-
var import_react15 = __toESM(require("react"), 1);
|
|
3236
|
-
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3237
|
-
var LazySeoHealthDashboard = import_react15.default.lazy(() => Promise.resolve().then(() => (init_SeoHealthDashboard(), SeoHealthDashboard_exports)));
|
|
1026
|
+
var LazySeoHealthDashboard = React12__default.default.lazy(() => import('./SeoHealthDashboard-3VBITMWT.cjs'));
|
|
3238
1027
|
function createSeoHealthPane(optionsOrS, optionsWhenS) {
|
|
3239
1028
|
const S = optionsOrS;
|
|
3240
|
-
const _a = optionsWhenS != null ? optionsWhenS : {}, { query, openInPane = true, title: paneTitle } = _a, rest = __objRest(_a, ["query", "openInPane", "title"]);
|
|
3241
|
-
const SeoHealthPane = () => /* @__PURE__ */
|
|
1029
|
+
const _a = optionsWhenS != null ? optionsWhenS : {}, { query, openInPane = true, title: paneTitle } = _a, rest = chunkS367Y35J_cjs.__objRest(_a, ["query", "openInPane", "title"]);
|
|
1030
|
+
const SeoHealthPane = () => /* @__PURE__ */ jsxRuntime.jsx(React12__default.default.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3242
1031
|
LazySeoHealthDashboard,
|
|
3243
|
-
__spreadValues({
|
|
1032
|
+
chunkS367Y35J_cjs.__spreadValues({
|
|
3244
1033
|
customQuery: query,
|
|
3245
1034
|
openInPane,
|
|
3246
1035
|
title: paneTitle
|
|
@@ -3255,15 +1044,15 @@ function createSeoHealthPane(optionsOrS, optionsWhenS) {
|
|
|
3255
1044
|
|
|
3256
1045
|
// src/index.ts
|
|
3257
1046
|
var src_default = plugin_default;
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
1047
|
+
|
|
1048
|
+
exports.allSchemas = types;
|
|
1049
|
+
exports.createSeoHealthPane = createSeoHealthPane;
|
|
1050
|
+
exports.default = src_default;
|
|
1051
|
+
exports.metaAttributeSchema = metaAttribute_default;
|
|
1052
|
+
exports.metaTagSchema = metaTag_default;
|
|
1053
|
+
exports.openGraphSchema = openGraph;
|
|
1054
|
+
exports.robotsSchema = robots_default;
|
|
1055
|
+
exports.seoFieldsSchema = seoFieldsSchema;
|
|
1056
|
+
exports.twitterSchema = twitter;
|
|
1057
|
+
//# sourceMappingURL=index.cjs.map
|
|
3269
1058
|
//# sourceMappingURL=index.cjs.map
|