@consilioweb/payload-seo-analyzer 1.8.1 → 1.10.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 +75 -1
- package/dist/client.cjs +887 -91
- package/dist/client.js +887 -91
- package/dist/index.cjs +1445 -347
- package/dist/index.d.cts +125 -3
- package/dist/index.d.ts +125 -3
- package/dist/index.js +1440 -348
- package/package.json +1 -1
package/dist/client.cjs
CHANGED
|
@@ -1058,6 +1058,8 @@ var fr = {
|
|
|
1058
1058
|
},
|
|
1059
1059
|
seoView: {
|
|
1060
1060
|
loadingAudit: "Chargement de l'audit SEO...",
|
|
1061
|
+
buildingAudit: "G\xE9n\xE9ration de l'audit SEO en cours\u2026 (calcul\xE9 en arri\xE8re-plan pour ne pas surcharger le serveur, cela peut prendre un moment sur un gros site)",
|
|
1062
|
+
buildTimeout: "La g\xE9n\xE9ration de l'audit prend plus de temps que pr\xE9vu. R\xE9essayez dans quelques instants.",
|
|
1061
1063
|
errorSaving: "Erreur lors de la sauvegarde",
|
|
1062
1064
|
auditTitle: "Audit SEO",
|
|
1063
1065
|
pagesAnalyzed: "pages analys\xE9es",
|
|
@@ -1500,7 +1502,19 @@ var fr = {
|
|
|
1500
1502
|
generateMeta: "G\xE9n\xE9rer les meta",
|
|
1501
1503
|
metaTitle: "Meta Title",
|
|
1502
1504
|
metaDescription: "Meta Description",
|
|
1503
|
-
emptyValue: "(vide)"
|
|
1505
|
+
emptyValue: "(vide)",
|
|
1506
|
+
optimizeWithAi: "Optimiser avec l'IA",
|
|
1507
|
+
optimizeIntro: "L'IA analyse la page et propose des meta optimis\xE9es (titre, description, mot-cl\xE9). V\xE9rifiez puis appliquez.",
|
|
1508
|
+
optimizeRunning: "Analyse en cours\u2026",
|
|
1509
|
+
applyAll: "Appliquer",
|
|
1510
|
+
applied: "Appliqu\xE9",
|
|
1511
|
+
whyChanges: "Pourquoi ces changements",
|
|
1512
|
+
labelCurrent: "Actuel",
|
|
1513
|
+
labelSuggested: "Sugg\xE9r\xE9",
|
|
1514
|
+
labelFocusKeyword: "Mot-cl\xE9 cible",
|
|
1515
|
+
heuristicNote: "Suggestions heuristiques (cl\xE9 API Claude non configur\xE9e).",
|
|
1516
|
+
applySaveHint: "Champs remplis \u2014 pensez \xE0 enregistrer le document.",
|
|
1517
|
+
noMetaChange: "Aucun changement propos\xE9."
|
|
1504
1518
|
},
|
|
1505
1519
|
scoreHistory: {
|
|
1506
1520
|
loading: "Chargement de l'historique...",
|
|
@@ -1636,6 +1650,8 @@ var en = {
|
|
|
1636
1650
|
},
|
|
1637
1651
|
seoView: {
|
|
1638
1652
|
loadingAudit: "Loading SEO audit...",
|
|
1653
|
+
buildingAudit: "Building the SEO audit\u2026 (computed in the background to avoid overloading the server \u2014 this can take a moment on a large site)",
|
|
1654
|
+
buildTimeout: "The audit is taking longer than expected. Please try again in a moment.",
|
|
1639
1655
|
errorSaving: "Error during save",
|
|
1640
1656
|
auditTitle: "SEO Audit",
|
|
1641
1657
|
pagesAnalyzed: "pages analyzed",
|
|
@@ -2078,7 +2094,19 @@ var en = {
|
|
|
2078
2094
|
generateMeta: "Generate meta",
|
|
2079
2095
|
metaTitle: "Meta Title",
|
|
2080
2096
|
metaDescription: "Meta Description",
|
|
2081
|
-
emptyValue: "(empty)"
|
|
2097
|
+
emptyValue: "(empty)",
|
|
2098
|
+
optimizeWithAi: "Optimize with AI",
|
|
2099
|
+
optimizeIntro: "AI analyzes the page and proposes optimized meta tags (title, description, keyword). Review, then apply.",
|
|
2100
|
+
optimizeRunning: "Analyzing\u2026",
|
|
2101
|
+
applyAll: "Apply",
|
|
2102
|
+
applied: "Applied",
|
|
2103
|
+
whyChanges: "Why these changes",
|
|
2104
|
+
labelCurrent: "Current",
|
|
2105
|
+
labelSuggested: "Suggested",
|
|
2106
|
+
labelFocusKeyword: "Focus keyword",
|
|
2107
|
+
heuristicNote: "Heuristic suggestions (Claude API key not configured).",
|
|
2108
|
+
applySaveHint: "Fields filled \u2014 remember to save the document.",
|
|
2109
|
+
noMetaChange: "No changes proposed."
|
|
2082
2110
|
},
|
|
2083
2111
|
scoreHistory: {
|
|
2084
2112
|
loading: "Loading history...",
|
|
@@ -6484,9 +6512,11 @@ var C2 = {
|
|
|
6484
6512
|
white: "#fff",
|
|
6485
6513
|
green: "#22c55e",
|
|
6486
6514
|
red: "#ef4444",
|
|
6515
|
+
bg: "#fafafa",
|
|
6487
6516
|
textPrimary: "var(--theme-text, #1a1a1a)",
|
|
6488
6517
|
textSecondary: "var(--theme-elevation-600, #6b7280)",
|
|
6489
6518
|
border: "var(--theme-border-color, #000)",
|
|
6519
|
+
inputBg: "var(--theme-input-bg, #fff)",
|
|
6490
6520
|
surfaceBg: "var(--theme-elevation-0, #fff)",
|
|
6491
6521
|
surface50: "var(--theme-elevation-50, #f9fafb)"
|
|
6492
6522
|
};
|
|
@@ -6986,10 +7016,48 @@ function useInternalLinkSuggestions(documentId, collection, textContent) {
|
|
|
6986
7016
|
}, [textContent, documentId, collection]);
|
|
6987
7017
|
return { suggestions, loading };
|
|
6988
7018
|
}
|
|
7019
|
+
function AiDiffRow({
|
|
7020
|
+
label,
|
|
7021
|
+
current,
|
|
7022
|
+
suggested,
|
|
7023
|
+
labelCurrent,
|
|
7024
|
+
labelSuggested,
|
|
7025
|
+
emptyValue,
|
|
7026
|
+
C: colors
|
|
7027
|
+
}) {
|
|
7028
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 10 }, children: [
|
|
7029
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 10, fontWeight: 700, color: colors.textSecondary, textTransform: "uppercase", marginBottom: 4 }, children: label }),
|
|
7030
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 11, color: colors.textSecondary, marginBottom: 3 }, children: [
|
|
7031
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontWeight: 700 }, children: [
|
|
7032
|
+
labelCurrent,
|
|
7033
|
+
": "
|
|
7034
|
+
] }),
|
|
7035
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { textDecoration: current ? "line-through" : "none", opacity: 0.7 }, children: current || emptyValue })
|
|
7036
|
+
] }),
|
|
7037
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7038
|
+
"div",
|
|
7039
|
+
{
|
|
7040
|
+
style: {
|
|
7041
|
+
padding: "6px 10px",
|
|
7042
|
+
borderRadius: 6,
|
|
7043
|
+
border: `1px solid var(--theme-elevation-200, #e5e7eb)`,
|
|
7044
|
+
backgroundColor: colors.surface50,
|
|
7045
|
+
fontSize: 12,
|
|
7046
|
+
color: colors.textPrimary,
|
|
7047
|
+
lineHeight: 1.5
|
|
7048
|
+
},
|
|
7049
|
+
children: [
|
|
7050
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 10, fontWeight: 700, color: colors.green, textTransform: "uppercase", marginRight: 6 }, children: labelSuggested }),
|
|
7051
|
+
suggested || emptyValue
|
|
7052
|
+
]
|
|
7053
|
+
}
|
|
7054
|
+
)
|
|
7055
|
+
] });
|
|
7056
|
+
}
|
|
6989
7057
|
var SeoAnalyzer = () => {
|
|
6990
7058
|
const locale = useSeoLocale();
|
|
6991
7059
|
const t = getDashboardT(locale);
|
|
6992
|
-
const [formFields] = ui.useAllFormFields();
|
|
7060
|
+
const [formFields, dispatchFields] = ui.useAllFormFields();
|
|
6993
7061
|
const initialScoreRef = React4.useRef(null);
|
|
6994
7062
|
const [suggestionsOpen, setSuggestionsOpen] = React4.useState(true);
|
|
6995
7063
|
const [cannibalizationExpanded, setCannibalizationExpanded] = React4.useState(false);
|
|
@@ -6998,6 +7066,10 @@ var SeoAnalyzer = () => {
|
|
|
6998
7066
|
const [aiGenerating, setAiGenerating] = React4.useState(false);
|
|
6999
7067
|
const [aiResult, setAiResult] = React4.useState(null);
|
|
7000
7068
|
const [aiCopied, setAiCopied] = React4.useState(null);
|
|
7069
|
+
const [aiOptimizing, setAiOptimizing] = React4.useState(false);
|
|
7070
|
+
const [aiOptimizeResult, setAiOptimizeResult] = React4.useState(null);
|
|
7071
|
+
const [aiOptimizeApplied, setAiOptimizeApplied] = React4.useState(false);
|
|
7072
|
+
const [aiOptimizeError, setAiOptimizeError] = React4.useState(false);
|
|
7001
7073
|
const getFieldValue = React4.useCallback(
|
|
7002
7074
|
(path) => {
|
|
7003
7075
|
if (!formFields) return void 0;
|
|
@@ -7725,6 +7797,145 @@ var SeoAnalyzer = () => {
|
|
|
7725
7797
|
}
|
|
7726
7798
|
)
|
|
7727
7799
|
] }),
|
|
7800
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 12 }, children: [
|
|
7801
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7802
|
+
"button",
|
|
7803
|
+
{
|
|
7804
|
+
type: "button",
|
|
7805
|
+
disabled: aiOptimizing || !documentId,
|
|
7806
|
+
title: !documentId ? t.seoAnalyzer.applySaveHint : void 0,
|
|
7807
|
+
onClick: async () => {
|
|
7808
|
+
setAiOptimizing(true);
|
|
7809
|
+
setAiOptimizeResult(null);
|
|
7810
|
+
setAiOptimizeApplied(false);
|
|
7811
|
+
setAiOptimizeError(false);
|
|
7812
|
+
try {
|
|
7813
|
+
const res = await fetch("/api/seo-plugin/ai-optimize", {
|
|
7814
|
+
method: "POST",
|
|
7815
|
+
credentials: "include",
|
|
7816
|
+
headers: { "Content-Type": "application/json" },
|
|
7817
|
+
body: JSON.stringify({ collection: currentCollection, id: documentId })
|
|
7818
|
+
});
|
|
7819
|
+
if (res.ok) {
|
|
7820
|
+
setAiOptimizeResult(await res.json());
|
|
7821
|
+
} else {
|
|
7822
|
+
setAiOptimizeError(true);
|
|
7823
|
+
}
|
|
7824
|
+
} catch {
|
|
7825
|
+
setAiOptimizeError(true);
|
|
7826
|
+
}
|
|
7827
|
+
setAiOptimizing(false);
|
|
7828
|
+
},
|
|
7829
|
+
style: {
|
|
7830
|
+
display: "flex",
|
|
7831
|
+
alignItems: "center",
|
|
7832
|
+
gap: 6,
|
|
7833
|
+
width: "100%",
|
|
7834
|
+
padding: "10px 14px",
|
|
7835
|
+
borderRadius: 8,
|
|
7836
|
+
border: `2px solid ${C2.border}`,
|
|
7837
|
+
backgroundColor: "#7c3aed",
|
|
7838
|
+
color: "#fff",
|
|
7839
|
+
fontWeight: 800,
|
|
7840
|
+
fontSize: 12,
|
|
7841
|
+
cursor: aiOptimizing || !documentId ? "not-allowed" : "pointer",
|
|
7842
|
+
opacity: aiOptimizing || !documentId ? 0.6 : 1,
|
|
7843
|
+
textTransform: "uppercase",
|
|
7844
|
+
letterSpacing: "0.04em",
|
|
7845
|
+
justifyContent: "center",
|
|
7846
|
+
boxShadow: "2px 2px 0 0 var(--theme-border-color, rgba(0,0,0,1))"
|
|
7847
|
+
},
|
|
7848
|
+
children: aiOptimizing ? t.seoAnalyzer.optimizeRunning : `\u2728 ${t.seoAnalyzer.optimizeWithAi}`
|
|
7849
|
+
}
|
|
7850
|
+
),
|
|
7851
|
+
aiOptimizeError && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 8, padding: "8px 12px", borderRadius: 6, fontSize: 11, color: C2.white, backgroundColor: C2.red }, children: t.common.loadingError }),
|
|
7852
|
+
aiOptimizeResult && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7853
|
+
"div",
|
|
7854
|
+
{
|
|
7855
|
+
style: {
|
|
7856
|
+
marginTop: 8,
|
|
7857
|
+
padding: "12px 14px",
|
|
7858
|
+
borderRadius: 8,
|
|
7859
|
+
border: `2px solid ${C2.border}`,
|
|
7860
|
+
backgroundColor: C2.surfaceBg
|
|
7861
|
+
},
|
|
7862
|
+
children: [
|
|
7863
|
+
aiOptimizeResult.method === "heuristic" && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 10, color: C2.textSecondary, marginBottom: 8, fontStyle: "italic" }, children: t.seoAnalyzer.heuristicNote }),
|
|
7864
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7865
|
+
AiDiffRow,
|
|
7866
|
+
{
|
|
7867
|
+
label: t.seoAnalyzer.metaTitle,
|
|
7868
|
+
current: aiOptimizeResult.current.metaTitle,
|
|
7869
|
+
suggested: aiOptimizeResult.suggestions.metaTitle,
|
|
7870
|
+
labelCurrent: t.seoAnalyzer.labelCurrent,
|
|
7871
|
+
labelSuggested: t.seoAnalyzer.labelSuggested,
|
|
7872
|
+
emptyValue: t.seoAnalyzer.emptyValue,
|
|
7873
|
+
C: C2
|
|
7874
|
+
}
|
|
7875
|
+
),
|
|
7876
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7877
|
+
AiDiffRow,
|
|
7878
|
+
{
|
|
7879
|
+
label: t.seoAnalyzer.metaDescription,
|
|
7880
|
+
current: aiOptimizeResult.current.metaDescription,
|
|
7881
|
+
suggested: aiOptimizeResult.suggestions.metaDescription,
|
|
7882
|
+
labelCurrent: t.seoAnalyzer.labelCurrent,
|
|
7883
|
+
labelSuggested: t.seoAnalyzer.labelSuggested,
|
|
7884
|
+
emptyValue: t.seoAnalyzer.emptyValue,
|
|
7885
|
+
C: C2
|
|
7886
|
+
}
|
|
7887
|
+
),
|
|
7888
|
+
aiOptimizeResult.suggestions.focusKeyword && aiOptimizeResult.suggestions.focusKeyword !== aiOptimizeResult.current.focusKeyword && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7889
|
+
AiDiffRow,
|
|
7890
|
+
{
|
|
7891
|
+
label: t.seoAnalyzer.labelFocusKeyword,
|
|
7892
|
+
current: aiOptimizeResult.current.focusKeyword,
|
|
7893
|
+
suggested: aiOptimizeResult.suggestions.focusKeyword,
|
|
7894
|
+
labelCurrent: t.seoAnalyzer.labelCurrent,
|
|
7895
|
+
labelSuggested: t.seoAnalyzer.labelSuggested,
|
|
7896
|
+
emptyValue: t.seoAnalyzer.emptyValue,
|
|
7897
|
+
C: C2
|
|
7898
|
+
}
|
|
7899
|
+
),
|
|
7900
|
+
aiOptimizeResult.suggestions.rationale.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 4, marginBottom: 10 }, children: [
|
|
7901
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 10, fontWeight: 700, color: C2.textSecondary, textTransform: "uppercase", marginBottom: 4 }, children: t.seoAnalyzer.whyChanges }),
|
|
7902
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: 0, paddingLeft: 16, fontSize: 11, color: C2.textPrimary, lineHeight: 1.5 }, children: aiOptimizeResult.suggestions.rationale.map((r, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: r }, i)) })
|
|
7903
|
+
] }),
|
|
7904
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7905
|
+
"button",
|
|
7906
|
+
{
|
|
7907
|
+
type: "button",
|
|
7908
|
+
disabled: aiOptimizeApplied,
|
|
7909
|
+
onClick: () => {
|
|
7910
|
+
const sug = aiOptimizeResult.suggestions;
|
|
7911
|
+
if (sug.metaTitle) dispatchFields({ type: "UPDATE", path: "meta.title", value: sug.metaTitle });
|
|
7912
|
+
if (sug.metaDescription) dispatchFields({ type: "UPDATE", path: "meta.description", value: sug.metaDescription });
|
|
7913
|
+
if (sug.focusKeyword && sug.focusKeyword !== aiOptimizeResult.current.focusKeyword) {
|
|
7914
|
+
dispatchFields({ type: "UPDATE", path: "focusKeyword", value: sug.focusKeyword });
|
|
7915
|
+
}
|
|
7916
|
+
setAiOptimizeApplied(true);
|
|
7917
|
+
},
|
|
7918
|
+
style: {
|
|
7919
|
+
width: "100%",
|
|
7920
|
+
padding: "9px 14px",
|
|
7921
|
+
borderRadius: 6,
|
|
7922
|
+
border: `2px solid ${C2.border}`,
|
|
7923
|
+
backgroundColor: aiOptimizeApplied ? C2.green : C2.cyan,
|
|
7924
|
+
color: aiOptimizeApplied ? C2.white : C2.black,
|
|
7925
|
+
fontWeight: 800,
|
|
7926
|
+
fontSize: 11,
|
|
7927
|
+
textTransform: "uppercase",
|
|
7928
|
+
letterSpacing: "0.04em",
|
|
7929
|
+
cursor: aiOptimizeApplied ? "default" : "pointer"
|
|
7930
|
+
},
|
|
7931
|
+
children: aiOptimizeApplied ? `\u2713 ${t.seoAnalyzer.applied}` : t.seoAnalyzer.applyAll
|
|
7932
|
+
}
|
|
7933
|
+
),
|
|
7934
|
+
aiOptimizeApplied && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 6, fontSize: 10, color: C2.textSecondary, textAlign: "center" }, children: t.seoAnalyzer.applySaveHint })
|
|
7935
|
+
]
|
|
7936
|
+
}
|
|
7937
|
+
)
|
|
7938
|
+
] }),
|
|
7728
7939
|
suggestions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7729
7940
|
"div",
|
|
7730
7941
|
{
|
|
@@ -9064,6 +9275,7 @@ function SeoView() {
|
|
|
9064
9275
|
const [items, setItems] = React4.useState([]);
|
|
9065
9276
|
const [stats, setStats] = React4.useState(null);
|
|
9066
9277
|
const [loading, setLoading] = React4.useState(true);
|
|
9278
|
+
const [building, setBuilding] = React4.useState(false);
|
|
9067
9279
|
const [error, setError] = React4.useState(null);
|
|
9068
9280
|
const [filter, setFilter] = React4.useState("all");
|
|
9069
9281
|
const [scoreFilter, setScoreFilter] = React4.useState("all");
|
|
@@ -9080,9 +9292,22 @@ function SeoView() {
|
|
|
9080
9292
|
const fetchAudit = React4.useCallback(async (forceRefresh = false) => {
|
|
9081
9293
|
setLoading(true);
|
|
9082
9294
|
setError(null);
|
|
9295
|
+
setBuilding(false);
|
|
9083
9296
|
try {
|
|
9084
|
-
const
|
|
9085
|
-
|
|
9297
|
+
const base = "/api/seo-plugin/audit";
|
|
9298
|
+
let res = await fetch(forceRefresh ? `${base}?nocache=1` : base, {
|
|
9299
|
+
credentials: "include",
|
|
9300
|
+
cache: "no-store"
|
|
9301
|
+
});
|
|
9302
|
+
let attempts = 0;
|
|
9303
|
+
const MAX_POLLS = 90;
|
|
9304
|
+
while (res.status === 202 && attempts < MAX_POLLS) {
|
|
9305
|
+
setBuilding(true);
|
|
9306
|
+
await new Promise((r) => setTimeout(r, 3e3));
|
|
9307
|
+
res = await fetch(base, { credentials: "include", cache: "no-store" });
|
|
9308
|
+
attempts++;
|
|
9309
|
+
}
|
|
9310
|
+
if (res.status === 202) throw new Error(t.seoView.buildTimeout);
|
|
9086
9311
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
9087
9312
|
const data = await res.json();
|
|
9088
9313
|
setItems(data.results || []);
|
|
@@ -9090,6 +9315,7 @@ function SeoView() {
|
|
|
9090
9315
|
} catch (e) {
|
|
9091
9316
|
setError(e instanceof Error ? e.message : t.common.loadingError);
|
|
9092
9317
|
}
|
|
9318
|
+
setBuilding(false);
|
|
9093
9319
|
setLoading(false);
|
|
9094
9320
|
}, [t]);
|
|
9095
9321
|
React4.useEffect(() => {
|
|
@@ -9531,7 +9757,7 @@ function SeoView() {
|
|
|
9531
9757
|
fontSize: 14,
|
|
9532
9758
|
fontFamily: "var(--font-body, system-ui)"
|
|
9533
9759
|
},
|
|
9534
|
-
children: t.seoView.loadingAudit
|
|
9760
|
+
children: building ? t.seoView.buildingAudit : t.seoView.loadingAudit
|
|
9535
9761
|
}
|
|
9536
9762
|
);
|
|
9537
9763
|
}
|
|
@@ -15684,7 +15910,7 @@ function getSchemaTypes(t) {
|
|
|
15684
15910
|
}
|
|
15685
15911
|
};
|
|
15686
15912
|
}
|
|
15687
|
-
function
|
|
15913
|
+
function buildJsonLd2(type, values) {
|
|
15688
15914
|
switch (type) {
|
|
15689
15915
|
case "LocalBusiness": {
|
|
15690
15916
|
const result = {
|
|
@@ -15965,7 +16191,7 @@ function SchemaBuilderView() {
|
|
|
15965
16191
|
[arrayName]: (prev[arrayName] || []).filter((_, i) => i !== index)
|
|
15966
16192
|
}));
|
|
15967
16193
|
}, []);
|
|
15968
|
-
const jsonLd = React4.useMemo(() =>
|
|
16194
|
+
const jsonLd = React4.useMemo(() => buildJsonLd2(selectedType, values), [selectedType, values]);
|
|
15969
16195
|
const jsonString = React4.useMemo(() => JSON.stringify(jsonLd, null, 2), [jsonLd]);
|
|
15970
16196
|
const scriptTag = React4.useMemo(
|
|
15971
16197
|
() => `<script type="application/ld+json">
|
|
@@ -16742,6 +16968,573 @@ function GscPanel({ locale }) {
|
|
|
16742
16968
|
] })
|
|
16743
16969
|
] });
|
|
16744
16970
|
}
|
|
16971
|
+
var C6 = {
|
|
16972
|
+
text: "var(--theme-text, #1a1a1a)",
|
|
16973
|
+
sub: "var(--theme-elevation-600, #6b7280)",
|
|
16974
|
+
card: "var(--theme-elevation-50, #f9fafb)",
|
|
16975
|
+
border: "var(--theme-elevation-200, #e5e7eb)",
|
|
16976
|
+
green: "#22c55e",
|
|
16977
|
+
red: "#ef4444",
|
|
16978
|
+
blue: "#3b82f6"
|
|
16979
|
+
};
|
|
16980
|
+
var S3 = {
|
|
16981
|
+
fr: {
|
|
16982
|
+
title: "Suivi de positions (rank tracking)",
|
|
16983
|
+
subtitle: "Historique quotidien des positions Google (via Search Console) et mouvements dans le temps.",
|
|
16984
|
+
needGsc: "Connectez Google Search Console ci-dessus pour activer le suivi de positions.",
|
|
16985
|
+
snapshot: "Relever maintenant",
|
|
16986
|
+
snapshotting: "Relev\xE9 en cours\u2026",
|
|
16987
|
+
noData: "Pas encore de donn\xE9es. Le relev\xE9 tourne automatiquement chaque jour ; cliquez \xAB Relever maintenant \xBB pour d\xE9marrer.",
|
|
16988
|
+
lastSnapshot: "Dernier relev\xE9",
|
|
16989
|
+
query: "Requ\xEAte",
|
|
16990
|
+
position: "Position",
|
|
16991
|
+
change: "\xC9volution",
|
|
16992
|
+
clicks: "Clics",
|
|
16993
|
+
impressions: "Impr.",
|
|
16994
|
+
stable: "stable",
|
|
16995
|
+
newQ: "nouveau",
|
|
16996
|
+
countLabel: "requ\xEAtes suivies"
|
|
16997
|
+
},
|
|
16998
|
+
en: {
|
|
16999
|
+
title: "Rank tracking",
|
|
17000
|
+
subtitle: "Daily Google position history (via Search Console) and movement over time.",
|
|
17001
|
+
needGsc: "Connect Google Search Console above to enable rank tracking.",
|
|
17002
|
+
snapshot: "Snapshot now",
|
|
17003
|
+
snapshotting: "Snapshotting\u2026",
|
|
17004
|
+
noData: 'No data yet. The snapshot runs automatically every day; click "Snapshot now" to start.',
|
|
17005
|
+
lastSnapshot: "Last snapshot",
|
|
17006
|
+
query: "Query",
|
|
17007
|
+
position: "Position",
|
|
17008
|
+
change: "Change",
|
|
17009
|
+
clicks: "Clicks",
|
|
17010
|
+
impressions: "Impr.",
|
|
17011
|
+
stable: "stable",
|
|
17012
|
+
newQ: "new",
|
|
17013
|
+
countLabel: "tracked queries"
|
|
17014
|
+
}
|
|
17015
|
+
};
|
|
17016
|
+
function RankTrackingPanel({ locale }) {
|
|
17017
|
+
const s = S3[locale] ?? S3.fr;
|
|
17018
|
+
const [movers, setMovers] = React4.useState(null);
|
|
17019
|
+
const [lastSnapshot, setLastSnapshot] = React4.useState(null);
|
|
17020
|
+
const [loading, setLoading] = React4.useState(true);
|
|
17021
|
+
const [busy, setBusy] = React4.useState(false);
|
|
17022
|
+
const [error, setError] = React4.useState(null);
|
|
17023
|
+
const [notConnected, setNotConnected] = React4.useState(false);
|
|
17024
|
+
const load = React4.useCallback(async () => {
|
|
17025
|
+
setLoading(true);
|
|
17026
|
+
setError(null);
|
|
17027
|
+
try {
|
|
17028
|
+
const res = await fetch("/api/seo-plugin/rank-history", { credentials: "include", cache: "no-store" });
|
|
17029
|
+
if (res.status === 403 || res.status === 409) {
|
|
17030
|
+
setNotConnected(true);
|
|
17031
|
+
setMovers(null);
|
|
17032
|
+
return;
|
|
17033
|
+
}
|
|
17034
|
+
const json = await res.json();
|
|
17035
|
+
if (!res.ok) {
|
|
17036
|
+
setError(json.error || `Error ${res.status}`);
|
|
17037
|
+
return;
|
|
17038
|
+
}
|
|
17039
|
+
setMovers(json.movers || []);
|
|
17040
|
+
setLastSnapshot(json.lastSnapshot || null);
|
|
17041
|
+
} catch (e) {
|
|
17042
|
+
setError(e instanceof Error ? e.message : "Network error");
|
|
17043
|
+
} finally {
|
|
17044
|
+
setLoading(false);
|
|
17045
|
+
}
|
|
17046
|
+
}, []);
|
|
17047
|
+
React4.useEffect(() => {
|
|
17048
|
+
void load();
|
|
17049
|
+
}, [load]);
|
|
17050
|
+
const snapshotNow = async () => {
|
|
17051
|
+
setBusy(true);
|
|
17052
|
+
setError(null);
|
|
17053
|
+
try {
|
|
17054
|
+
const res = await fetch("/api/seo-plugin/rank-snapshot", { method: "POST", credentials: "include" });
|
|
17055
|
+
const json = await res.json();
|
|
17056
|
+
if (res.status === 409) {
|
|
17057
|
+
setNotConnected(true);
|
|
17058
|
+
return;
|
|
17059
|
+
}
|
|
17060
|
+
if (!res.ok) {
|
|
17061
|
+
setError(json.error || json.reason || `Error ${res.status}`);
|
|
17062
|
+
return;
|
|
17063
|
+
}
|
|
17064
|
+
await load();
|
|
17065
|
+
} catch (e) {
|
|
17066
|
+
setError(e instanceof Error ? e.message : "Network error");
|
|
17067
|
+
} finally {
|
|
17068
|
+
setBusy(false);
|
|
17069
|
+
}
|
|
17070
|
+
};
|
|
17071
|
+
const card = {
|
|
17072
|
+
padding: 16,
|
|
17073
|
+
borderRadius: 12,
|
|
17074
|
+
border: `1px solid ${C6.border}`,
|
|
17075
|
+
backgroundColor: C6.card,
|
|
17076
|
+
marginBottom: 20
|
|
17077
|
+
};
|
|
17078
|
+
const btn = {
|
|
17079
|
+
padding: "8px 12px",
|
|
17080
|
+
borderRadius: 8,
|
|
17081
|
+
border: `1px solid ${C6.blue}`,
|
|
17082
|
+
backgroundColor: C6.blue,
|
|
17083
|
+
color: "#fff",
|
|
17084
|
+
fontSize: 12,
|
|
17085
|
+
fontWeight: 700,
|
|
17086
|
+
cursor: busy ? "wait" : "pointer",
|
|
17087
|
+
opacity: busy ? 0.6 : 1
|
|
17088
|
+
};
|
|
17089
|
+
const renderDelta = (m) => {
|
|
17090
|
+
if (m.previousPosition === null) {
|
|
17091
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C6.sub, fontSize: 11 }, children: s.newQ });
|
|
17092
|
+
}
|
|
17093
|
+
if (Math.abs(m.delta) < 0.1) {
|
|
17094
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: C6.sub, fontSize: 11 }, children: [
|
|
17095
|
+
"\u2014 ",
|
|
17096
|
+
s.stable
|
|
17097
|
+
] });
|
|
17098
|
+
}
|
|
17099
|
+
const up = m.delta > 0;
|
|
17100
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: up ? C6.green : C6.red, fontWeight: 700, fontSize: 12 }, children: [
|
|
17101
|
+
up ? "\u25B2" : "\u25BC",
|
|
17102
|
+
" ",
|
|
17103
|
+
Math.abs(m.delta).toFixed(1)
|
|
17104
|
+
] });
|
|
17105
|
+
};
|
|
17106
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: card, children: [
|
|
17107
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flexWrap: "wrap" }, children: [
|
|
17108
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
17109
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 800, color: C6.text }, children: s.title }),
|
|
17110
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: C6.sub, marginTop: 2 }, children: s.subtitle })
|
|
17111
|
+
] }),
|
|
17112
|
+
!notConnected && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: snapshotNow, disabled: busy, style: btn, children: busy ? s.snapshotting : s.snapshot })
|
|
17113
|
+
] }),
|
|
17114
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: C6.red, fontSize: 13, fontWeight: 600, marginTop: 10 }, children: error }),
|
|
17115
|
+
notConnected && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12, fontSize: 13, color: C6.sub }, children: s.needGsc }),
|
|
17116
|
+
!notConnected && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 12 }, children: [
|
|
17117
|
+
lastSnapshot && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 11, color: C6.sub, marginBottom: 8 }, children: [
|
|
17118
|
+
s.lastSnapshot,
|
|
17119
|
+
": ",
|
|
17120
|
+
new Date(lastSnapshot).toLocaleString(locale),
|
|
17121
|
+
movers ? ` \xB7 ${movers.length} ${s.countLabel}` : ""
|
|
17122
|
+
] }),
|
|
17123
|
+
loading && !movers && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 13, color: C6.sub }, children: "\u2026" }),
|
|
17124
|
+
movers && movers.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 13, color: C6.sub }, children: s.noData }),
|
|
17125
|
+
movers && movers.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsxs("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: 12 }, children: [
|
|
17126
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { style: { textAlign: "left", color: C6.sub }, children: [
|
|
17127
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { style: { padding: "6px 8px" }, children: s.query }),
|
|
17128
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.position }),
|
|
17129
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.change }),
|
|
17130
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.clicks }),
|
|
17131
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { style: { padding: "6px 8px", textAlign: "right" }, children: s.impressions })
|
|
17132
|
+
] }) }),
|
|
17133
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: movers.slice(0, 100).map((m, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { style: { borderTop: `1px solid ${C6.border}`, color: C6.text }, children: [
|
|
17134
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "6px 8px", maxWidth: 320, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: m.query }),
|
|
17135
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "6px 8px", textAlign: "right", fontWeight: 700 }, children: m.position.toFixed(1) }),
|
|
17136
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "6px 8px", textAlign: "right" }, children: renderDelta(m) }),
|
|
17137
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "6px 8px", textAlign: "right" }, children: m.clicks }),
|
|
17138
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "6px 8px", textAlign: "right" }, children: m.impressions })
|
|
17139
|
+
] }, i)) })
|
|
17140
|
+
] }) })
|
|
17141
|
+
] })
|
|
17142
|
+
] });
|
|
17143
|
+
}
|
|
17144
|
+
var C7 = {
|
|
17145
|
+
text: "var(--theme-text, #1a1a1a)",
|
|
17146
|
+
sub: "var(--theme-elevation-600, #6b7280)",
|
|
17147
|
+
card: "var(--theme-elevation-50, #f9fafb)",
|
|
17148
|
+
border: "var(--theme-elevation-200, #e5e7eb)",
|
|
17149
|
+
green: "#22c55e",
|
|
17150
|
+
red: "#ef4444",
|
|
17151
|
+
amber: "#f59e0b",
|
|
17152
|
+
blue: "#3b82f6"
|
|
17153
|
+
};
|
|
17154
|
+
var S4 = {
|
|
17155
|
+
fr: {
|
|
17156
|
+
title: "Monitoring & alertes",
|
|
17157
|
+
subtitle: "Digest p\xE9riodique : r\xE9gressions de score, nouveaux 404, chutes de position (webhook / email).",
|
|
17158
|
+
notConfigured: "Aucun canal configur\xE9. D\xE9finissez SEO_ALERT_WEBHOOK_URL et/ou SEO_ALERT_EMAIL c\xF4t\xE9 serveur, puis activez features.alerts.",
|
|
17159
|
+
webhook: "Webhook",
|
|
17160
|
+
email: "Email",
|
|
17161
|
+
configured: "configur\xE9",
|
|
17162
|
+
missing: "absent",
|
|
17163
|
+
preview: "Aper\xE7u",
|
|
17164
|
+
sendNow: "Envoyer maintenant",
|
|
17165
|
+
sending: "Envoi\u2026",
|
|
17166
|
+
loading: "Chargement\u2026",
|
|
17167
|
+
noIssues: "Aucun probl\xE8me d\xE9tect\xE9 sur la p\xE9riode. \u{1F389}",
|
|
17168
|
+
scoreReg: "R\xE9gressions de score",
|
|
17169
|
+
notFound: "Nouveaux 404",
|
|
17170
|
+
rankDrops: "Chutes de position",
|
|
17171
|
+
sent: "Digest envoy\xE9",
|
|
17172
|
+
nothingToSend: "Rien \xE0 envoyer (aucun probl\xE8me).",
|
|
17173
|
+
issues: "probl\xE8me(s)"
|
|
17174
|
+
},
|
|
17175
|
+
en: {
|
|
17176
|
+
title: "Monitoring & alerts",
|
|
17177
|
+
subtitle: "Periodic digest: score regressions, new 404s, ranking drops (webhook / email).",
|
|
17178
|
+
notConfigured: "No channel configured. Set SEO_ALERT_WEBHOOK_URL and/or SEO_ALERT_EMAIL on the server, then enable features.alerts.",
|
|
17179
|
+
webhook: "Webhook",
|
|
17180
|
+
email: "Email",
|
|
17181
|
+
configured: "configured",
|
|
17182
|
+
missing: "missing",
|
|
17183
|
+
preview: "Preview",
|
|
17184
|
+
sendNow: "Send now",
|
|
17185
|
+
sending: "Sending\u2026",
|
|
17186
|
+
loading: "Loading\u2026",
|
|
17187
|
+
noIssues: "No issues for the period. \u{1F389}",
|
|
17188
|
+
scoreReg: "Score regressions",
|
|
17189
|
+
notFound: "New 404s",
|
|
17190
|
+
rankDrops: "Ranking drops",
|
|
17191
|
+
sent: "Digest sent",
|
|
17192
|
+
nothingToSend: "Nothing to send (no issues).",
|
|
17193
|
+
issues: "issue(s)"
|
|
17194
|
+
}
|
|
17195
|
+
};
|
|
17196
|
+
function AlertsPanel({ locale }) {
|
|
17197
|
+
const s = S4[locale] ?? S4.fr;
|
|
17198
|
+
const [digest, setDigest] = React4.useState(null);
|
|
17199
|
+
const [config, setConfig] = React4.useState(null);
|
|
17200
|
+
const [loading, setLoading] = React4.useState(true);
|
|
17201
|
+
const [busy, setBusy] = React4.useState(false);
|
|
17202
|
+
const [error, setError] = React4.useState(null);
|
|
17203
|
+
const [notice, setNotice] = React4.useState(null);
|
|
17204
|
+
const load = React4.useCallback(async () => {
|
|
17205
|
+
setLoading(true);
|
|
17206
|
+
setError(null);
|
|
17207
|
+
try {
|
|
17208
|
+
const res = await fetch("/api/seo-plugin/alerts-digest", { credentials: "include", cache: "no-store" });
|
|
17209
|
+
if (res.status === 404 || res.status === 403) {
|
|
17210
|
+
setConfig({ webhookConfigured: false, emailConfigured: false, scoreDrop: 0, positionDrop: 0, windowHours: 0 });
|
|
17211
|
+
setDigest(null);
|
|
17212
|
+
return;
|
|
17213
|
+
}
|
|
17214
|
+
const json = await res.json();
|
|
17215
|
+
if (!res.ok) {
|
|
17216
|
+
setError(json.error || `Error ${res.status}`);
|
|
17217
|
+
return;
|
|
17218
|
+
}
|
|
17219
|
+
setDigest(json.digest);
|
|
17220
|
+
setConfig(json.config);
|
|
17221
|
+
} catch (e) {
|
|
17222
|
+
setError(e instanceof Error ? e.message : "Network error");
|
|
17223
|
+
} finally {
|
|
17224
|
+
setLoading(false);
|
|
17225
|
+
}
|
|
17226
|
+
}, []);
|
|
17227
|
+
React4.useEffect(() => {
|
|
17228
|
+
void load();
|
|
17229
|
+
}, [load]);
|
|
17230
|
+
const sendNow = async () => {
|
|
17231
|
+
setBusy(true);
|
|
17232
|
+
setError(null);
|
|
17233
|
+
setNotice(null);
|
|
17234
|
+
try {
|
|
17235
|
+
const res = await fetch("/api/seo-plugin/alerts-run", { method: "POST", credentials: "include" });
|
|
17236
|
+
const json = await res.json();
|
|
17237
|
+
if (!res.ok) {
|
|
17238
|
+
setError(json.error || `Error ${res.status}`);
|
|
17239
|
+
return;
|
|
17240
|
+
}
|
|
17241
|
+
setNotice(json.delivery?.sent ? s.sent : s.nothingToSend);
|
|
17242
|
+
if (json.digest) setDigest(json.digest);
|
|
17243
|
+
} catch (e) {
|
|
17244
|
+
setError(e instanceof Error ? e.message : "Network error");
|
|
17245
|
+
} finally {
|
|
17246
|
+
setBusy(false);
|
|
17247
|
+
}
|
|
17248
|
+
};
|
|
17249
|
+
const card = {
|
|
17250
|
+
padding: 16,
|
|
17251
|
+
borderRadius: 12,
|
|
17252
|
+
border: `1px solid ${C7.border}`,
|
|
17253
|
+
backgroundColor: C7.card,
|
|
17254
|
+
marginBottom: 20
|
|
17255
|
+
};
|
|
17256
|
+
const btn = {
|
|
17257
|
+
padding: "8px 12px",
|
|
17258
|
+
borderRadius: 8,
|
|
17259
|
+
border: `1px solid ${C7.blue}`,
|
|
17260
|
+
backgroundColor: C7.blue,
|
|
17261
|
+
color: "#fff",
|
|
17262
|
+
fontSize: 12,
|
|
17263
|
+
fontWeight: 700,
|
|
17264
|
+
cursor: busy ? "wait" : "pointer",
|
|
17265
|
+
opacity: busy ? 0.6 : 1
|
|
17266
|
+
};
|
|
17267
|
+
const chip = (ok, label) => ({
|
|
17268
|
+
fontSize: 11,
|
|
17269
|
+
fontWeight: 700,
|
|
17270
|
+
padding: "3px 8px",
|
|
17271
|
+
borderRadius: 999,
|
|
17272
|
+
color: "#fff",
|
|
17273
|
+
backgroundColor: ok ? C7.green : C7.sub,
|
|
17274
|
+
marginRight: 6
|
|
17275
|
+
});
|
|
17276
|
+
const hasChannel = config && (config.webhookConfigured || config.emailConfigured);
|
|
17277
|
+
const list = (title, rows) => rows.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 10 }, children: [
|
|
17278
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 12, fontWeight: 700, color: C7.text, marginBottom: 4 }, children: [
|
|
17279
|
+
title,
|
|
17280
|
+
" ",
|
|
17281
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: C7.amber }, children: [
|
|
17282
|
+
"(",
|
|
17283
|
+
rows.length,
|
|
17284
|
+
")"
|
|
17285
|
+
] })
|
|
17286
|
+
] }),
|
|
17287
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: 0, paddingLeft: 18, fontSize: 12, color: C7.sub, lineHeight: 1.6 }, children: rows.slice(0, 8).map((r, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: r }, i)) })
|
|
17288
|
+
] }) : null;
|
|
17289
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: card, children: [
|
|
17290
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flexWrap: "wrap" }, children: [
|
|
17291
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
17292
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 800, color: C7.text }, children: s.title }),
|
|
17293
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: C7.sub, marginTop: 2 }, children: s.subtitle })
|
|
17294
|
+
] }),
|
|
17295
|
+
hasChannel && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: sendNow, disabled: busy, style: btn, children: busy ? s.sending : s.sendNow })
|
|
17296
|
+
] }),
|
|
17297
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: C7.red, fontSize: 13, fontWeight: 600, marginTop: 10 }, children: error }),
|
|
17298
|
+
notice && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: C7.green, fontSize: 13, fontWeight: 600, marginTop: 10 }, children: notice }),
|
|
17299
|
+
config && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 12 }, children: [
|
|
17300
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: chip(config.webhookConfigured, s.webhook), children: [
|
|
17301
|
+
s.webhook,
|
|
17302
|
+
": ",
|
|
17303
|
+
config.webhookConfigured ? s.configured : s.missing
|
|
17304
|
+
] }),
|
|
17305
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: chip(config.emailConfigured, s.email), children: [
|
|
17306
|
+
s.email,
|
|
17307
|
+
": ",
|
|
17308
|
+
config.emailConfigured ? s.configured : s.missing
|
|
17309
|
+
] })
|
|
17310
|
+
] }),
|
|
17311
|
+
!loading && !hasChannel && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12, fontSize: 13, color: C7.sub }, children: s.notConfigured }),
|
|
17312
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12, fontSize: 13, color: C7.sub }, children: s.loading }),
|
|
17313
|
+
digest && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 8 }, children: [
|
|
17314
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 12, color: C7.sub, marginTop: 6 }, children: [
|
|
17315
|
+
digest.totalIssues,
|
|
17316
|
+
" ",
|
|
17317
|
+
s.issues
|
|
17318
|
+
] }),
|
|
17319
|
+
digest.totalIssues === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 8, fontSize: 13, color: C7.sub }, children: s.noIssues }),
|
|
17320
|
+
list(
|
|
17321
|
+
s.scoreReg,
|
|
17322
|
+
digest.scoreRegressions.map((r) => `${r.collection}/${r.documentId} \u2014 ${r.from} \u2192 ${r.to} (\u2212${r.drop})`)
|
|
17323
|
+
),
|
|
17324
|
+
list(s.notFound, digest.newNotFound.map((n) => `${n.url} \u2014 ${n.count}\xD7`)),
|
|
17325
|
+
list(s.rankDrops, digest.rankDrops.map((d) => `\u201C${d.query}\u201D \u2014 #${d.from} \u2192 #${d.to} (\u25BC${d.drop})`))
|
|
17326
|
+
] })
|
|
17327
|
+
] });
|
|
17328
|
+
}
|
|
17329
|
+
var C8 = {
|
|
17330
|
+
text: "var(--theme-text, #1a1a1a)",
|
|
17331
|
+
sub: "var(--theme-elevation-600, #6b7280)",
|
|
17332
|
+
card: "var(--theme-elevation-50, #f9fafb)",
|
|
17333
|
+
bg: "var(--theme-elevation-0, #fff)",
|
|
17334
|
+
border: "var(--theme-elevation-200, #e5e7eb)",
|
|
17335
|
+
green: "#22c55e",
|
|
17336
|
+
red: "#ef4444",
|
|
17337
|
+
violet: "#7c3aed"
|
|
17338
|
+
};
|
|
17339
|
+
var S5 = {
|
|
17340
|
+
fr: {
|
|
17341
|
+
title: "Alt-text IA des images",
|
|
17342
|
+
subtitle: "G\xE9n\xE8re l'attribut alt des images qui n'en ont pas (Claude vision), pour l'accessibilit\xE9 et le SEO.",
|
|
17343
|
+
none: "Toutes les images ont un alt. \u{1F389}",
|
|
17344
|
+
forbidden: "R\xE9serv\xE9 aux administrateurs.",
|
|
17345
|
+
disabled: "Fonction IA d\xE9sactiv\xE9e (features.aiFeatures).",
|
|
17346
|
+
missing: "image(s) sans alt",
|
|
17347
|
+
generate: "G\xE9n\xE9rer",
|
|
17348
|
+
generating: "\u2026",
|
|
17349
|
+
apply: "Appliquer",
|
|
17350
|
+
applied: "Appliqu\xE9 \u2713",
|
|
17351
|
+
noKey: "Cl\xE9 API Claude requise (ANTHROPIC_API_KEY).",
|
|
17352
|
+
loading: "Chargement\u2026",
|
|
17353
|
+
refresh: "Rafra\xEEchir"
|
|
17354
|
+
},
|
|
17355
|
+
en: {
|
|
17356
|
+
title: "AI image alt-text",
|
|
17357
|
+
subtitle: "Generate alt text for images that lack one (Claude vision), for accessibility and SEO.",
|
|
17358
|
+
none: "All images have alt text. \u{1F389}",
|
|
17359
|
+
forbidden: "Admins only.",
|
|
17360
|
+
disabled: "AI feature disabled (features.aiFeatures).",
|
|
17361
|
+
missing: "image(s) without alt",
|
|
17362
|
+
generate: "Generate",
|
|
17363
|
+
generating: "\u2026",
|
|
17364
|
+
apply: "Apply",
|
|
17365
|
+
applied: "Applied \u2713",
|
|
17366
|
+
noKey: "Claude API key required (ANTHROPIC_API_KEY).",
|
|
17367
|
+
loading: "Loading\u2026",
|
|
17368
|
+
refresh: "Refresh"
|
|
17369
|
+
}
|
|
17370
|
+
};
|
|
17371
|
+
function AltTextPanel({ locale }) {
|
|
17372
|
+
const s = S5[locale] ?? S5.fr;
|
|
17373
|
+
const [items, setItems] = React4.useState(null);
|
|
17374
|
+
const [collection, setCollection] = React4.useState("media");
|
|
17375
|
+
const [missingCount, setMissingCount] = React4.useState(0);
|
|
17376
|
+
const [loading, setLoading] = React4.useState(true);
|
|
17377
|
+
const [state, setState] = React4.useState({});
|
|
17378
|
+
const [status, setStatus] = React4.useState("ok");
|
|
17379
|
+
const load = React4.useCallback(async () => {
|
|
17380
|
+
setLoading(true);
|
|
17381
|
+
try {
|
|
17382
|
+
const res = await fetch("/api/seo-plugin/alt-text-audit", { credentials: "include", cache: "no-store" });
|
|
17383
|
+
if (res.status === 404) {
|
|
17384
|
+
setStatus("disabled");
|
|
17385
|
+
return;
|
|
17386
|
+
}
|
|
17387
|
+
if (res.status === 403) {
|
|
17388
|
+
setStatus("forbidden");
|
|
17389
|
+
return;
|
|
17390
|
+
}
|
|
17391
|
+
const json = await res.json();
|
|
17392
|
+
setStatus("ok");
|
|
17393
|
+
setItems(json.items || []);
|
|
17394
|
+
setMissingCount(json.missingCount || 0);
|
|
17395
|
+
setCollection(json.collection || "media");
|
|
17396
|
+
} catch {
|
|
17397
|
+
setItems([]);
|
|
17398
|
+
} finally {
|
|
17399
|
+
setLoading(false);
|
|
17400
|
+
}
|
|
17401
|
+
}, []);
|
|
17402
|
+
React4.useEffect(() => {
|
|
17403
|
+
void load();
|
|
17404
|
+
}, [load]);
|
|
17405
|
+
const setRow = (id, patch) => setState((prev) => ({ ...prev, [id]: { ...prev[id], ...patch } }));
|
|
17406
|
+
const generate = async (item) => {
|
|
17407
|
+
setRow(item.id, { busy: true, error: void 0 });
|
|
17408
|
+
try {
|
|
17409
|
+
const res = await fetch("/api/seo-plugin/ai-alt-text", {
|
|
17410
|
+
method: "POST",
|
|
17411
|
+
credentials: "include",
|
|
17412
|
+
headers: { "Content-Type": "application/json" },
|
|
17413
|
+
body: JSON.stringify({ collection, id: item.id, apply: false })
|
|
17414
|
+
});
|
|
17415
|
+
const json = await res.json();
|
|
17416
|
+
if (!res.ok) {
|
|
17417
|
+
setRow(item.id, { busy: false, error: json.code === "no_api_key" ? s.noKey : json.error || `Error ${res.status}` });
|
|
17418
|
+
return;
|
|
17419
|
+
}
|
|
17420
|
+
setRow(item.id, { busy: false, alt: json.alt });
|
|
17421
|
+
} catch (e) {
|
|
17422
|
+
setRow(item.id, { busy: false, error: e instanceof Error ? e.message : "Network error" });
|
|
17423
|
+
}
|
|
17424
|
+
};
|
|
17425
|
+
const apply = async (item) => {
|
|
17426
|
+
const alt = state[item.id]?.alt;
|
|
17427
|
+
if (!alt) return;
|
|
17428
|
+
setRow(item.id, { busy: true, error: void 0 });
|
|
17429
|
+
try {
|
|
17430
|
+
const res = await fetch("/api/seo-plugin/ai-alt-text", {
|
|
17431
|
+
method: "POST",
|
|
17432
|
+
credentials: "include",
|
|
17433
|
+
headers: { "Content-Type": "application/json" },
|
|
17434
|
+
body: JSON.stringify({ collection, id: item.id, apply: true, altText: alt })
|
|
17435
|
+
});
|
|
17436
|
+
const json = await res.json();
|
|
17437
|
+
if (!res.ok) {
|
|
17438
|
+
setRow(item.id, { busy: false, error: json.error || `Error ${res.status}` });
|
|
17439
|
+
return;
|
|
17440
|
+
}
|
|
17441
|
+
setRow(item.id, { busy: false, applied: true });
|
|
17442
|
+
} catch (e) {
|
|
17443
|
+
setRow(item.id, { busy: false, error: e instanceof Error ? e.message : "Network error" });
|
|
17444
|
+
}
|
|
17445
|
+
};
|
|
17446
|
+
const card = {
|
|
17447
|
+
padding: 16,
|
|
17448
|
+
borderRadius: 12,
|
|
17449
|
+
border: `1px solid ${C8.border}`,
|
|
17450
|
+
backgroundColor: C8.card,
|
|
17451
|
+
marginBottom: 20
|
|
17452
|
+
};
|
|
17453
|
+
const btn = (bg) => ({
|
|
17454
|
+
padding: "6px 10px",
|
|
17455
|
+
borderRadius: 6,
|
|
17456
|
+
border: `1px solid ${bg}`,
|
|
17457
|
+
backgroundColor: bg,
|
|
17458
|
+
color: "#fff",
|
|
17459
|
+
fontSize: 11,
|
|
17460
|
+
fontWeight: 700,
|
|
17461
|
+
cursor: "pointer"
|
|
17462
|
+
});
|
|
17463
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: card, children: [
|
|
17464
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, flexWrap: "wrap" }, children: [
|
|
17465
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
17466
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 16, fontWeight: 800, color: C8.text }, children: s.title }),
|
|
17467
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: C8.sub, marginTop: 2 }, children: s.subtitle })
|
|
17468
|
+
] }),
|
|
17469
|
+
status === "ok" && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => void load(), style: btn(C8.sub), children: s.refresh })
|
|
17470
|
+
] }),
|
|
17471
|
+
status === "forbidden" && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12, fontSize: 13, color: C8.sub }, children: s.forbidden }),
|
|
17472
|
+
status === "disabled" && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 12, fontSize: 13, color: C8.sub }, children: s.disabled }),
|
|
17473
|
+
status === "ok" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 12 }, children: [
|
|
17474
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 13, color: C8.sub }, children: s.loading }),
|
|
17475
|
+
!loading && items && items.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 13, color: C8.sub }, children: s.none }),
|
|
17476
|
+
!loading && items && items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
17477
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 12, color: C8.sub, marginBottom: 10 }, children: [
|
|
17478
|
+
missingCount,
|
|
17479
|
+
" ",
|
|
17480
|
+
s.missing
|
|
17481
|
+
] }),
|
|
17482
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: items.map((item) => {
|
|
17483
|
+
const rs = state[item.id] || {};
|
|
17484
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17485
|
+
"div",
|
|
17486
|
+
{
|
|
17487
|
+
style: {
|
|
17488
|
+
display: "flex",
|
|
17489
|
+
gap: 12,
|
|
17490
|
+
alignItems: "center",
|
|
17491
|
+
padding: 8,
|
|
17492
|
+
borderRadius: 8,
|
|
17493
|
+
border: `1px solid ${C8.border}`,
|
|
17494
|
+
backgroundColor: C8.bg
|
|
17495
|
+
},
|
|
17496
|
+
children: [
|
|
17497
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17498
|
+
"img",
|
|
17499
|
+
{
|
|
17500
|
+
src: item.url,
|
|
17501
|
+
alt: "",
|
|
17502
|
+
style: { width: 48, height: 48, objectFit: "cover", borderRadius: 6, flexShrink: 0, border: `1px solid ${C8.border}` }
|
|
17503
|
+
}
|
|
17504
|
+
),
|
|
17505
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
17506
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, color: C8.sub, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: item.filename }),
|
|
17507
|
+
rs.alt !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
17508
|
+
"input",
|
|
17509
|
+
{
|
|
17510
|
+
value: rs.alt,
|
|
17511
|
+
onChange: (e) => setRow(item.id, { alt: e.target.value }),
|
|
17512
|
+
disabled: rs.applied,
|
|
17513
|
+
maxLength: 125,
|
|
17514
|
+
style: {
|
|
17515
|
+
width: "100%",
|
|
17516
|
+
marginTop: 4,
|
|
17517
|
+
padding: "4px 8px",
|
|
17518
|
+
fontSize: 12,
|
|
17519
|
+
borderRadius: 6,
|
|
17520
|
+
border: `1px solid ${C8.border}`,
|
|
17521
|
+
backgroundColor: C8.bg,
|
|
17522
|
+
color: C8.text
|
|
17523
|
+
}
|
|
17524
|
+
}
|
|
17525
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: C8.sub, marginTop: 4, fontStyle: "italic" }, children: "\u2014" }),
|
|
17526
|
+
rs.error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, color: C8.red, marginTop: 2 }, children: rs.error })
|
|
17527
|
+
] }),
|
|
17528
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { flexShrink: 0 }, children: rs.applied ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 11, fontWeight: 700, color: C8.green }, children: s.applied }) : rs.alt !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => void apply(item), disabled: rs.busy, style: btn(C8.green), children: rs.busy ? s.generating : s.apply }) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => void generate(item), disabled: rs.busy, style: btn(C8.violet), children: rs.busy ? s.generating : s.generate }) })
|
|
17529
|
+
]
|
|
17530
|
+
},
|
|
17531
|
+
item.id
|
|
17532
|
+
);
|
|
17533
|
+
}) })
|
|
17534
|
+
] })
|
|
17535
|
+
] })
|
|
17536
|
+
] });
|
|
17537
|
+
}
|
|
16745
17538
|
var V8 = {
|
|
16746
17539
|
text: "var(--theme-text, #1a1a1a)",
|
|
16747
17540
|
textSecondary: "var(--theme-elevation-600, #6b7280)",
|
|
@@ -17156,6 +17949,9 @@ function PerformanceView() {
|
|
|
17156
17949
|
),
|
|
17157
17950
|
/* @__PURE__ */ jsxRuntime.jsx(CoreWebVitalsPanel, { locale }),
|
|
17158
17951
|
/* @__PURE__ */ jsxRuntime.jsx(GscPanel, { locale }),
|
|
17952
|
+
/* @__PURE__ */ jsxRuntime.jsx(RankTrackingPanel, { locale }),
|
|
17953
|
+
/* @__PURE__ */ jsxRuntime.jsx(AlertsPanel, { locale }),
|
|
17954
|
+
/* @__PURE__ */ jsxRuntime.jsx(AltTextPanel, { locale }),
|
|
17159
17955
|
showImport && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17160
17956
|
"div",
|
|
17161
17957
|
{
|
|
@@ -18815,7 +19611,7 @@ var controlBtnStyle = {
|
|
|
18815
19611
|
cursor: "pointer",
|
|
18816
19612
|
lineHeight: 1.4
|
|
18817
19613
|
};
|
|
18818
|
-
var
|
|
19614
|
+
var C9 = {
|
|
18819
19615
|
cyan: "#00E5FF",
|
|
18820
19616
|
black: "#000",
|
|
18821
19617
|
green: "#22c55e",
|
|
@@ -18830,10 +19626,10 @@ var C6 = {
|
|
|
18830
19626
|
var TITLE_MIN = 30;
|
|
18831
19627
|
var TITLE_MAX = 60;
|
|
18832
19628
|
function getCharColor(len) {
|
|
18833
|
-
if (len === 0) return
|
|
18834
|
-
if (len >= TITLE_MIN && len <= TITLE_MAX) return
|
|
18835
|
-
if (len > 0 && len < TITLE_MIN) return
|
|
18836
|
-
return
|
|
19629
|
+
if (len === 0) return C9.textSecondary;
|
|
19630
|
+
if (len >= TITLE_MIN && len <= TITLE_MAX) return C9.green;
|
|
19631
|
+
if (len > 0 && len < TITLE_MIN) return C9.orange;
|
|
19632
|
+
return C9.red;
|
|
18837
19633
|
}
|
|
18838
19634
|
function getProgressPercent(len) {
|
|
18839
19635
|
if (len === 0) return 0;
|
|
@@ -18841,9 +19637,9 @@ function getProgressPercent(len) {
|
|
|
18841
19637
|
}
|
|
18842
19638
|
function getProgressColor(len) {
|
|
18843
19639
|
if (len === 0) return "var(--theme-elevation-200, #e5e7eb)";
|
|
18844
|
-
if (len >= TITLE_MIN && len <= TITLE_MAX) return
|
|
18845
|
-
if (len < TITLE_MIN) return
|
|
18846
|
-
return
|
|
19640
|
+
if (len >= TITLE_MIN && len <= TITLE_MAX) return C9.green;
|
|
19641
|
+
if (len < TITLE_MIN) return C9.orange;
|
|
19642
|
+
return C9.red;
|
|
18847
19643
|
}
|
|
18848
19644
|
function MetaTitleField({
|
|
18849
19645
|
path,
|
|
@@ -18914,7 +19710,7 @@ function MetaTitleField({
|
|
|
18914
19710
|
style: {
|
|
18915
19711
|
fontSize: 13,
|
|
18916
19712
|
fontWeight: 700,
|
|
18917
|
-
color:
|
|
19713
|
+
color: C9.textPrimary
|
|
18918
19714
|
},
|
|
18919
19715
|
children: t.metaTitle.label
|
|
18920
19716
|
}
|
|
@@ -18954,9 +19750,9 @@ function MetaTitleField({
|
|
|
18954
19750
|
fontSize: 14,
|
|
18955
19751
|
fontFamily: "inherit",
|
|
18956
19752
|
borderRadius: 8,
|
|
18957
|
-
border: `2px solid ${
|
|
18958
|
-
backgroundColor:
|
|
18959
|
-
color:
|
|
19753
|
+
border: `2px solid ${C9.border}`,
|
|
19754
|
+
backgroundColor: C9.surfaceBg,
|
|
19755
|
+
color: C9.textPrimary,
|
|
18960
19756
|
outline: "none",
|
|
18961
19757
|
boxShadow: "2px 2px 0 0 var(--theme-border-color, rgba(0,0,0,1))"
|
|
18962
19758
|
}
|
|
@@ -18974,9 +19770,9 @@ function MetaTitleField({
|
|
|
18974
19770
|
gap: 5,
|
|
18975
19771
|
padding: "8px 14px",
|
|
18976
19772
|
borderRadius: 8,
|
|
18977
|
-
border: `2px solid ${
|
|
18978
|
-
backgroundColor: loading ?
|
|
18979
|
-
color: loading ?
|
|
19773
|
+
border: `2px solid ${C9.border}`,
|
|
19774
|
+
backgroundColor: loading ? C9.surface50 : C9.cyan,
|
|
19775
|
+
color: loading ? C9.textSecondary : C9.black,
|
|
18980
19776
|
fontWeight: 800,
|
|
18981
19777
|
fontSize: 11,
|
|
18982
19778
|
textTransform: "uppercase",
|
|
@@ -19023,7 +19819,7 @@ function MetaTitleField({
|
|
|
19023
19819
|
justifyContent: "space-between",
|
|
19024
19820
|
marginTop: 4,
|
|
19025
19821
|
fontSize: 10,
|
|
19026
|
-
color:
|
|
19822
|
+
color: C9.textSecondary
|
|
19027
19823
|
},
|
|
19028
19824
|
children: [
|
|
19029
19825
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
@@ -19057,9 +19853,9 @@ function MetaTitleField({
|
|
|
19057
19853
|
borderRadius: 6,
|
|
19058
19854
|
fontSize: 11,
|
|
19059
19855
|
fontWeight: 600,
|
|
19060
|
-
color:
|
|
19856
|
+
color: C9.red,
|
|
19061
19857
|
backgroundColor: "rgba(239,68,68,0.08)",
|
|
19062
|
-
border: `1px solid ${
|
|
19858
|
+
border: `1px solid ${C9.red}`
|
|
19063
19859
|
},
|
|
19064
19860
|
children: error
|
|
19065
19861
|
}
|
|
@@ -19068,7 +19864,7 @@ function MetaTitleField({
|
|
|
19068
19864
|
}
|
|
19069
19865
|
);
|
|
19070
19866
|
}
|
|
19071
|
-
var
|
|
19867
|
+
var C10 = {
|
|
19072
19868
|
cyan: "#00E5FF",
|
|
19073
19869
|
black: "#000",
|
|
19074
19870
|
green: "#22c55e",
|
|
@@ -19083,10 +19879,10 @@ var C7 = {
|
|
|
19083
19879
|
var DESC_MIN = 120;
|
|
19084
19880
|
var DESC_MAX = 160;
|
|
19085
19881
|
function getCharColor2(len) {
|
|
19086
|
-
if (len === 0) return
|
|
19087
|
-
if (len >= DESC_MIN && len <= DESC_MAX) return
|
|
19088
|
-
if (len > 0 && len < DESC_MIN) return
|
|
19089
|
-
return
|
|
19882
|
+
if (len === 0) return C10.textSecondary;
|
|
19883
|
+
if (len >= DESC_MIN && len <= DESC_MAX) return C10.green;
|
|
19884
|
+
if (len > 0 && len < DESC_MIN) return C10.orange;
|
|
19885
|
+
return C10.red;
|
|
19090
19886
|
}
|
|
19091
19887
|
function getProgressPercent2(len) {
|
|
19092
19888
|
if (len === 0) return 0;
|
|
@@ -19094,9 +19890,9 @@ function getProgressPercent2(len) {
|
|
|
19094
19890
|
}
|
|
19095
19891
|
function getProgressColor2(len) {
|
|
19096
19892
|
if (len === 0) return "var(--theme-elevation-200, #e5e7eb)";
|
|
19097
|
-
if (len >= DESC_MIN && len <= DESC_MAX) return
|
|
19098
|
-
if (len < DESC_MIN) return
|
|
19099
|
-
return
|
|
19893
|
+
if (len >= DESC_MIN && len <= DESC_MAX) return C10.green;
|
|
19894
|
+
if (len < DESC_MIN) return C10.orange;
|
|
19895
|
+
return C10.red;
|
|
19100
19896
|
}
|
|
19101
19897
|
function MetaDescriptionField({
|
|
19102
19898
|
path,
|
|
@@ -19167,7 +19963,7 @@ function MetaDescriptionField({
|
|
|
19167
19963
|
style: {
|
|
19168
19964
|
fontSize: 13,
|
|
19169
19965
|
fontWeight: 700,
|
|
19170
|
-
color:
|
|
19966
|
+
color: C10.textPrimary
|
|
19171
19967
|
},
|
|
19172
19968
|
children: t.metaDescription.label
|
|
19173
19969
|
}
|
|
@@ -19207,9 +20003,9 @@ function MetaDescriptionField({
|
|
|
19207
20003
|
fontSize: 14,
|
|
19208
20004
|
fontFamily: "inherit",
|
|
19209
20005
|
borderRadius: 8,
|
|
19210
|
-
border: `2px solid ${
|
|
19211
|
-
backgroundColor:
|
|
19212
|
-
color:
|
|
20006
|
+
border: `2px solid ${C10.border}`,
|
|
20007
|
+
backgroundColor: C10.surfaceBg,
|
|
20008
|
+
color: C10.textPrimary,
|
|
19213
20009
|
outline: "none",
|
|
19214
20010
|
resize: "vertical",
|
|
19215
20011
|
lineHeight: 1.5,
|
|
@@ -19229,9 +20025,9 @@ function MetaDescriptionField({
|
|
|
19229
20025
|
gap: 5,
|
|
19230
20026
|
padding: "8px 14px",
|
|
19231
20027
|
borderRadius: 8,
|
|
19232
|
-
border: `2px solid ${
|
|
19233
|
-
backgroundColor: loading ?
|
|
19234
|
-
color: loading ?
|
|
20028
|
+
border: `2px solid ${C10.border}`,
|
|
20029
|
+
backgroundColor: loading ? C10.surface50 : C10.cyan,
|
|
20030
|
+
color: loading ? C10.textSecondary : C10.black,
|
|
19235
20031
|
fontWeight: 800,
|
|
19236
20032
|
fontSize: 11,
|
|
19237
20033
|
textTransform: "uppercase",
|
|
@@ -19279,7 +20075,7 @@ function MetaDescriptionField({
|
|
|
19279
20075
|
justifyContent: "space-between",
|
|
19280
20076
|
marginTop: 4,
|
|
19281
20077
|
fontSize: 10,
|
|
19282
|
-
color:
|
|
20078
|
+
color: C10.textSecondary
|
|
19283
20079
|
},
|
|
19284
20080
|
children: [
|
|
19285
20081
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
@@ -19313,9 +20109,9 @@ function MetaDescriptionField({
|
|
|
19313
20109
|
borderRadius: 6,
|
|
19314
20110
|
fontSize: 11,
|
|
19315
20111
|
fontWeight: 600,
|
|
19316
|
-
color:
|
|
20112
|
+
color: C10.red,
|
|
19317
20113
|
backgroundColor: "rgba(239,68,68,0.08)",
|
|
19318
|
-
border: `1px solid ${
|
|
20114
|
+
border: `1px solid ${C10.red}`
|
|
19319
20115
|
},
|
|
19320
20116
|
children: error
|
|
19321
20117
|
}
|
|
@@ -19324,7 +20120,7 @@ function MetaDescriptionField({
|
|
|
19324
20120
|
}
|
|
19325
20121
|
);
|
|
19326
20122
|
}
|
|
19327
|
-
var
|
|
20123
|
+
var C11 = {
|
|
19328
20124
|
cyan: "#00E5FF",
|
|
19329
20125
|
black: "#000",
|
|
19330
20126
|
white: "#fff",
|
|
@@ -19401,8 +20197,8 @@ function MetaImageField({
|
|
|
19401
20197
|
gap: 10,
|
|
19402
20198
|
padding: "10px 14px",
|
|
19403
20199
|
borderRadius: 8,
|
|
19404
|
-
border: `2px solid ${
|
|
19405
|
-
backgroundColor:
|
|
20200
|
+
border: `2px solid ${C11.border}`,
|
|
20201
|
+
backgroundColor: C11.surfaceBg,
|
|
19406
20202
|
boxShadow: "2px 2px 0 0 var(--theme-border-color, rgba(0,0,0,1))"
|
|
19407
20203
|
},
|
|
19408
20204
|
children: [
|
|
@@ -19421,7 +20217,7 @@ function MetaImageField({
|
|
|
19421
20217
|
fontWeight: 900,
|
|
19422
20218
|
backgroundColor: hasImage ? "rgba(34,197,94,0.15)" : "rgba(255,138,0,0.15)",
|
|
19423
20219
|
color: hasImage ? "#16a34a" : "#d97706",
|
|
19424
|
-
border: `1px solid ${hasImage ?
|
|
20220
|
+
border: `1px solid ${hasImage ? C11.green : C11.orange}`
|
|
19425
20221
|
},
|
|
19426
20222
|
children: hasImage ? "\u2713" : "!"
|
|
19427
20223
|
}
|
|
@@ -19433,7 +20229,7 @@ function MetaImageField({
|
|
|
19433
20229
|
style: {
|
|
19434
20230
|
fontSize: 12,
|
|
19435
20231
|
fontWeight: 700,
|
|
19436
|
-
color:
|
|
20232
|
+
color: C11.textPrimary
|
|
19437
20233
|
},
|
|
19438
20234
|
children: t.metaImage.label
|
|
19439
20235
|
}
|
|
@@ -19443,7 +20239,7 @@ function MetaImageField({
|
|
|
19443
20239
|
{
|
|
19444
20240
|
style: {
|
|
19445
20241
|
fontSize: 10,
|
|
19446
|
-
color:
|
|
20242
|
+
color: C11.textSecondary,
|
|
19447
20243
|
lineHeight: 1.4
|
|
19448
20244
|
},
|
|
19449
20245
|
children: hasImage ? t.metaImage.imageSet : t.metaImage.noImage
|
|
@@ -19463,9 +20259,9 @@ function MetaImageField({
|
|
|
19463
20259
|
gap: 5,
|
|
19464
20260
|
padding: "8px 14px",
|
|
19465
20261
|
borderRadius: 8,
|
|
19466
|
-
border: `2px solid ${
|
|
19467
|
-
backgroundColor: loading ?
|
|
19468
|
-
color: loading ?
|
|
20262
|
+
border: `2px solid ${C11.border}`,
|
|
20263
|
+
backgroundColor: loading ? C11.surface50 : success ? C11.green : C11.cyan,
|
|
20264
|
+
color: loading ? C11.textSecondary : success ? C11.white : C11.black,
|
|
19469
20265
|
fontWeight: 800,
|
|
19470
20266
|
fontSize: 11,
|
|
19471
20267
|
textTransform: "uppercase",
|
|
@@ -19492,9 +20288,9 @@ function MetaImageField({
|
|
|
19492
20288
|
borderRadius: 6,
|
|
19493
20289
|
fontSize: 11,
|
|
19494
20290
|
fontWeight: 600,
|
|
19495
|
-
color:
|
|
20291
|
+
color: C11.red,
|
|
19496
20292
|
backgroundColor: "rgba(239,68,68,0.08)",
|
|
19497
|
-
border: `1px solid ${
|
|
20293
|
+
border: `1px solid ${C11.red}`
|
|
19498
20294
|
},
|
|
19499
20295
|
children: error
|
|
19500
20296
|
}
|
|
@@ -19503,7 +20299,7 @@ function MetaImageField({
|
|
|
19503
20299
|
}
|
|
19504
20300
|
);
|
|
19505
20301
|
}
|
|
19506
|
-
var
|
|
20302
|
+
var C12 = {
|
|
19507
20303
|
black: "#000",
|
|
19508
20304
|
white: "#fff",
|
|
19509
20305
|
green: "#22c55e",
|
|
@@ -19517,15 +20313,15 @@ var C9 = {
|
|
|
19517
20313
|
function getCompletenessColor(count) {
|
|
19518
20314
|
switch (count) {
|
|
19519
20315
|
case 0:
|
|
19520
|
-
return
|
|
20316
|
+
return C12.red;
|
|
19521
20317
|
case 1:
|
|
19522
|
-
return
|
|
20318
|
+
return C12.orange;
|
|
19523
20319
|
case 2:
|
|
19524
|
-
return
|
|
20320
|
+
return C12.yellow;
|
|
19525
20321
|
case 3:
|
|
19526
|
-
return
|
|
20322
|
+
return C12.green;
|
|
19527
20323
|
default:
|
|
19528
|
-
return
|
|
20324
|
+
return C12.textSecondary;
|
|
19529
20325
|
}
|
|
19530
20326
|
}
|
|
19531
20327
|
function getCompletenessLabel(count, ov) {
|
|
@@ -19583,8 +20379,8 @@ function OverviewField({
|
|
|
19583
20379
|
fontFamily: "var(--font-body, Inter, system-ui, sans-serif)",
|
|
19584
20380
|
padding: "12px 14px",
|
|
19585
20381
|
borderRadius: 10,
|
|
19586
|
-
border: `2px solid ${
|
|
19587
|
-
backgroundColor:
|
|
20382
|
+
border: `2px solid ${C12.border}`,
|
|
20383
|
+
backgroundColor: C12.surfaceBg,
|
|
19588
20384
|
boxShadow: "3px 3px 0 0 var(--theme-border-color, rgba(0,0,0,1))",
|
|
19589
20385
|
marginBottom: 12
|
|
19590
20386
|
},
|
|
@@ -19607,7 +20403,7 @@ function OverviewField({
|
|
|
19607
20403
|
fontWeight: 800,
|
|
19608
20404
|
textTransform: "uppercase",
|
|
19609
20405
|
letterSpacing: "0.04em",
|
|
19610
|
-
color:
|
|
20406
|
+
color: C12.textPrimary
|
|
19611
20407
|
},
|
|
19612
20408
|
children: t.overview.metaCompleteness
|
|
19613
20409
|
}
|
|
@@ -19622,8 +20418,8 @@ function OverviewField({
|
|
|
19622
20418
|
fontSize: 11,
|
|
19623
20419
|
fontWeight: 800,
|
|
19624
20420
|
backgroundColor: completenessColor,
|
|
19625
|
-
color: completenessColor ===
|
|
19626
|
-
border: `2px solid ${
|
|
20421
|
+
color: completenessColor === C12.yellow ? C12.black : C12.white,
|
|
20422
|
+
border: `2px solid ${C12.border}`,
|
|
19627
20423
|
textTransform: "uppercase",
|
|
19628
20424
|
letterSpacing: "0.03em"
|
|
19629
20425
|
},
|
|
@@ -19721,7 +20517,7 @@ function OverviewField({
|
|
|
19721
20517
|
style: {
|
|
19722
20518
|
fontSize: 12,
|
|
19723
20519
|
fontWeight: 600,
|
|
19724
|
-
color: item.filled ?
|
|
20520
|
+
color: item.filled ? C12.textPrimary : C12.textSecondary
|
|
19725
20521
|
},
|
|
19726
20522
|
children: item.label
|
|
19727
20523
|
}
|
|
@@ -19733,7 +20529,7 @@ function OverviewField({
|
|
|
19733
20529
|
marginLeft: "auto",
|
|
19734
20530
|
fontSize: 10,
|
|
19735
20531
|
fontWeight: 700,
|
|
19736
|
-
color: item.filled ?
|
|
20532
|
+
color: item.filled ? C12.green : C12.red,
|
|
19737
20533
|
textTransform: "uppercase",
|
|
19738
20534
|
letterSpacing: "0.03em"
|
|
19739
20535
|
},
|
|
@@ -19750,7 +20546,7 @@ function OverviewField({
|
|
|
19750
20546
|
}
|
|
19751
20547
|
);
|
|
19752
20548
|
}
|
|
19753
|
-
var
|
|
20549
|
+
var C13 = {
|
|
19754
20550
|
cyan: "#00E5FF",
|
|
19755
20551
|
black: "#000",
|
|
19756
20552
|
white: "#fff",
|
|
@@ -19769,10 +20565,10 @@ var G = {
|
|
|
19769
20565
|
descGrey: "#4d5156",
|
|
19770
20566
|
faviconBg: "#e8eaed"};
|
|
19771
20567
|
function charCountColor2(len, min, max) {
|
|
19772
|
-
if (len >= min && len <= max) return
|
|
19773
|
-
if (len > 0 && len < min) return
|
|
19774
|
-
if (len > max) return
|
|
19775
|
-
return
|
|
20568
|
+
if (len >= min && len <= max) return C13.green;
|
|
20569
|
+
if (len > 0 && len < min) return C13.orange;
|
|
20570
|
+
if (len > max) return C13.red;
|
|
20571
|
+
return C13.textSecondary;
|
|
19776
20572
|
}
|
|
19777
20573
|
function truncateText(text, maxChars) {
|
|
19778
20574
|
if (text.length <= maxChars) return text;
|
|
@@ -19827,8 +20623,8 @@ function SerpPreview({
|
|
|
19827
20623
|
padding: "10px 12px",
|
|
19828
20624
|
cursor: "pointer",
|
|
19829
20625
|
borderRadius: 8,
|
|
19830
|
-
border: `2px solid ${
|
|
19831
|
-
backgroundColor:
|
|
20626
|
+
border: `2px solid ${C13.border}`,
|
|
20627
|
+
backgroundColor: C13.surface50,
|
|
19832
20628
|
userSelect: "none"
|
|
19833
20629
|
},
|
|
19834
20630
|
children: [
|
|
@@ -19843,7 +20639,7 @@ function SerpPreview({
|
|
|
19843
20639
|
fontWeight: 800,
|
|
19844
20640
|
textTransform: "uppercase",
|
|
19845
20641
|
letterSpacing: "0.04em",
|
|
19846
|
-
color:
|
|
20642
|
+
color: C13.textPrimary
|
|
19847
20643
|
},
|
|
19848
20644
|
children: [
|
|
19849
20645
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -19875,7 +20671,7 @@ function SerpPreview({
|
|
|
19875
20671
|
transition: "transform 0.2s",
|
|
19876
20672
|
display: "inline-block",
|
|
19877
20673
|
transform: open ? "rotate(90deg)" : "none",
|
|
19878
|
-
color:
|
|
20674
|
+
color: C13.textSecondary
|
|
19879
20675
|
},
|
|
19880
20676
|
children: "\u25B6"
|
|
19881
20677
|
}
|
|
@@ -19908,10 +20704,10 @@ function SerpPreview({
|
|
|
19908
20704
|
"div",
|
|
19909
20705
|
{
|
|
19910
20706
|
style: {
|
|
19911
|
-
backgroundColor:
|
|
19912
|
-
border: `2px solid ${
|
|
20707
|
+
backgroundColor: C13.white,
|
|
20708
|
+
border: `2px solid ${C13.border}`,
|
|
19913
20709
|
borderRadius: 12,
|
|
19914
|
-
boxShadow: `3px 3px 0 0 ${
|
|
20710
|
+
boxShadow: `3px 3px 0 0 ${C13.border}`,
|
|
19915
20711
|
padding: isDesktop ? 20 : 14,
|
|
19916
20712
|
maxWidth: isDesktop ? 650 : 380,
|
|
19917
20713
|
overflow: "hidden"
|
|
@@ -19974,7 +20770,7 @@ function SerpPreview({
|
|
|
19974
20770
|
style: {
|
|
19975
20771
|
fontSize: 14,
|
|
19976
20772
|
fontWeight: 400,
|
|
19977
|
-
color:
|
|
20773
|
+
color: C13.black,
|
|
19978
20774
|
lineHeight: 1.3,
|
|
19979
20775
|
whiteSpace: "nowrap",
|
|
19980
20776
|
overflow: "hidden",
|
|
@@ -20038,7 +20834,7 @@ function SerpPreview({
|
|
|
20038
20834
|
"span",
|
|
20039
20835
|
{
|
|
20040
20836
|
style: {
|
|
20041
|
-
color:
|
|
20837
|
+
color: C13.textSecondary,
|
|
20042
20838
|
fontStyle: "italic",
|
|
20043
20839
|
fontSize: titleFontSize - 2
|
|
20044
20840
|
},
|
|
@@ -20067,7 +20863,7 @@ function SerpPreview({
|
|
|
20067
20863
|
"span",
|
|
20068
20864
|
{
|
|
20069
20865
|
style: {
|
|
20070
|
-
color:
|
|
20866
|
+
color: C13.textSecondary,
|
|
20071
20867
|
fontStyle: "italic",
|
|
20072
20868
|
fontSize: descFontSize - 1
|
|
20073
20869
|
},
|
|
@@ -20100,7 +20896,7 @@ function SerpPreview({
|
|
|
20100
20896
|
fontSize: 11
|
|
20101
20897
|
},
|
|
20102
20898
|
children: [
|
|
20103
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color:
|
|
20899
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C13.textSecondary, fontWeight: 600 }, children: t.serpPreview.previewTitle }),
|
|
20104
20900
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
20105
20901
|
"span",
|
|
20106
20902
|
{
|
|
@@ -20129,7 +20925,7 @@ function SerpPreview({
|
|
|
20129
20925
|
fontSize: 11
|
|
20130
20926
|
},
|
|
20131
20927
|
children: [
|
|
20132
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color:
|
|
20928
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C13.textSecondary, fontWeight: 600 }, children: t.serpPreview.previewDescription }),
|
|
20133
20929
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
20134
20930
|
"span",
|
|
20135
20931
|
{
|
|
@@ -20158,14 +20954,14 @@ function SerpPreview({
|
|
|
20158
20954
|
fontSize: 11
|
|
20159
20955
|
},
|
|
20160
20956
|
children: [
|
|
20161
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color:
|
|
20957
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: C13.textSecondary, fontWeight: 600 }, children: t.serpPreview.url }),
|
|
20162
20958
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
20163
20959
|
"span",
|
|
20164
20960
|
{
|
|
20165
20961
|
style: {
|
|
20166
20962
|
fontWeight: 700,
|
|
20167
20963
|
fontVariantNumeric: "tabular-nums",
|
|
20168
|
-
color: fullUrl.length <= 75 ?
|
|
20964
|
+
color: fullUrl.length <= 75 ? C13.green : C13.red
|
|
20169
20965
|
},
|
|
20170
20966
|
children: [
|
|
20171
20967
|
fullUrl.length,
|
|
@@ -20200,13 +20996,13 @@ function DeviceButton({
|
|
|
20200
20996
|
gap: 5,
|
|
20201
20997
|
padding: "4px 12px",
|
|
20202
20998
|
borderRadius: 6,
|
|
20203
|
-
border: `2px solid ${
|
|
20999
|
+
border: `2px solid ${C13.border}`,
|
|
20204
21000
|
fontSize: 11,
|
|
20205
21001
|
fontWeight: 700,
|
|
20206
21002
|
cursor: "pointer",
|
|
20207
|
-
backgroundColor: active ?
|
|
20208
|
-
color: active ?
|
|
20209
|
-
boxShadow: active ? `2px 2px 0 0 ${
|
|
21003
|
+
backgroundColor: active ? C13.cyan : C13.surfaceBg,
|
|
21004
|
+
color: active ? C13.black : C13.textPrimary,
|
|
21005
|
+
boxShadow: active ? `2px 2px 0 0 ${C13.border}` : "none",
|
|
20210
21006
|
transition: "background-color 0.15s"
|
|
20211
21007
|
},
|
|
20212
21008
|
children: [
|