@focus-reactive/payload-plugin-seo 1.6.0 → 1.7.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 +13 -2
- package/dist/admin.css +200 -17
- package/dist/components/SeoButton/SeoButtonInner.d.ts.map +1 -1
- package/dist/components/SeoButton/SeoButtonInner.js +46 -16
- package/dist/components/SeoButton/SeoButtonInner.js.map +1 -1
- package/dist/components/SeoDrawer/build-analysis-input.d.ts +2 -2
- package/dist/components/SeoDrawer/build-analysis-input.d.ts.map +1 -1
- package/dist/components/SeoDrawer/build-analysis-input.js +1 -1
- package/dist/components/SeoDrawer/build-analysis-input.js.map +1 -1
- package/dist/components/SeoDrawer/buildInput.d.ts +3 -3
- package/dist/components/SeoDrawer/buildInput.d.ts.map +1 -1
- package/dist/components/SeoDrawer/buildInput.js +3 -2
- package/dist/components/SeoDrawer/buildInput.js.map +1 -1
- package/dist/components/SeoDrawer/components/SerpPreview/highlight-keyphrase.d.ts +1 -1
- package/dist/components/SeoDrawer/components/SerpPreview/highlight-keyphrase.d.ts.map +1 -1
- package/dist/components/SeoDrawer/components/SerpPreview/highlight-keyphrase.js +10 -3
- package/dist/components/SeoDrawer/components/SerpPreview/highlight-keyphrase.js.map +1 -1
- package/dist/components/SeoDrawer/components/SerpPreview/index.d.ts +2 -1
- package/dist/components/SeoDrawer/components/SerpPreview/index.d.ts.map +1 -1
- package/dist/components/SeoDrawer/components/SerpPreview/index.js +8 -2
- package/dist/components/SeoDrawer/components/SerpPreview/index.js.map +1 -1
- package/dist/components/SeoDrawer/components/SerpPreview/variants.d.ts +6 -6
- package/dist/components/SeoDrawer/components/TabWrapper.d.ts +6 -0
- package/dist/components/SeoDrawer/components/TabWrapper.d.ts.map +1 -0
- package/dist/components/SeoDrawer/components/TabWrapper.js +8 -0
- package/dist/components/SeoDrawer/components/TabWrapper.js.map +1 -0
- package/dist/components/SeoDrawer/index.d.ts +11 -4
- package/dist/components/SeoDrawer/index.d.ts.map +1 -1
- package/dist/components/SeoDrawer/index.js +38 -16
- package/dist/components/SeoDrawer/index.js.map +1 -1
- package/dist/components/SeoDrawer/keyphraseState.d.ts +16 -0
- package/dist/components/SeoDrawer/keyphraseState.d.ts.map +1 -0
- package/dist/components/SeoDrawer/keyphraseState.js +73 -0
- package/dist/components/SeoDrawer/keyphraseState.js.map +1 -0
- package/dist/components/SeoDrawer/keyphraseStorage.d.ts +5 -0
- package/dist/components/SeoDrawer/keyphraseStorage.d.ts.map +1 -0
- package/dist/components/SeoDrawer/keyphraseStorage.js +60 -0
- package/dist/components/SeoDrawer/keyphraseStorage.js.map +1 -0
- package/dist/components/SeoDrawer/tabs/InclusiveTab.d.ts.map +1 -1
- package/dist/components/SeoDrawer/tabs/InclusiveTab.js +3 -2
- package/dist/components/SeoDrawer/tabs/InclusiveTab.js.map +1 -1
- package/dist/components/SeoDrawer/tabs/KeyphraseTab.d.ts +14 -7
- package/dist/components/SeoDrawer/tabs/KeyphraseTab.d.ts.map +1 -1
- package/dist/components/SeoDrawer/tabs/KeyphraseTab.js +110 -69
- package/dist/components/SeoDrawer/tabs/KeyphraseTab.js.map +1 -1
- package/dist/components/SeoDrawer/tabs/OnPageTab.d.ts.map +1 -1
- package/dist/components/SeoDrawer/tabs/OnPageTab.js +3 -2
- package/dist/components/SeoDrawer/tabs/OnPageTab.js.map +1 -1
- package/dist/components/SeoDrawer/tabs/ReadabilityTab.d.ts.map +1 -1
- package/dist/components/SeoDrawer/tabs/ReadabilityTab.js +3 -2
- package/dist/components/SeoDrawer/tabs/ReadabilityTab.js.map +1 -1
- package/dist/components/SeoDrawer/tabs/SerpTab.d.ts +2 -1
- package/dist/components/SeoDrawer/tabs/SerpTab.d.ts.map +1 -1
- package/dist/components/SeoDrawer/tabs/SerpTab.js +14 -3
- package/dist/components/SeoDrawer/tabs/SerpTab.js.map +1 -1
- package/dist/components/SeoDrawer/tabs/VitalsTab.d.ts.map +1 -1
- package/dist/components/SeoDrawer/tabs/VitalsTab.js +7 -3
- package/dist/components/SeoDrawer/tabs/VitalsTab.js.map +1 -1
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseCard.d.ts +21 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseCard.d.ts.map +1 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseCard.js +38 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseCard.js.map +1 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseDetail.d.ts +25 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseDetail.d.ts.map +1 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseDetail.js +127 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseDetail.js.map +1 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseRail.d.ts +12 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseRail.d.ts.map +1 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseRail.js +54 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/KeyphraseRail.js.map +1 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/SynonymsField.d.ts +7 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/SynonymsField.d.ts.map +1 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/SynonymsField.js +93 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/SynonymsField.js.map +1 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/icons.d.ts +2 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/icons.d.ts.map +1 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/icons.js +7 -0
- package/dist/components/SeoDrawer/tabs/keyphrase/icons.js.map +1 -0
- package/dist/components/SeoDrawer/useAnalysis.d.ts +0 -1
- package/dist/components/SeoDrawer/useAnalysis.d.ts.map +1 -1
- package/dist/components/SeoDrawer/useAnalysis.js +0 -3
- package/dist/components/SeoDrawer/useAnalysis.js.map +1 -1
- package/dist/components/SeoDrawer/useKeyphrases.d.ts +18 -0
- package/dist/components/SeoDrawer/useKeyphrases.d.ts.map +1 -0
- package/dist/components/SeoDrawer/useKeyphrases.js +78 -0
- package/dist/components/SeoDrawer/useKeyphrases.js.map +1 -0
- package/dist/components/SeoDrawer/useLiveDocument.d.ts +4 -3
- package/dist/components/SeoDrawer/useLiveDocument.d.ts.map +1 -1
- package/dist/components/SeoDrawer/useLiveDocument.js +17 -9
- package/dist/components/SeoDrawer/useLiveDocument.js.map +1 -1
- package/dist/components/SeoDrawer/variants.d.ts +1 -1
- package/dist/components/SeoDrawer/variants.d.ts.map +1 -1
- package/dist/components/SeoDrawer/variants.js +2 -1
- package/dist/components/SeoDrawer/variants.js.map +1 -1
- package/dist/constants/generation.d.ts +1 -1
- package/dist/constants/generation.js +1 -1
- package/dist/constants/generation.js.map +1 -1
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +2 -0
- package/dist/constants/index.js.map +1 -1
- package/dist/engine/buildPaper.d.ts +2 -2
- package/dist/engine/buildPaper.d.ts.map +1 -1
- package/dist/engine/buildPaper.js +4 -2
- package/dist/engine/buildPaper.js.map +1 -1
- package/dist/engine/runAnalysis/index.d.ts.map +1 -1
- package/dist/engine/runAnalysis/index.js +7 -0
- package/dist/engine/runAnalysis/index.js.map +1 -1
- package/dist/engine/runAnalysis/services/derive-related.d.ts +4 -0
- package/dist/engine/runAnalysis/services/derive-related.d.ts.map +1 -0
- package/dist/engine/runAnalysis/services/derive-related.js +16 -0
- package/dist/engine/runAnalysis/services/derive-related.js.map +1 -0
- package/dist/engine/types/analysis.d.ts +11 -0
- package/dist/engine/types/analysis.d.ts.map +1 -1
- package/dist/ui/Button.d.ts +9 -0
- package/dist/ui/Button.d.ts.map +1 -0
- package/dist/ui/Button.js +34 -0
- package/dist/ui/Button.js.map +1 -0
- package/dist/ui/ScoreRing.d.ts +17 -4
- package/dist/ui/ScoreRing.d.ts.map +1 -1
- package/dist/ui/ScoreRing.js +38 -14
- package/dist/ui/ScoreRing.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/SeoDrawer/keyphrasePending.d.ts +0 -2
- package/dist/components/SeoDrawer/keyphrasePending.d.ts.map +0 -1
- package/dist/components/SeoDrawer/keyphrasePending.js +0 -9
- package/dist/components/SeoDrawer/keyphrasePending.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SeoButtonInner.d.ts","sourceRoot":"","sources":["../../../src/components/SeoButton/SeoButtonInner.tsx"],"names":[],"mappings":"AAWA,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAID,wBAAgB,cAAc,CAAC,EAC7B,cAAc,EACd,MAAM,EACN,IAAI,EACJ,gBAAgB,EAChB,kBAAkB,GACnB,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"SeoButtonInner.d.ts","sourceRoot":"","sources":["../../../src/components/SeoButton/SeoButtonInner.tsx"],"names":[],"mappings":"AAWA,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAID,wBAAgB,cAAc,CAAC,EAC7B,cAAc,EACd,MAAM,EACN,IAAI,EACJ,gBAAgB,EAChB,kBAAkB,GACnB,EAAE,cAAc,2CAqFhB"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Button, useModal } from "@payloadcms/ui";
|
|
3
|
+
import { Button, useDocumentInfo, useLocale, useModal } from "@payloadcms/ui";
|
|
4
4
|
import { Gauge } from "lucide-react";
|
|
5
5
|
import { useCallback, useState } from "react";
|
|
6
6
|
import { ScoreBadge } from "./ScoreBadge";
|
|
7
7
|
import { SeoDrawer } from "../SeoDrawer";
|
|
8
|
-
import { isKeyphrasePending } from "../SeoDrawer/keyphrasePending";
|
|
9
8
|
import { useAnalysis } from "../SeoDrawer/useAnalysis";
|
|
9
|
+
import { useKeyphrases } from "../SeoDrawer/useKeyphrases";
|
|
10
10
|
import { useLiveDocument } from "../SeoDrawer/useLiveDocument";
|
|
11
11
|
const DRAWER_SLUG = "seo-analytics-drawer";
|
|
12
12
|
function SeoButtonInner({
|
|
@@ -17,25 +17,49 @@ function SeoButtonInner({
|
|
|
17
17
|
extractContentPath
|
|
18
18
|
}) {
|
|
19
19
|
const { openModal } = useModal();
|
|
20
|
-
const
|
|
20
|
+
const { id } = useDocumentInfo();
|
|
21
|
+
const locale = useLocale();
|
|
22
|
+
const docId = id == null ? "" : String(id);
|
|
23
|
+
const localeCode = locale?.code ?? "en";
|
|
24
|
+
const {
|
|
25
|
+
addRelated,
|
|
26
|
+
addSynonym,
|
|
27
|
+
isDuplicate,
|
|
28
|
+
keyphrases,
|
|
29
|
+
remove: removeKeyphrase,
|
|
30
|
+
removeSynonym,
|
|
31
|
+
setFocus,
|
|
32
|
+
updateText
|
|
33
|
+
} = useKeyphrases({ collectionSlug, docId, localeCode });
|
|
34
|
+
const [selectedId, setSelectedId] = useState(null);
|
|
21
35
|
const { signature, getInput } = useLiveDocument({
|
|
22
36
|
collectionSlug,
|
|
23
37
|
fields,
|
|
24
|
-
site: {
|
|
25
|
-
|
|
38
|
+
site: {
|
|
39
|
+
name: site.name,
|
|
40
|
+
baseUrl: site.baseUrl
|
|
41
|
+
},
|
|
42
|
+
keyphrases,
|
|
26
43
|
extractContentPath
|
|
27
44
|
});
|
|
28
|
-
const { result, analyzing,
|
|
29
|
-
getInput,
|
|
30
|
-
signature,
|
|
31
|
-
supportedLocales
|
|
32
|
-
});
|
|
33
|
-
const keyphrasePending = isKeyphrasePending(keyphrase, analyzedKeyphrase);
|
|
45
|
+
const { result, analyzing, analyzeNow } = useAnalysis({ getInput, signature, supportedLocales });
|
|
34
46
|
const overall = result?.overall ?? null;
|
|
35
47
|
const open = useCallback(() => {
|
|
36
48
|
analyzeNow();
|
|
37
49
|
openModal(DRAWER_SLUG);
|
|
38
50
|
}, [analyzeNow, openModal]);
|
|
51
|
+
const handleAddRelated = useCallback(() => {
|
|
52
|
+
const newId = addRelated();
|
|
53
|
+
if (newId)
|
|
54
|
+
setSelectedId(newId);
|
|
55
|
+
}, [addRelated]);
|
|
56
|
+
const handleRemove = useCallback(
|
|
57
|
+
(id2) => {
|
|
58
|
+
removeKeyphrase(id2);
|
|
59
|
+
setSelectedId((current) => current === id2 ? null : current);
|
|
60
|
+
},
|
|
61
|
+
[removeKeyphrase]
|
|
62
|
+
);
|
|
39
63
|
return /* @__PURE__ */ jsxs("span", { className: "relative inline-flex", children: [
|
|
40
64
|
/* @__PURE__ */ jsx(
|
|
41
65
|
Button,
|
|
@@ -56,13 +80,19 @@ function SeoButtonInner({
|
|
|
56
80
|
/* @__PURE__ */ jsx(
|
|
57
81
|
SeoDrawer,
|
|
58
82
|
{
|
|
59
|
-
analyzeNow,
|
|
60
|
-
analyzing,
|
|
61
83
|
drawerSlug: DRAWER_SLUG,
|
|
62
|
-
|
|
63
|
-
|
|
84
|
+
keyphrases,
|
|
85
|
+
selectedId,
|
|
86
|
+
onSelect: setSelectedId,
|
|
64
87
|
result,
|
|
65
|
-
|
|
88
|
+
analyzing,
|
|
89
|
+
onAddRelated: handleAddRelated,
|
|
90
|
+
onTextChange: updateText,
|
|
91
|
+
onAddSynonym: addSynonym,
|
|
92
|
+
onRemoveSynonym: removeSynonym,
|
|
93
|
+
onRemove: handleRemove,
|
|
94
|
+
onSetFocus: setFocus,
|
|
95
|
+
isDuplicate,
|
|
66
96
|
site
|
|
67
97
|
}
|
|
68
98
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/SeoButton/SeoButtonInner.tsx"],"sourcesContent":["\"use client\";\n\nimport { Button, useModal } from \"@payloadcms/ui\";\nimport { Gauge } from \"lucide-react\";\nimport { useCallback, useState } from \"react\";\nimport { ScoreBadge } from \"./ScoreBadge\";\nimport { SeoDrawer } from \"../SeoDrawer\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/components/SeoButton/SeoButtonInner.tsx"],"sourcesContent":["\"use client\";\n\nimport { Button, useDocumentInfo, useLocale, useModal } from \"@payloadcms/ui\";\nimport { Gauge } from \"lucide-react\";\nimport { useCallback, useState } from \"react\";\nimport { ScoreBadge } from \"./ScoreBadge\";\nimport { SeoDrawer } from \"../SeoDrawer\";\nimport { useAnalysis } from \"../SeoDrawer/useAnalysis\";\nimport { useKeyphrases } from \"../SeoDrawer/useKeyphrases\";\nimport { useLiveDocument } from \"../SeoDrawer/useLiveDocument\";\n\nexport interface SeoButtonProps {\n collectionSlug: string;\n fields: Record<string, string>;\n extractContentPath: string;\n site: { name: string; baseUrl: string; faviconUrl: string };\n supportedLocales: string[];\n}\n\nconst DRAWER_SLUG = \"seo-analytics-drawer\";\n\nexport function SeoButtonInner({\n collectionSlug,\n fields,\n site,\n supportedLocales,\n extractContentPath,\n}: SeoButtonProps) {\n const { openModal } = useModal();\n const { id } = useDocumentInfo();\n const locale = useLocale();\n\n const docId = id == null ? \"\" : String(id);\n const localeCode = locale?.code ?? \"en\";\n\n const {\n addRelated,\n addSynonym,\n isDuplicate,\n keyphrases,\n remove: removeKeyphrase,\n removeSynonym,\n setFocus,\n updateText,\n } = useKeyphrases({ collectionSlug, docId, localeCode });\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const { signature, getInput } = useLiveDocument({\n collectionSlug,\n fields,\n site: {\n name: site.name,\n baseUrl: site.baseUrl,\n },\n keyphrases,\n extractContentPath,\n });\n const { result, analyzing, analyzeNow } = useAnalysis({ getInput, signature, supportedLocales });\n\n const overall = result?.overall ?? null;\n\n const open = useCallback(() => {\n analyzeNow();\n openModal(DRAWER_SLUG);\n }, [analyzeNow, openModal]);\n\n const handleAddRelated = useCallback(() => {\n const newId = addRelated();\n if (newId) setSelectedId(newId);\n }, [addRelated]);\n\n const handleRemove = useCallback(\n (id: string) => {\n removeKeyphrase(id);\n setSelectedId((current) => (current === id ? null : current));\n },\n [removeKeyphrase]\n );\n\n return (\n <span className=\"relative inline-flex\">\n <Button\n aria-label=\"SEO Analytics\"\n buttonStyle=\"none\"\n className=\"seo-doc-btn m-0 w-[calc(var(--base)*1.6)] h-[calc(var(--base)*1.6)] inline-flex items-center justify-center border border-[var(--theme-elevation-100)] rounded-rs bg-transparent text-neutral-800 transition-[border-color,background-color] duration-100 hover:border-neutral-300 hover:bg-neutral-100\"\n extraButtonProps={{ title: undefined }}\n icon={<Gauge />}\n iconStyle=\"without-border\"\n margin={false}\n onClick={open}\n size=\"small\"\n tooltip=\"SEO Analytics\"\n />\n {overall && <ScoreBadge score={overall.seoScore} status={overall.status} />}\n\n <SeoDrawer\n drawerSlug={DRAWER_SLUG}\n keyphrases={keyphrases}\n selectedId={selectedId}\n onSelect={setSelectedId}\n result={result}\n analyzing={analyzing}\n onAddRelated={handleAddRelated}\n onTextChange={updateText}\n onAddSynonym={addSynonym}\n onRemoveSynonym={removeSynonym}\n onRemove={handleRemove}\n onSetFocus={setFocus}\n isDuplicate={isDuplicate}\n site={site}\n />\n </span>\n );\n}\n"],"mappings":";AA+EI,SAMU,KANV;AA7EJ,SAAS,QAAQ,iBAAiB,WAAW,gBAAgB;AAC7D,SAAS,aAAa;AACtB,SAAS,aAAa,gBAAgB;AACtC,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAUhC,MAAM,cAAc;AAEb,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,QAAM,EAAE,UAAU,IAAI,SAAS;AAC/B,QAAM,EAAE,GAAG,IAAI,gBAAgB;AAC/B,QAAM,SAAS,UAAU;AAEzB,QAAM,QAAQ,MAAM,OAAO,KAAK,OAAO,EAAE;AACzC,QAAM,aAAa,QAAQ,QAAQ;AAEnC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,cAAc,EAAE,gBAAgB,OAAO,WAAW,CAAC;AACvD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAwB,IAAI;AAChE,QAAM,EAAE,WAAW,SAAS,IAAI,gBAAgB;AAAA,IAC9C;AAAA,IACA;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,EAAE,QAAQ,WAAW,WAAW,IAAI,YAAY,EAAE,UAAU,WAAW,iBAAiB,CAAC;AAE/F,QAAM,UAAU,QAAQ,WAAW;AAEnC,QAAM,OAAO,YAAY,MAAM;AAC7B,eAAW;AACX,cAAU,WAAW;AAAA,EACvB,GAAG,CAAC,YAAY,SAAS,CAAC;AAE1B,QAAM,mBAAmB,YAAY,MAAM;AACzC,UAAM,QAAQ,WAAW;AACzB,QAAI;AAAO,oBAAc,KAAK;AAAA,EAChC,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,eAAe;AAAA,IACnB,CAACA,QAAe;AACd,sBAAgBA,GAAE;AAClB,oBAAc,CAAC,YAAa,YAAYA,MAAK,OAAO,OAAQ;AAAA,IAC9D;AAAA,IACA,CAAC,eAAe;AAAA,EAClB;AAEA,SACE,qBAAC,UAAK,WAAU,wBACd;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,cAAW;AAAA,QACX,aAAY;AAAA,QACZ,WAAU;AAAA,QACV,kBAAkB,EAAE,OAAO,OAAU;AAAA,QACrC,MAAM,oBAAC,SAAM;AAAA,QACb,WAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,MAAK;AAAA,QACL,SAAQ;AAAA;AAAA,IACV;AAAA,IACC,WAAW,oBAAC,cAAW,OAAO,QAAQ,UAAU,QAAQ,QAAQ,QAAQ;AAAA,IAEzE;AAAA,MAAC;AAAA;AAAA,QACC,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA,cAAc;AAAA,QACd,cAAc;AAAA,QACd,cAAc;AAAA,QACd,iBAAiB;AAAA,QACjB,UAAU;AAAA,QACV,YAAY;AAAA,QACZ;AAAA,QACA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":["id"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnalysisInput } from "../../engine/types/analysis";
|
|
1
|
+
import type { AnalysisInput, KeyphraseInput } from "../../engine/types/analysis";
|
|
2
2
|
import type { ContentExtractor, SeoFieldPaths } from "../../types/config";
|
|
3
3
|
export interface BuildAnalysisInputArgs {
|
|
4
4
|
values: Record<string, unknown>;
|
|
@@ -7,7 +7,7 @@ export interface BuildAnalysisInputArgs {
|
|
|
7
7
|
} | null | undefined;
|
|
8
8
|
payloadLocale: string | undefined;
|
|
9
9
|
apiRoute?: string;
|
|
10
|
-
|
|
10
|
+
keyphrases: KeyphraseInput[];
|
|
11
11
|
fields: SeoFieldPaths;
|
|
12
12
|
site: {
|
|
13
13
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-analysis-input.d.ts","sourceRoot":"","sources":["../../../src/components/SeoDrawer/build-analysis-input.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"build-analysis-input.d.ts","sourceRoot":"","sources":["../../../src/components/SeoDrawer/build-analysis-input.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AACjF,OAAO,KAAK,EACV,gBAAgB,EAIhB,aAAa,EACd,MAAM,oBAAoB,CAAC;AAK5B,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,aAAa,CAAC,CAY7F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/SeoDrawer/build-analysis-input.ts"],"sourcesContent":["import type { ContentNode } from \"../../content/schema/nodes\";\nimport { serialize } from \"../../content/schema/serialize\";\nimport {\n compact,\n heading,\n html,\n image,\n link,\n paragraph,\n richText,\n video,\n} from \"../../content/schema/helpers\";\nimport { createResolveDocs } from \"../../content/resolve/resolve-docs\";\nimport type { AnalysisInput } from \"../../engine/types/analysis\";\nimport type {\n ContentExtractor,\n ContentHelpers,\n ExtractContext,\n ExtractToolkit,\n SeoFieldPaths,\n} from \"../../types/config\";\nimport { buildInput } from \"./buildInput\";\n\nconst helpers: ContentHelpers = { heading, paragraph, link, image, video, html, richText, compact };\n\nexport interface BuildAnalysisInputArgs {\n values: Record<string, unknown>;\n locale: string | { code?: string } | null | undefined;\n payloadLocale: string | undefined;\n apiRoute?: string;\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/SeoDrawer/build-analysis-input.ts"],"sourcesContent":["import type { ContentNode } from \"../../content/schema/nodes\";\nimport { serialize } from \"../../content/schema/serialize\";\nimport {\n compact,\n heading,\n html,\n image,\n link,\n paragraph,\n richText,\n video,\n} from \"../../content/schema/helpers\";\nimport { createResolveDocs } from \"../../content/resolve/resolve-docs\";\nimport type { AnalysisInput, KeyphraseInput } from \"../../engine/types/analysis\";\nimport type {\n ContentExtractor,\n ContentHelpers,\n ExtractContext,\n ExtractToolkit,\n SeoFieldPaths,\n} from \"../../types/config\";\nimport { buildInput } from \"./buildInput\";\n\nconst helpers: ContentHelpers = { heading, paragraph, link, image, video, html, richText, compact };\n\nexport interface BuildAnalysisInputArgs {\n values: Record<string, unknown>;\n locale: string | { code?: string } | null | undefined;\n payloadLocale: string | undefined;\n apiRoute?: string;\n keyphrases: KeyphraseInput[];\n fields: SeoFieldPaths;\n site: { name: string; baseUrl: string };\n extractor?: ContentExtractor;\n}\n\nexport async function buildAnalysisInput(args: BuildAnalysisInputArgs): Promise<AnalysisInput> {\n const ir = await extractIntermediateRepresentation(args);\n const contentHtml = serialize(ir);\n\n return buildInput({\n values: args.values,\n contentHtml,\n locale: args.locale,\n keyphrases: args.keyphrases,\n fields: args.fields,\n site: args.site,\n });\n}\n\nasync function extractIntermediateRepresentation(\n args: BuildAnalysisInputArgs\n): Promise<ContentNode[]> {\n if (!args.extractor) return [];\n\n const ctx: ExtractContext = {\n locale: args.payloadLocale,\n apiRoute: args.apiRoute,\n };\n\n const toolkit: ExtractToolkit = {\n resolveDocs: createResolveDocs(args.apiRoute, args.payloadLocale),\n helpers,\n };\n\n return await args.extractor(args.values, ctx, toolkit);\n}\n"],"mappings":"AACA,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AASlC,SAAS,kBAAkB;AAE3B,MAAM,UAA0B,EAAE,SAAS,WAAW,MAAM,OAAO,OAAO,MAAM,UAAU,QAAQ;AAalG,eAAsB,mBAAmB,MAAsD;AAC7F,QAAM,KAAK,MAAM,kCAAkC,IAAI;AACvD,QAAM,cAAc,UAAU,EAAE;AAEhC,SAAO,WAAW;AAAA,IAChB,QAAQ,KAAK;AAAA,IACb;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,YAAY,KAAK;AAAA,IACjB,QAAQ,KAAK;AAAA,IACb,MAAM,KAAK;AAAA,EACb,CAAC;AACH;AAEA,eAAe,kCACb,MACwB;AACxB,MAAI,CAAC,KAAK;AAAW,WAAO,CAAC;AAE7B,QAAM,MAAsB;AAAA,IAC1B,QAAQ,KAAK;AAAA,IACb,UAAU,KAAK;AAAA,EACjB;AAEA,QAAM,UAA0B;AAAA,IAC9B,aAAa,kBAAkB,KAAK,UAAU,KAAK,aAAa;AAAA,IAChE;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,UAAU,KAAK,QAAQ,KAAK,OAAO;AACvD;","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnalysisInput } from "../../engine/types/analysis";
|
|
1
|
+
import type { AnalysisInput, KeyphraseInput } from "../../engine/types/analysis";
|
|
2
2
|
import type { SeoFieldPaths } from "../../types/config";
|
|
3
3
|
export interface BuildInputArgs {
|
|
4
4
|
values: Record<string, unknown>;
|
|
@@ -6,12 +6,12 @@ export interface BuildInputArgs {
|
|
|
6
6
|
locale: string | {
|
|
7
7
|
code?: string;
|
|
8
8
|
} | null | undefined;
|
|
9
|
-
|
|
9
|
+
keyphrases: KeyphraseInput[];
|
|
10
10
|
fields: SeoFieldPaths;
|
|
11
11
|
site: {
|
|
12
12
|
name: string;
|
|
13
13
|
baseUrl: string;
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
|
-
export declare function buildInput({ values, contentHtml, locale,
|
|
16
|
+
export declare function buildInput({ values, contentHtml, locale, keyphrases, fields, site, }: BuildInputArgs): AnalysisInput;
|
|
17
17
|
//# sourceMappingURL=buildInput.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildInput.d.ts","sourceRoot":"","sources":["../../../src/components/SeoDrawer/buildInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"buildInput.d.ts","sourceRoot":"","sources":["../../../src/components/SeoDrawer/buildInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA2BxD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC;AAED,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,WAAW,EACX,MAAM,EACN,UAAU,EACV,MAAM,EACN,IAAI,GACL,EAAE,cAAc,GAAG,aAAa,CAmBhC"}
|
|
@@ -15,7 +15,7 @@ function buildInput({
|
|
|
15
15
|
values,
|
|
16
16
|
contentHtml,
|
|
17
17
|
locale,
|
|
18
|
-
|
|
18
|
+
keyphrases,
|
|
19
19
|
fields,
|
|
20
20
|
site
|
|
21
21
|
}) {
|
|
@@ -25,7 +25,8 @@ function buildInput({
|
|
|
25
25
|
slug: valueAt(values, fields.slug ?? "slug"),
|
|
26
26
|
description: valueAt(values, fields.metaDescription),
|
|
27
27
|
contentHtml,
|
|
28
|
-
keyphrase,
|
|
28
|
+
keyphrase: keyphrases[0]?.text ?? "",
|
|
29
|
+
keyphrases,
|
|
29
30
|
locale: normalizeLocale(locale),
|
|
30
31
|
site,
|
|
31
32
|
has: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/SeoDrawer/buildInput.ts"],"sourcesContent":["import type { AnalysisInput } from \"../../engine/types/analysis\";\nimport type { SeoFieldPaths } from \"../../types/config\";\n\nfunction valueAt(values: Record<string, unknown>, path?: string): string {\n if (!path) return \"\";\n\n const v = path\n .split(\".\")\n .reduce<unknown>(\n (acc, k) =>\n acc && typeof acc === \"object\" ? (acc as Record<string, unknown>)[k] : undefined,\n values\n );\n\n return typeof v === \"string\" ? v : \"\";\n}\n\nfunction normalizeLocale(locale: string | { code?: string } | null | undefined): string {\n const code =\n (typeof locale === \"object\" && locale\n ? locale.code\n : locale != null\n ? String(locale)\n : undefined) ?? \"en\";\n\n return code.includes(\"_\") ? code : `${code}_${code.toUpperCase()}`;\n}\n\nexport interface BuildInputArgs {\n values: Record<string, unknown>;\n contentHtml: string;\n locale: string | { code?: string } | null | undefined;\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/SeoDrawer/buildInput.ts"],"sourcesContent":["import type { AnalysisInput, KeyphraseInput } from \"../../engine/types/analysis\";\nimport type { SeoFieldPaths } from \"../../types/config\";\n\nfunction valueAt(values: Record<string, unknown>, path?: string): string {\n if (!path) return \"\";\n\n const v = path\n .split(\".\")\n .reduce<unknown>(\n (acc, k) =>\n acc && typeof acc === \"object\" ? (acc as Record<string, unknown>)[k] : undefined,\n values\n );\n\n return typeof v === \"string\" ? v : \"\";\n}\n\nfunction normalizeLocale(locale: string | { code?: string } | null | undefined): string {\n const code =\n (typeof locale === \"object\" && locale\n ? locale.code\n : locale != null\n ? String(locale)\n : undefined) ?? \"en\";\n\n return code.includes(\"_\") ? code : `${code}_${code.toUpperCase()}`;\n}\n\nexport interface BuildInputArgs {\n values: Record<string, unknown>;\n contentHtml: string;\n locale: string | { code?: string } | null | undefined;\n keyphrases: KeyphraseInput[];\n fields: SeoFieldPaths;\n site: { name: string; baseUrl: string };\n}\n\nexport function buildInput({\n values,\n contentHtml,\n locale,\n keyphrases,\n fields,\n site,\n}: BuildInputArgs): AnalysisInput {\n const title = valueAt(values, fields.seoTitle) || valueAt(values, \"title\");\n\n return {\n title,\n slug: valueAt(values, fields.slug ?? \"slug\"),\n description: valueAt(values, fields.metaDescription),\n contentHtml,\n keyphrase: keyphrases[0]?.text ?? \"\",\n keyphrases,\n locale: normalizeLocale(locale),\n site,\n has: {\n seoTitle: Boolean(fields.seoTitle && valueAt(values, fields.seoTitle)),\n metaDescription: Boolean(fields.metaDescription),\n slug: Boolean(fields.slug ?? \"slug\"),\n content: contentHtml.trim().length > 0,\n },\n };\n}\n"],"mappings":"AAGA,SAAS,QAAQ,QAAiC,MAAuB;AACvE,MAAI,CAAC;AAAM,WAAO;AAElB,QAAM,IAAI,KACP,MAAM,GAAG,EACT;AAAA,IACC,CAAC,KAAK,MACJ,OAAO,OAAO,QAAQ,WAAY,IAAgC,CAAC,IAAI;AAAA,IACzE;AAAA,EACF;AAEF,SAAO,OAAO,MAAM,WAAW,IAAI;AACrC;AAEA,SAAS,gBAAgB,QAA+D;AACtF,QAAM,QACH,OAAO,WAAW,YAAY,SAC3B,OAAO,OACP,UAAU,OACR,OAAO,MAAM,IACb,WAAc;AAEtB,SAAO,KAAK,SAAS,GAAG,IAAI,OAAO,GAAG,IAAI,IAAI,KAAK,YAAY,CAAC;AAClE;AAWO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAkC;AAChC,QAAM,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,KAAK,QAAQ,QAAQ,OAAO;AAEzE,SAAO;AAAA,IACL;AAAA,IACA,MAAM,QAAQ,QAAQ,OAAO,QAAQ,MAAM;AAAA,IAC3C,aAAa,QAAQ,QAAQ,OAAO,eAAe;AAAA,IACnD;AAAA,IACA,WAAW,WAAW,CAAC,GAAG,QAAQ;AAAA,IAClC;AAAA,IACA,QAAQ,gBAAgB,MAAM;AAAA,IAC9B;AAAA,IACA,KAAK;AAAA,MACH,UAAU,QAAQ,OAAO,YAAY,QAAQ,QAAQ,OAAO,QAAQ,CAAC;AAAA,MACrE,iBAAiB,QAAQ,OAAO,eAAe;AAAA,MAC/C,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,MACnC,SAAS,YAAY,KAAK,EAAE,SAAS;AAAA,IACvC;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
export declare function highlightKeyphrase(text: string, keyphrase: string): ReactNode[];
|
|
2
|
+
export declare function highlightKeyphrase(text: string, keyphrase: string, synonyms?: string[]): ReactNode[];
|
|
3
3
|
//# sourceMappingURL=highlight-keyphrase.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"highlight-keyphrase.d.ts","sourceRoot":"","sources":["../../../../../src/components/SeoDrawer/components/SerpPreview/highlight-keyphrase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"highlight-keyphrase.d.ts","sourceRoot":"","sources":["../../../../../src/components/SeoDrawer/components/SerpPreview/highlight-keyphrase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAkBvC,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,MAAM,EAAO,GACtB,SAAS,EAAE,CASb"}
|
|
@@ -2,10 +2,17 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
function escapeRegex(value) {
|
|
3
3
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4
4
|
}
|
|
5
|
-
function
|
|
6
|
-
|
|
5
|
+
function buildHighlightPattern(keyphrase, synonyms) {
|
|
6
|
+
const terms = [keyphrase, ...synonyms].map((term) => term.trim()).filter((term) => term.length > 0).sort((a, b) => b.length - a.length).map(escapeRegex);
|
|
7
|
+
if (terms.length === 0)
|
|
8
|
+
return null;
|
|
9
|
+
return terms.join("|");
|
|
10
|
+
}
|
|
11
|
+
function highlightKeyphrase(text, keyphrase, synonyms = []) {
|
|
12
|
+
const pattern = buildHighlightPattern(keyphrase, synonyms);
|
|
13
|
+
if (!pattern)
|
|
7
14
|
return [text];
|
|
8
|
-
const segments = text.split(new RegExp(`(${
|
|
15
|
+
const segments = text.split(new RegExp(`(${pattern})`, "gi"));
|
|
9
16
|
return segments.map(
|
|
10
17
|
(segment, index) => index % 2 === 1 ? /* @__PURE__ */ jsx("strong", { children: segment }, index) : segment
|
|
11
18
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/SeoDrawer/components/SerpPreview/highlight-keyphrase.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nexport function highlightKeyphrase(text: string
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/SeoDrawer/components/SerpPreview/highlight-keyphrase.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction buildHighlightPattern(keyphrase: string, synonyms: string[]): string | null {\n const terms = [keyphrase, ...synonyms]\n .map((term) => term.trim())\n .filter((term) => term.length > 0)\n .sort((a, b) => b.length - a.length)\n .map(escapeRegex);\n\n if (terms.length === 0) return null;\n\n return terms.join(\"|\");\n}\n\nexport function highlightKeyphrase(\n text: string,\n keyphrase: string,\n synonyms: string[] = []\n): ReactNode[] {\n const pattern = buildHighlightPattern(keyphrase, synonyms);\n if (!pattern) return [text];\n\n const segments = text.split(new RegExp(`(${pattern})`, \"gi\"));\n\n return segments.map((segment, index) =>\n index % 2 === 1 ? <strong key={index}>{segment}</strong> : segment\n );\n}\n"],"mappings":"AA6BsB;AA3BtB,SAAS,YAAY,OAAuB;AAC1C,SAAO,MAAM,QAAQ,uBAAuB,MAAM;AACpD;AAEA,SAAS,sBAAsB,WAAmB,UAAmC;AACnF,QAAM,QAAQ,CAAC,WAAW,GAAG,QAAQ,EAClC,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAClC,IAAI,WAAW;AAElB,MAAI,MAAM,WAAW;AAAG,WAAO;AAE/B,SAAO,MAAM,KAAK,GAAG;AACvB;AAEO,SAAS,mBACd,MACA,WACA,WAAqB,CAAC,GACT;AACb,QAAM,UAAU,sBAAsB,WAAW,QAAQ;AACzD,MAAI,CAAC;AAAS,WAAO,CAAC,IAAI;AAE1B,QAAM,WAAW,KAAK,MAAM,IAAI,OAAO,IAAI,OAAO,KAAK,IAAI,CAAC;AAE5D,SAAO,SAAS;AAAA,IAAI,CAAC,SAAS,UAC5B,QAAQ,MAAM,IAAI,oBAAC,YAAoB,qBAAR,KAAgB,IAAY;AAAA,EAC7D;AACF;","names":[]}
|
|
@@ -4,9 +4,10 @@ export type SerpMode = "mobile" | "desktop";
|
|
|
4
4
|
interface SerpPreviewProps {
|
|
5
5
|
data: SerpResult;
|
|
6
6
|
keyphrase: string;
|
|
7
|
+
synonyms?: string[];
|
|
7
8
|
faviconUrl: string;
|
|
8
9
|
mode: SerpMode;
|
|
9
10
|
}
|
|
10
|
-
export declare function SerpPreview({ data, keyphrase, faviconUrl, mode }: SerpPreviewProps): ReactElement;
|
|
11
|
+
export declare function SerpPreview({ data, keyphrase, synonyms, faviconUrl, mode, }: SerpPreviewProps): ReactElement;
|
|
11
12
|
export {};
|
|
12
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/SeoDrawer/components/SerpPreview/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAapE,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE5C,UAAU,gBAAgB;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/SeoDrawer/components/SerpPreview/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAapE,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE5C,UAAU,gBAAgB;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,SAAS,EACT,QAAa,EACb,UAAU,EACV,IAAI,GACL,EAAE,gBAAgB,GAAG,YAAY,CAqBjC"}
|
|
@@ -10,7 +10,13 @@ import {
|
|
|
10
10
|
serpUrlRow
|
|
11
11
|
} from "./variants";
|
|
12
12
|
import { truncateDescription } from "./truncate-description";
|
|
13
|
-
function SerpPreview({
|
|
13
|
+
function SerpPreview({
|
|
14
|
+
data,
|
|
15
|
+
keyphrase,
|
|
16
|
+
synonyms = [],
|
|
17
|
+
faviconUrl,
|
|
18
|
+
mode
|
|
19
|
+
}) {
|
|
14
20
|
const result = /* @__PURE__ */ jsxs("div", { className: serpContainer({ mode }), children: [
|
|
15
21
|
/* @__PURE__ */ jsxs("div", { className: serpUrlRow({ mode }), children: [
|
|
16
22
|
/* @__PURE__ */ jsx(SerpFavicon, { faviconUrl, siteName: data.siteName }),
|
|
@@ -20,7 +26,7 @@ function SerpPreview({ data, keyphrase, faviconUrl, mode }) {
|
|
|
20
26
|
] })
|
|
21
27
|
] }),
|
|
22
28
|
/* @__PURE__ */ jsx("div", { className: serpTitle({ mode }), children: data.title }),
|
|
23
|
-
/* @__PURE__ */ jsx("div", { className: serpDescription({ mode }), children: highlightKeyphrase(truncateDescription(data.description), keyphrase) })
|
|
29
|
+
/* @__PURE__ */ jsx("div", { className: serpDescription({ mode }), children: highlightKeyphrase(truncateDescription(data.description), keyphrase, synonyms) })
|
|
24
30
|
] });
|
|
25
31
|
return mode === "desktop" ? /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: result }) : result;
|
|
26
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/SeoDrawer/components/SerpPreview/index.tsx"],"sourcesContent":["import type { ReactElement } from \"react\";\nimport type { SerpResult } from \"../../../../engine/types/analysis\";\nimport { highlightKeyphrase } from \"./highlight-keyphrase\";\nimport { SerpFavicon } from \"./serp-favicon\";\nimport {\n serpContainer,\n serpDescription,\n serpHostname,\n serpSiteName,\n serpTitle,\n serpUrlRow,\n} from \"./variants\";\nimport { truncateDescription } from \"./truncate-description\";\n\nexport type SerpMode = \"mobile\" | \"desktop\";\n\ninterface SerpPreviewProps {\n data: SerpResult;\n keyphrase: string;\n faviconUrl: string;\n mode: SerpMode;\n}\n\nexport function SerpPreview({
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/SeoDrawer/components/SerpPreview/index.tsx"],"sourcesContent":["import type { ReactElement } from \"react\";\nimport type { SerpResult } from \"../../../../engine/types/analysis\";\nimport { highlightKeyphrase } from \"./highlight-keyphrase\";\nimport { SerpFavicon } from \"./serp-favicon\";\nimport {\n serpContainer,\n serpDescription,\n serpHostname,\n serpSiteName,\n serpTitle,\n serpUrlRow,\n} from \"./variants\";\nimport { truncateDescription } from \"./truncate-description\";\n\nexport type SerpMode = \"mobile\" | \"desktop\";\n\ninterface SerpPreviewProps {\n data: SerpResult;\n keyphrase: string;\n synonyms?: string[];\n faviconUrl: string;\n mode: SerpMode;\n}\n\nexport function SerpPreview({\n data,\n keyphrase,\n synonyms = [],\n faviconUrl,\n mode,\n}: SerpPreviewProps): ReactElement {\n const result = (\n <div className={serpContainer({ mode })}>\n <div className={serpUrlRow({ mode })}>\n <SerpFavicon faviconUrl={faviconUrl} siteName={data.siteName} />\n\n <div className=\"overflow-hidden\">\n <div className={serpSiteName({ mode })}>{data.siteName}</div>\n <div className={serpHostname({ mode })}>{data.url}</div>\n </div>\n </div>\n\n <div className={serpTitle({ mode })}>{data.title}</div>\n\n <div className={serpDescription({ mode })}>\n {highlightKeyphrase(truncateDescription(data.description), keyphrase, synonyms)}\n </div>\n </div>\n );\n\n return mode === \"desktop\" ? <div className=\"overflow-x-auto\">{result}</div> : result;\n}\n"],"mappings":"AAkCQ,cAEA,YAFA;AAhCR,SAAS,0BAA0B;AACnC,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,2BAA2B;AAY7B,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,WAAW,CAAC;AAAA,EACZ;AAAA,EACA;AACF,GAAmC;AACjC,QAAM,SACJ,qBAAC,SAAI,WAAW,cAAc,EAAE,KAAK,CAAC,GACpC;AAAA,yBAAC,SAAI,WAAW,WAAW,EAAE,KAAK,CAAC,GACjC;AAAA,0BAAC,eAAY,YAAwB,UAAU,KAAK,UAAU;AAAA,MAE9D,qBAAC,SAAI,WAAU,mBACb;AAAA,4BAAC,SAAI,WAAW,aAAa,EAAE,KAAK,CAAC,GAAI,eAAK,UAAS;AAAA,QACvD,oBAAC,SAAI,WAAW,aAAa,EAAE,KAAK,CAAC,GAAI,eAAK,KAAI;AAAA,SACpD;AAAA,OACF;AAAA,IAEA,oBAAC,SAAI,WAAW,UAAU,EAAE,KAAK,CAAC,GAAI,eAAK,OAAM;AAAA,IAEjD,oBAAC,SAAI,WAAW,gBAAgB,EAAE,KAAK,CAAC,GACrC,6BAAmB,oBAAoB,KAAK,WAAW,GAAG,WAAW,QAAQ,GAChF;AAAA,KACF;AAGF,SAAO,SAAS,YAAY,oBAAC,SAAI,WAAU,mBAAmB,kBAAO,IAAS;AAChF;","names":[]}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
export declare const serpContainer: (props?: ({
|
|
2
|
-
mode?: "
|
|
2
|
+
mode?: "mobile" | "desktop" | null | undefined;
|
|
3
3
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
4
4
|
export declare const serpUrlRow: (props?: ({
|
|
5
|
-
mode?: "
|
|
5
|
+
mode?: "mobile" | "desktop" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
export declare const serpSiteName: (props?: ({
|
|
8
|
-
mode?: "
|
|
8
|
+
mode?: "mobile" | "desktop" | null | undefined;
|
|
9
9
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
10
10
|
export declare const serpHostname: (props?: ({
|
|
11
|
-
mode?: "
|
|
11
|
+
mode?: "mobile" | "desktop" | null | undefined;
|
|
12
12
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
13
13
|
export declare const serpTitle: (props?: ({
|
|
14
|
-
mode?: "
|
|
14
|
+
mode?: "mobile" | "desktop" | null | undefined;
|
|
15
15
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
16
16
|
export declare const serpDescription: (props?: ({
|
|
17
|
-
mode?: "
|
|
17
|
+
mode?: "mobile" | "desktop" | null | undefined;
|
|
18
18
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
19
19
|
//# sourceMappingURL=variants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabWrapper.d.ts","sourceRoot":"","sources":["../../../../src/components/SeoDrawer/components/TabWrapper.tsx"],"names":[],"mappings":"AAAA,UAAU,eAAe;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE,eAAe,2CAEvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/SeoDrawer/components/TabWrapper.tsx"],"sourcesContent":["interface TabWrapperProps {\n children: React.ReactNode;\n}\n\nexport function TabWrapper({ children }: TabWrapperProps) {\n return <div className=\"py-[18px]\">{children}</div>;\n}\n"],"mappings":"AAKS;AADF,SAAS,WAAW,EAAE,SAAS,GAAoB;AACxD,SAAO,oBAAC,SAAI,WAAU,aAAa,UAAS;AAC9C;","names":[]}
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import type { AnalysisResult } from "../../engine/types/analysis";
|
|
2
|
+
import type { KeyphraseEntry } from "./keyphraseState";
|
|
2
3
|
import "../../admin.css";
|
|
3
4
|
export interface SeoDrawerProps {
|
|
4
5
|
drawerSlug: string;
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
keyphrases: KeyphraseEntry[];
|
|
7
|
+
selectedId: string | null;
|
|
8
|
+
onSelect: (id: string) => void;
|
|
7
9
|
result: AnalysisResult | null;
|
|
8
10
|
analyzing: boolean;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
onAddRelated: () => void;
|
|
12
|
+
onTextChange: (id: string, text: string) => void;
|
|
13
|
+
onAddSynonym: (id: string, syn: string) => void;
|
|
14
|
+
onRemoveSynonym: (id: string, index: number) => void;
|
|
15
|
+
onRemove: (id: string) => void;
|
|
16
|
+
onSetFocus: (id: string) => void;
|
|
17
|
+
isDuplicate: (id: string, text: string) => boolean;
|
|
11
18
|
site: {
|
|
12
19
|
name: string;
|
|
13
20
|
baseUrl: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SeoDrawer/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SeoDrawer/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,6BAA6B,CAAC;AAC/E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAWvD,OAAO,iBAAiB,CAAC;AAEzB,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACnD,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7D;AAED,eAAO,MAAM,SAAS,sDAiFpB,CAAC"}
|
|
@@ -14,17 +14,25 @@ import { VitalsTab } from "./tabs/VitalsTab";
|
|
|
14
14
|
import "../../admin.css";
|
|
15
15
|
const SeoDrawer = memo(function SeoDrawer2({
|
|
16
16
|
drawerSlug,
|
|
17
|
-
keyphrase,
|
|
18
|
-
setKeyphrase,
|
|
19
17
|
result,
|
|
18
|
+
site,
|
|
20
19
|
analyzing,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
isDuplicate,
|
|
21
|
+
keyphrases,
|
|
22
|
+
onAddRelated,
|
|
23
|
+
onAddSynonym,
|
|
24
|
+
onRemove,
|
|
25
|
+
onRemoveSynonym,
|
|
26
|
+
onSelect,
|
|
27
|
+
onSetFocus,
|
|
28
|
+
onTextChange,
|
|
29
|
+
selectedId
|
|
24
30
|
}) {
|
|
25
31
|
const [tab, setTab] = useState("keyphrase");
|
|
26
32
|
const total = result?.overall.seoScore ?? 0;
|
|
27
33
|
const totalStatus = result ? result.overall.status : "idle";
|
|
34
|
+
const focusKeyphrase = keyphrases[0]?.text ?? "";
|
|
35
|
+
const focusSynonyms = keyphrases[0]?.synonyms ?? [];
|
|
28
36
|
return /* @__PURE__ */ jsx(
|
|
29
37
|
Drawer,
|
|
30
38
|
{
|
|
@@ -33,7 +41,7 @@ const SeoDrawer = memo(function SeoDrawer2({
|
|
|
33
41
|
Header: /* @__PURE__ */ jsx(Header, { drawerSlug, total, totalStatus }),
|
|
34
42
|
children: /* @__PURE__ */ jsxs("div", { className: "seo-root relative text-neutral-800", "data-status": totalStatus, children: [
|
|
35
43
|
/* @__PURE__ */ jsx(TabsNav, { active: tab, onChange: setTab }),
|
|
36
|
-
/* @__PURE__ */ jsx("div", {
|
|
44
|
+
/* @__PURE__ */ jsx("div", { children: result === null && tab !== "keyphrase" ? /* @__PURE__ */ jsxs(
|
|
37
45
|
"div",
|
|
38
46
|
{
|
|
39
47
|
className: "flex items-center gap-[8px] text-neutral-500 text-[13px]",
|
|
@@ -48,19 +56,33 @@ const SeoDrawer = memo(function SeoDrawer2({
|
|
|
48
56
|
tab === "keyphrase" && /* @__PURE__ */ jsx(
|
|
49
57
|
KeyphraseTab,
|
|
50
58
|
{
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
keyphrases,
|
|
60
|
+
selectedId,
|
|
61
|
+
onSelect,
|
|
62
|
+
result,
|
|
54
63
|
analyzing,
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
onAddRelated,
|
|
65
|
+
onTextChange,
|
|
66
|
+
onAddSynonym,
|
|
67
|
+
onRemoveSynonym,
|
|
68
|
+
onRemove,
|
|
69
|
+
onSetFocus,
|
|
70
|
+
isDuplicate
|
|
57
71
|
}
|
|
58
72
|
),
|
|
59
|
-
tab === "onpage" && /* @__PURE__ */ jsx(OnPageTab, { data: result.onPage }),
|
|
60
|
-
tab === "readability" && /* @__PURE__ */ jsx(ReadabilityTab, { data: result.readability }),
|
|
61
|
-
tab === "inclusive" && /* @__PURE__ */ jsx(InclusiveTab, { data: result.inclusive }),
|
|
62
|
-
tab === "vitals" && /* @__PURE__ */ jsx(VitalsTab, { data: result.vitals, onRequestKeyphrase: () => setTab("keyphrase") }),
|
|
63
|
-
tab === "serp" && /* @__PURE__ */ jsx(
|
|
73
|
+
tab === "onpage" && result && /* @__PURE__ */ jsx(OnPageTab, { data: result.onPage }),
|
|
74
|
+
tab === "readability" && result && /* @__PURE__ */ jsx(ReadabilityTab, { data: result.readability }),
|
|
75
|
+
tab === "inclusive" && result && /* @__PURE__ */ jsx(InclusiveTab, { data: result.inclusive }),
|
|
76
|
+
tab === "vitals" && result && /* @__PURE__ */ jsx(VitalsTab, { data: result.vitals, onRequestKeyphrase: () => setTab("keyphrase") }),
|
|
77
|
+
tab === "serp" && result && /* @__PURE__ */ jsx(
|
|
78
|
+
SerpTab,
|
|
79
|
+
{
|
|
80
|
+
data: result.serp,
|
|
81
|
+
keyphrase: focusKeyphrase,
|
|
82
|
+
synonyms: focusSynonyms,
|
|
83
|
+
faviconUrl: site.faviconUrl
|
|
84
|
+
}
|
|
85
|
+
)
|
|
64
86
|
] }) })
|
|
65
87
|
] })
|
|
66
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/SeoDrawer/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { Drawer } from \"@payloadcms/ui\";\nimport { Loader2 } from \"lucide-react\";\nimport { memo, useState } from \"react\";\nimport type { AnalysisResult, TotalStatus } from \"../../engine/types/analysis\";\nimport { Header } from \"./components/Header\";\nimport { TabsNav } from \"./TabsNav\";\nimport type { TabKey } from \"./TabsNav\";\nimport { KeyphraseTab } from \"./tabs/KeyphraseTab\";\nimport { OnPageTab } from \"./tabs/OnPageTab\";\nimport { ReadabilityTab } from \"./tabs/ReadabilityTab\";\nimport { InclusiveTab } from \"./tabs/InclusiveTab\";\nimport { SerpTab } from \"./tabs/SerpTab\";\nimport { VitalsTab } from \"./tabs/VitalsTab\";\n\nimport \"../../admin.css\";\n\nexport interface SeoDrawerProps {\n drawerSlug: string;\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/SeoDrawer/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { Drawer } from \"@payloadcms/ui\";\nimport { Loader2 } from \"lucide-react\";\nimport { memo, useState } from \"react\";\nimport type { AnalysisResult, TotalStatus } from \"../../engine/types/analysis\";\nimport type { KeyphraseEntry } from \"./keyphraseState\";\nimport { Header } from \"./components/Header\";\nimport { TabsNav } from \"./TabsNav\";\nimport type { TabKey } from \"./TabsNav\";\nimport { KeyphraseTab } from \"./tabs/KeyphraseTab\";\nimport { OnPageTab } from \"./tabs/OnPageTab\";\nimport { ReadabilityTab } from \"./tabs/ReadabilityTab\";\nimport { InclusiveTab } from \"./tabs/InclusiveTab\";\nimport { SerpTab } from \"./tabs/SerpTab\";\nimport { VitalsTab } from \"./tabs/VitalsTab\";\n\nimport \"../../admin.css\";\n\nexport interface SeoDrawerProps {\n drawerSlug: string;\n keyphrases: KeyphraseEntry[];\n selectedId: string | null;\n onSelect: (id: string) => void;\n result: AnalysisResult | null;\n analyzing: boolean;\n onAddRelated: () => void;\n onTextChange: (id: string, text: string) => void;\n onAddSynonym: (id: string, syn: string) => void;\n onRemoveSynonym: (id: string, index: number) => void;\n onRemove: (id: string) => void;\n onSetFocus: (id: string) => void;\n isDuplicate: (id: string, text: string) => boolean;\n site: { name: string; baseUrl: string; faviconUrl: string };\n}\n\nexport const SeoDrawer = memo(function SeoDrawer({\n drawerSlug,\n result,\n site,\n analyzing,\n isDuplicate,\n keyphrases,\n onAddRelated,\n onAddSynonym,\n onRemove,\n onRemoveSynonym,\n onSelect,\n onSetFocus,\n onTextChange,\n selectedId,\n}: SeoDrawerProps) {\n const [tab, setTab] = useState<TabKey>(\"keyphrase\");\n\n const total = result?.overall.seoScore ?? 0;\n const totalStatus: TotalStatus = result ? result.overall.status : \"idle\";\n\n const focusKeyphrase = keyphrases[0]?.text ?? \"\";\n const focusSynonyms = keyphrases[0]?.synonyms ?? [];\n\n return (\n <Drawer\n slug={drawerSlug}\n className=\"seo-drawer\"\n Header={<Header drawerSlug={drawerSlug} total={total} totalStatus={totalStatus} />}\n >\n <div className=\"seo-root relative text-neutral-800\" data-status={totalStatus}>\n <TabsNav active={tab} onChange={setTab} />\n\n <div>\n {result === null && tab !== \"keyphrase\" ? (\n <div\n className=\"flex items-center gap-[8px] text-neutral-500 text-[13px]\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <Loader2 aria-hidden=\"true\" className=\"w-[14px] h-[14px] animate-spin\" />\n Analyzing…\n </div>\n ) : (\n <>\n {tab === \"keyphrase\" && (\n <KeyphraseTab\n keyphrases={keyphrases}\n selectedId={selectedId}\n onSelect={onSelect}\n result={result}\n analyzing={analyzing}\n onAddRelated={onAddRelated}\n onTextChange={onTextChange}\n onAddSynonym={onAddSynonym}\n onRemoveSynonym={onRemoveSynonym}\n onRemove={onRemove}\n onSetFocus={onSetFocus}\n isDuplicate={isDuplicate}\n />\n )}\n {tab === \"onpage\" && result && <OnPageTab data={result.onPage} />}\n {tab === \"readability\" && result && <ReadabilityTab data={result.readability} />}\n {tab === \"inclusive\" && result && <InclusiveTab data={result.inclusive} />}\n {tab === \"vitals\" && result && (\n <VitalsTab data={result.vitals} onRequestKeyphrase={() => setTab(\"keyphrase\")} />\n )}\n {tab === \"serp\" && result && (\n <SerpTab\n data={result.serp}\n keyphrase={focusKeyphrase}\n synonyms={focusSynonyms}\n faviconUrl={site.faviconUrl}\n />\n )}\n </>\n )}\n </div>\n </div>\n </Drawer>\n );\n});\n"],"mappings":";AAgEc,SAgBF,UAhBE,KAOF,YAPE;AA9Dd,SAAS,cAAc;AACvB,SAAS,eAAe;AACxB,SAAS,MAAM,gBAAgB;AAG/B,SAAS,cAAc;AACvB,SAAS,eAAe;AAExB,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAC1B,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AACxB,SAAS,iBAAiB;AAE1B,OAAO;AAmBA,MAAM,YAAY,KAAK,SAASA,WAAU;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,QAAM,CAAC,KAAK,MAAM,IAAI,SAAiB,WAAW;AAElD,QAAM,QAAQ,QAAQ,QAAQ,YAAY;AAC1C,QAAM,cAA2B,SAAS,OAAO,QAAQ,SAAS;AAElE,QAAM,iBAAiB,WAAW,CAAC,GAAG,QAAQ;AAC9C,QAAM,gBAAgB,WAAW,CAAC,GAAG,YAAY,CAAC;AAElD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,WAAU;AAAA,MACV,QAAQ,oBAAC,UAAO,YAAwB,OAAc,aAA0B;AAAA,MAEhF,+BAAC,SAAI,WAAU,sCAAqC,eAAa,aAC/D;AAAA,4BAAC,WAAQ,QAAQ,KAAK,UAAU,QAAQ;AAAA,QAExC,oBAAC,SACE,qBAAW,QAAQ,QAAQ,cAC1B;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAK;AAAA,YACL,aAAU;AAAA,YAEV;AAAA,kCAAC,WAAQ,eAAY,QAAO,WAAU,kCAAiC;AAAA,cAAE;AAAA;AAAA;AAAA,QAE3E,IAEA,iCACG;AAAA,kBAAQ,eACP;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA;AAAA,UACF;AAAA,UAED,QAAQ,YAAY,UAAU,oBAAC,aAAU,MAAM,OAAO,QAAQ;AAAA,UAC9D,QAAQ,iBAAiB,UAAU,oBAAC,kBAAe,MAAM,OAAO,aAAa;AAAA,UAC7E,QAAQ,eAAe,UAAU,oBAAC,gBAAa,MAAM,OAAO,WAAW;AAAA,UACvE,QAAQ,YAAY,UACnB,oBAAC,aAAU,MAAM,OAAO,QAAQ,oBAAoB,MAAM,OAAO,WAAW,GAAG;AAAA,UAEhF,QAAQ,UAAU,UACjB;AAAA,YAAC;AAAA;AAAA,cACC,MAAM,OAAO;AAAA,cACb,WAAW;AAAA,cACX,UAAU;AAAA,cACV,YAAY,KAAK;AAAA;AAAA,UACnB;AAAA,WAEJ,GAEJ;AAAA,SACF;AAAA;AAAA,EACF;AAEJ,CAAC;","names":["SeoDrawer"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface KeyphraseEntry {
|
|
2
|
+
id: string;
|
|
3
|
+
text: string;
|
|
4
|
+
synonyms: string[];
|
|
5
|
+
}
|
|
6
|
+
export declare function createEntry(text?: string, synonyms?: string[]): KeyphraseEntry;
|
|
7
|
+
export declare function firstEmptyId(list: KeyphraseEntry[]): string | undefined;
|
|
8
|
+
export declare function addRelated(list: KeyphraseEntry[]): KeyphraseEntry[];
|
|
9
|
+
export declare function updateText(list: KeyphraseEntry[], id: string, text: string): KeyphraseEntry[];
|
|
10
|
+
export declare function addSynonym(list: KeyphraseEntry[], id: string, syn: string): KeyphraseEntry[];
|
|
11
|
+
export declare function removeSynonym(list: KeyphraseEntry[], id: string, index: number): KeyphraseEntry[];
|
|
12
|
+
export declare function remove(list: KeyphraseEntry[], id: string): KeyphraseEntry[];
|
|
13
|
+
export declare function setFocus(list: KeyphraseEntry[], id: string): KeyphraseEntry[];
|
|
14
|
+
export declare function isDuplicate(list: KeyphraseEntry[], id: string, text: string): boolean;
|
|
15
|
+
export declare function pruneEmpties(list: KeyphraseEntry[]): KeyphraseEntry[];
|
|
16
|
+
//# sourceMappingURL=keyphraseState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyphraseState.d.ts","sourceRoot":"","sources":["../../../src/components/SeoDrawer/keyphraseState.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAUD,wBAAgB,WAAW,CAAC,IAAI,SAAK,EAAE,QAAQ,GAAE,MAAM,EAAO,GAAG,cAAc,CAM9E;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,MAAM,GAAG,SAAS,CAEvE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAKnE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAE7F;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,EAAE,CAS5F;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAIjG;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,cAAc,EAAE,CAE3E;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,cAAc,EAAE,CAK7E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKrF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAErE"}
|