@justanarthur/payload-plugin-seo 1.3.6
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 +16 -0
- package/dist/defaults.d.ts +11 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/exports/client.d.ts +6 -0
- package/dist/exports/client.d.ts.map +1 -0
- package/dist/exports/fields-components.d.ts +6 -0
- package/dist/exports/fields-components.d.ts.map +1 -0
- package/dist/exports/fields.d.ts +6 -0
- package/dist/exports/fields.d.ts.map +1 -0
- package/dist/exports/types.d.ts +2 -0
- package/dist/exports/types.d.ts.map +1 -0
- package/dist/fields/MetaDescription/MetaDescriptionComponent.d.ts +9 -0
- package/dist/fields/MetaDescription/MetaDescriptionComponent.d.ts.map +1 -0
- package/dist/fields/MetaDescription/index.d.ts +16 -0
- package/dist/fields/MetaDescription/index.d.ts.map +1 -0
- package/dist/fields/MetaImage/MetaImageComponent.d.ts +8 -0
- package/dist/fields/MetaImage/MetaImageComponent.d.ts.map +1 -0
- package/dist/fields/MetaImage/index.d.ts +13 -0
- package/dist/fields/MetaImage/index.d.ts.map +1 -0
- package/dist/fields/MetaTitle/MetaTitleComponent.d.ts +10 -0
- package/dist/fields/MetaTitle/MetaTitleComponent.d.ts.map +1 -0
- package/dist/fields/MetaTitle/index.d.ts +16 -0
- package/dist/fields/MetaTitle/index.d.ts.map +1 -0
- package/dist/fields/Overview/OverviewComponent.d.ts +18 -0
- package/dist/fields/Overview/OverviewComponent.d.ts.map +1 -0
- package/dist/fields/Overview/index.d.ts +34 -0
- package/dist/fields/Overview/index.d.ts.map +1 -0
- package/dist/fields/Preview/PreviewComponent.d.ts +9 -0
- package/dist/fields/Preview/PreviewComponent.d.ts.map +1 -0
- package/dist/fields/Preview/index.d.ts +24 -0
- package/dist/fields/Preview/index.d.ts.map +1 -0
- package/dist/fields/index.scss +7 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/openai/message.d.ts +7 -0
- package/dist/openai/message.d.ts.map +1 -0
- package/dist/src/defaults.js +12 -0
- package/dist/src/defaults.js.map +1 -0
- package/dist/src/exports/client.js +7 -0
- package/dist/src/exports/client.js.map +1 -0
- package/dist/src/exports/fields-components.js +7 -0
- package/dist/src/exports/fields-components.js.map +1 -0
- package/dist/src/exports/fields.js +7 -0
- package/dist/src/exports/fields.js.map +1 -0
- package/dist/src/exports/types.js +3 -0
- package/dist/src/exports/types.js.map +1 -0
- package/dist/src/fields/MetaDescription/MetaDescriptionComponent.js +224 -0
- package/dist/src/fields/MetaDescription/MetaDescriptionComponent.js.map +1 -0
- package/dist/src/fields/MetaDescription/index.js +22 -0
- package/dist/src/fields/MetaDescription/index.js.map +1 -0
- package/dist/src/fields/MetaImage/MetaImageComponent.js +173 -0
- package/dist/src/fields/MetaImage/MetaImageComponent.js.map +1 -0
- package/dist/src/fields/MetaImage/index.js +24 -0
- package/dist/src/fields/MetaImage/index.js.map +1 -0
- package/dist/src/fields/MetaTitle/MetaTitleComponent.js +225 -0
- package/dist/src/fields/MetaTitle/MetaTitleComponent.js.map +1 -0
- package/dist/src/fields/MetaTitle/index.js +22 -0
- package/dist/src/fields/MetaTitle/index.js.map +1 -0
- package/dist/src/fields/Overview/OverviewComponent.js +67 -0
- package/dist/src/fields/Overview/OverviewComponent.js.map +1 -0
- package/dist/src/fields/Overview/index.js +25 -0
- package/dist/src/fields/Overview/index.js.map +1 -0
- package/dist/src/fields/Preview/PreviewComponent.js +117 -0
- package/dist/src/fields/Preview/PreviewComponent.js.map +1 -0
- package/dist/src/fields/Preview/index.js +23 -0
- package/dist/src/fields/Preview/index.js.map +1 -0
- package/dist/src/index.js +309 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/openai/message.js +28 -0
- package/dist/src/openai/message.js.map +1 -0
- package/dist/src/translations/cs.js +26 -0
- package/dist/src/translations/cs.js.map +1 -0
- package/dist/src/translations/de.js +26 -0
- package/dist/src/translations/de.js.map +1 -0
- package/dist/src/translations/en.js +27 -0
- package/dist/src/translations/en.js.map +1 -0
- package/dist/src/translations/es.js +26 -0
- package/dist/src/translations/es.js.map +1 -0
- package/dist/src/translations/fa.js +26 -0
- package/dist/src/translations/fa.js.map +1 -0
- package/dist/src/translations/fr.js +26 -0
- package/dist/src/translations/fr.js.map +1 -0
- package/dist/src/translations/index.js +30 -0
- package/dist/src/translations/index.js.map +1 -0
- package/dist/src/translations/it.js +26 -0
- package/dist/src/translations/it.js.map +1 -0
- package/dist/src/translations/nb.js +26 -0
- package/dist/src/translations/nb.js.map +1 -0
- package/dist/src/translations/pl.js +26 -0
- package/dist/src/translations/pl.js.map +1 -0
- package/dist/src/translations/ru.js +26 -0
- package/dist/src/translations/ru.js.map +1 -0
- package/dist/src/translations/sv.js +26 -0
- package/dist/src/translations/sv.js.map +1 -0
- package/dist/src/translations/tr.js +26 -0
- package/dist/src/translations/tr.js.map +1 -0
- package/dist/src/translations/uk.js +26 -0
- package/dist/src/translations/uk.js.map +1 -0
- package/dist/src/translations/vi.js +26 -0
- package/dist/src/translations/vi.js.map +1 -0
- package/dist/src/types.js +3 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/ui/LengthIndicator.js +135 -0
- package/dist/src/ui/LengthIndicator.js.map +1 -0
- package/dist/src/ui/Pill.js +23 -0
- package/dist/src/ui/Pill.js.map +1 -0
- package/dist/translations/cs.d.ts +3 -0
- package/dist/translations/cs.d.ts.map +1 -0
- package/dist/translations/de.d.ts +3 -0
- package/dist/translations/de.d.ts.map +1 -0
- package/dist/translations/en.d.ts +3 -0
- package/dist/translations/en.d.ts.map +1 -0
- package/dist/translations/es.d.ts +3 -0
- package/dist/translations/es.d.ts.map +1 -0
- package/dist/translations/fa.d.ts +3 -0
- package/dist/translations/fa.d.ts.map +1 -0
- package/dist/translations/fr.d.ts +3 -0
- package/dist/translations/fr.d.ts.map +1 -0
- package/dist/translations/index.d.ts +19 -0
- package/dist/translations/index.d.ts.map +1 -0
- package/dist/translations/it.d.ts +3 -0
- package/dist/translations/it.d.ts.map +1 -0
- package/dist/translations/nb.d.ts +3 -0
- package/dist/translations/nb.d.ts.map +1 -0
- package/dist/translations/pl.d.ts +3 -0
- package/dist/translations/pl.d.ts.map +1 -0
- package/dist/translations/ru.d.ts +3 -0
- package/dist/translations/ru.d.ts.map +1 -0
- package/dist/translations/sv.d.ts +3 -0
- package/dist/translations/sv.d.ts.map +1 -0
- package/dist/translations/tr.d.ts +3 -0
- package/dist/translations/tr.d.ts.map +1 -0
- package/dist/translations/translation-schema.json +96 -0
- package/dist/translations/uk.d.ts +3 -0
- package/dist/translations/uk.d.ts.map +1 -0
- package/dist/translations/vi.d.ts +3 -0
- package/dist/translations/vi.d.ts.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/ui/LengthIndicator.d.ts +7 -0
- package/dist/ui/LengthIndicator.d.ts.map +1 -0
- package/dist/ui/Pill.d.ts +7 -0
- package/dist/ui/Pill.d.ts.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/fields/MetaDescription/MetaDescriptionComponent.tsx"],"sourcesContent":["'use client'\n\nimport type { FieldType, Options } from '@payloadcms/ui'\nimport {\n FieldLabel,\n TextareaInput,\n useConfig,\n useDocumentInfo,\n useField,\n useForm,\n useLocale,\n useTranslation,\n} from '@payloadcms/ui'\nimport { reduceToSerializableFields } from '@payloadcms/ui/shared'\nimport type { TextareaFieldClientProps } from 'payload'\nimport React, { useCallback } from 'react'\n\nimport { defaults } from '../../defaults'\nimport type { PluginSEOTranslationKeys, PluginSEOTranslations } from '../../translations'\nimport type { GenerateDescription } from '../../types'\nimport { LengthIndicator } from '../../ui/LengthIndicator'\n\nconst { maxLength: maxLengthDefault, minLength: minLengthDefault } = defaults.description\n\ntype MetaDescriptionProps = {\n readonly hasGenerateDescriptionAi: boolean\n readonly hasGenerateDescriptionFn: boolean\n} & TextareaFieldClientProps\n\nexport const MetaDescriptionComponent: React.FC<MetaDescriptionProps> = (props) => {\n const {\n field: {\n label,\n localized,\n maxLength: maxLengthFromProps,\n minLength: minLengthFromProps,\n required,\n },\n hasGenerateDescriptionAi,\n hasGenerateDescriptionFn,\n path,\n readOnly,\n } = props\n\n const {\n config: {\n routes: { api },\n serverURL,\n },\n } = useConfig()\n\n const { t } = useTranslation<PluginSEOTranslations, PluginSEOTranslationKeys>()\n\n const locale = useLocale()\n\n const { getData } = useForm()\n\n const docInfo = useDocumentInfo()\n\n const maxLength = maxLengthFromProps || maxLengthDefault\n\n const minLength = minLengthFromProps || minLengthDefault\n\n const { customComponents, errorMessage, setValue, showError, value }: FieldType<string> =\n useField({\n path,\n } as Options)\n\n const { AfterInput, BeforeInput, Label } = customComponents || {}\n\n const regenerateDescription = useCallback(async () => {\n if (!hasGenerateDescriptionFn) {\n return\n }\n\n const endpoint = `${serverURL}${api}/plugin-seo/generate-description`\n\n const genDescriptionResponse = await fetch(endpoint, {\n body: JSON.stringify({\n collectionSlug: docInfo.collectionSlug,\n doc: getData(),\n docPermissions: docInfo.docPermissions,\n globalSlug: docInfo.globalSlug,\n hasPublishPermission: docInfo.hasPublishPermission,\n hasSavePermission: docInfo.hasSavePermission,\n id: docInfo.id,\n initialData: docInfo.initialData,\n initialState: docInfo.initialState\n ? reduceToSerializableFields(docInfo.initialState)\n : undefined,\n locale: typeof locale === 'object' ? locale?.code : locale,\n title: docInfo.title,\n } satisfies Omit<\n Parameters<GenerateDescription>[0],\n 'collectionConfig' | 'globalConfig' | 'hasPublishedDoc' | 'req' | 'versionCount'\n >),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: generatedDescription } = await genDescriptionResponse.json()\n\n setValue(generatedDescription || '')\n }, [\n hasGenerateDescriptionFn,\n serverURL,\n api,\n docInfo.id,\n docInfo.collectionSlug,\n docInfo.docPermissions,\n docInfo.globalSlug,\n docInfo.hasPublishPermission,\n docInfo.hasSavePermission,\n docInfo.initialData,\n docInfo.initialState,\n docInfo.title,\n getData,\n locale,\n setValue,\n ])\n\n const regenerateDescriptionAi = useCallback(async () => {\n if (!hasGenerateDescriptionAi) return\n\n const genDescriptionResponse = await fetch('/api/plugin-seo/generate-description-ai', {\n body: JSON.stringify({\n collectionSlug: docInfo.collectionSlug,\n doc: getData(),\n docPermissions: docInfo.docPermissions,\n globalSlug: docInfo.globalSlug,\n hasPublishPermission: docInfo.hasPublishPermission,\n hasSavePermission: docInfo.hasSavePermission,\n id: docInfo.id,\n initialData: docInfo.initialData,\n initialState: docInfo.initialState\n ? reduceToSerializableFields(docInfo.initialState)\n : undefined,\n locale: typeof locale === 'object' ? locale?.code : locale,\n title: docInfo.title,\n }),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: generatedDescription } = await genDescriptionResponse.json()\n\n setValue(generatedDescription || '')\n }, [\n setValue,\n hasGenerateDescriptionAi,\n locale,\n docInfo.id,\n docInfo.collectionSlug,\n docInfo.docPermissions,\n docInfo.globalSlug,\n docInfo.hasPublishPermission,\n docInfo.hasSavePermission,\n docInfo.initialData,\n docInfo.initialState,\n docInfo.title,\n getData,\n ])\n\n return (\n <div\n style={{\n marginBottom: '20px',\n }}\n >\n <div\n style={{\n marginBottom: '5px',\n position: 'relative',\n }}\n >\n <div className=\"plugin-seo__field\">\n {Label ?? (\n <FieldLabel label={label} localized={localized} path={path} required={required} />\n )}\n {hasGenerateDescriptionFn && (\n <React.Fragment>\n — \n <button\n disabled={readOnly}\n onClick={() => {\n void regenerateDescription()\n }}\n style={{\n background: 'none',\n backgroundColor: 'transparent',\n border: 'none',\n color: 'currentcolor',\n cursor: 'pointer',\n padding: 0,\n textDecoration: 'underline',\n }}\n type=\"button\"\n >\n {t('plugin-seo:autoGenerate')}\n </button>\n </React.Fragment>\n )}\n {hasGenerateDescriptionAi && (\n <React.Fragment>\n — \n <button\n disabled={readOnly}\n onClick={regenerateDescriptionAi}\n style={{\n background: 'none',\n backgroundColor: 'transparent',\n border: 'none',\n color: 'currentcolor',\n cursor: 'pointer',\n padding: 0,\n textDecoration: 'underline',\n }}\n type=\"button\"\n >\n {t('plugin-seo:generateAi')}\n </button>\n </React.Fragment>\n )}\n </div>\n <div\n style={{\n color: '#9A9A9A',\n }}\n >\n {t('plugin-seo:lengthTipDescription', { maxLength, minLength })}\n <a\n href=\"https://developers.google.com/search/docs/advanced/appearance/snippet#meta-descriptions\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n {t('plugin-seo:bestPractices')}\n </a>\n </div>\n </div>\n <div\n style={{\n marginBottom: '10px',\n position: 'relative',\n }}\n >\n <TextareaInput\n AfterInput={AfterInput}\n BeforeInput={BeforeInput}\n Error={errorMessage}\n onChange={setValue}\n path={path}\n readOnly={readOnly}\n required={required}\n showError={showError}\n style={{\n marginBottom: 0,\n }}\n value={value}\n />\n </div>\n <div\n style={{\n alignItems: 'center',\n display: 'flex',\n width: '100%',\n }}\n >\n <LengthIndicator maxLength={maxLength} minLength={minLength} text={value} />\n </div>\n </div>\n )\n}\n"],"names":["FieldLabel","TextareaInput","useConfig","useDocumentInfo","useField","useForm","useLocale","useTranslation","reduceToSerializableFields","React","useCallback","defaults","LengthIndicator","maxLength","maxLengthDefault","minLength","minLengthDefault","description","MetaDescriptionComponent","props","field","label","localized","maxLengthFromProps","minLengthFromProps","required","hasGenerateDescriptionAi","hasGenerateDescriptionFn","path","readOnly","config","routes","api","serverURL","t","locale","getData","docInfo","customComponents","errorMessage","setValue","showError","value","AfterInput","BeforeInput","Label","regenerateDescription","endpoint","genDescriptionResponse","fetch","body","JSON","stringify","collectionSlug","doc","docPermissions","globalSlug","hasPublishPermission","hasSavePermission","id","initialData","initialState","undefined","code","title","credentials","headers","method","result","generatedDescription","json","regenerateDescriptionAi","div","style","marginBottom","position","className","Fragment","button","disabled","onClick","background","backgroundColor","border","color","cursor","padding","textDecoration","type","a","href","rel","target","Error","onChange","alignItems","display","width","text"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
export const MetaDescriptionField = ({ hasGenerateAi = false, hasGenerateFn = false, overrides })=>{
|
|
3
|
+
return {
|
|
4
|
+
admin: {
|
|
5
|
+
components: {
|
|
6
|
+
Field: {
|
|
7
|
+
clientProps: {
|
|
8
|
+
hasGenerateDescriptionAi: hasGenerateAi,
|
|
9
|
+
hasGenerateDescriptionFn: hasGenerateFn
|
|
10
|
+
},
|
|
11
|
+
path: '@justanarthur/payload-plugin-seo/fields-components#MetaDescriptionComponent'
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
localized: true,
|
|
16
|
+
name: 'description',
|
|
17
|
+
type: 'textarea',
|
|
18
|
+
...overrides ?? {}
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/fields/MetaDescription/index.ts"],"sourcesContent":["// @ts-nocheck\nimport type { TextareaField } from 'payload'\n\ntype FieldFunctionProps = {\n /**\n * Tell the component if the generate AI function is available as configured in the plugin config\n */\n hasGenerateAi?: boolean\n /**\n * Tell the component if the generate function is available as configured in the plugin config\n */\n hasGenerateFn?: boolean\n overrides?: Omit<Partial<TextareaField>, 'admin'>\n}\n\ntype FieldFunction = ({\n hasGenerateAi,\n hasGenerateFn,\n overrides,\n}: FieldFunctionProps) => TextareaField\n\nexport const MetaDescriptionField: FieldFunction = ({\n hasGenerateAi = false,\n hasGenerateFn = false,\n overrides,\n}) => {\n return {\n admin: {\n components: {\n Field: {\n clientProps: {\n hasGenerateDescriptionAi: hasGenerateAi,\n hasGenerateDescriptionFn: hasGenerateFn,\n },\n path: '@justanarthur/payload-plugin-seo/fields-components#MetaDescriptionComponent',\n },\n },\n },\n localized: true,\n name: 'description',\n type: 'textarea',\n ...((overrides as TextareaField) ?? {}),\n }\n}\n"],"names":["MetaDescriptionField","hasGenerateAi","hasGenerateFn","overrides","admin","components","Field","clientProps","hasGenerateDescriptionAi","hasGenerateDescriptionFn","path","localized","name","type"],"mappings":"AAAA,cAAc;AAqBd,OAAO,MAAMA,uBAAsC,CAAC,EAClDC,gBAAgB,KAAK,EACrBC,gBAAgB,KAAK,EACrBC,SAAS,EACV;IACC,OAAO;QACLC,OAAO;YACLC,YAAY;gBACVC,OAAO;oBACLC,aAAa;wBACXC,0BAA0BP;wBAC1BQ,0BAA0BP;oBAC5B;oBACAQ,MAAM;gBACR;YACF;QACF;QACAC,WAAW;QACXC,MAAM;QACNC,MAAM;QACN,GAAI,AAACV,aAA+B,CAAC,CAAC;IACxC;AACF,EAAC"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { FieldLabel, RenderCustomComponent, UploadInput, useConfig, useDocumentInfo, useField, useForm, useLocale, useTranslation } from '@payloadcms/ui';
|
|
4
|
+
import { reduceToSerializableFields } from '@payloadcms/ui/shared';
|
|
5
|
+
import React, { useCallback } from 'react';
|
|
6
|
+
import { Pill } from '../../ui/Pill';
|
|
7
|
+
export const MetaImageComponent = (props)=>{
|
|
8
|
+
const { field: { label, localized, relationTo, required }, hasGenerateImageFn, path, readOnly } = props || {};
|
|
9
|
+
const { config: { collections, routes: { api }, serverURL } } = useConfig();
|
|
10
|
+
const field = useField({
|
|
11
|
+
...props,
|
|
12
|
+
path
|
|
13
|
+
});
|
|
14
|
+
const { customComponents } = field;
|
|
15
|
+
const { // biome-ignore lint/suspicious/noShadowRestrictedNames: <explanation>
|
|
16
|
+
Error, Label } = customComponents || {};
|
|
17
|
+
const { t } = useTranslation();
|
|
18
|
+
const locale = useLocale();
|
|
19
|
+
const { getData } = useForm();
|
|
20
|
+
const docInfo = useDocumentInfo();
|
|
21
|
+
const { setValue, showError, value } = field;
|
|
22
|
+
const regenerateImage = useCallback(async ()=>{
|
|
23
|
+
if (!hasGenerateImageFn) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const endpoint = `${serverURL}${api}/plugin-seo/generate-image`;
|
|
27
|
+
const genImageResponse = await fetch(endpoint, {
|
|
28
|
+
body: JSON.stringify({
|
|
29
|
+
collectionSlug: docInfo.collectionSlug,
|
|
30
|
+
doc: getData(),
|
|
31
|
+
docPermissions: docInfo.docPermissions,
|
|
32
|
+
globalSlug: docInfo.globalSlug,
|
|
33
|
+
hasPublishPermission: docInfo.hasPublishPermission,
|
|
34
|
+
hasSavePermission: docInfo.hasSavePermission,
|
|
35
|
+
id: docInfo.id,
|
|
36
|
+
initialData: docInfo.initialData,
|
|
37
|
+
initialState: docInfo.initialState ? reduceToSerializableFields(docInfo.initialState) : undefined,
|
|
38
|
+
locale: typeof locale === 'object' ? locale?.code : locale,
|
|
39
|
+
title: docInfo.title
|
|
40
|
+
}),
|
|
41
|
+
credentials: 'include',
|
|
42
|
+
headers: {
|
|
43
|
+
'Content-Type': 'application/json'
|
|
44
|
+
},
|
|
45
|
+
method: 'POST'
|
|
46
|
+
});
|
|
47
|
+
const generatedImage = await genImageResponse.text();
|
|
48
|
+
setValue(generatedImage || '');
|
|
49
|
+
}, [
|
|
50
|
+
hasGenerateImageFn,
|
|
51
|
+
serverURL,
|
|
52
|
+
api,
|
|
53
|
+
docInfo.id,
|
|
54
|
+
docInfo.collectionSlug,
|
|
55
|
+
docInfo.docPermissions,
|
|
56
|
+
docInfo.globalSlug,
|
|
57
|
+
docInfo.hasPublishPermission,
|
|
58
|
+
docInfo.hasSavePermission,
|
|
59
|
+
docInfo.initialData,
|
|
60
|
+
docInfo.initialState,
|
|
61
|
+
docInfo.title,
|
|
62
|
+
getData,
|
|
63
|
+
locale,
|
|
64
|
+
setValue
|
|
65
|
+
]);
|
|
66
|
+
const hasImage = Boolean(value);
|
|
67
|
+
const collection = collections?.find((coll)=>coll.slug === relationTo) || undefined;
|
|
68
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
69
|
+
style: {
|
|
70
|
+
marginBottom: '20px'
|
|
71
|
+
},
|
|
72
|
+
children: [
|
|
73
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
74
|
+
style: {
|
|
75
|
+
marginBottom: '5px',
|
|
76
|
+
position: 'relative'
|
|
77
|
+
},
|
|
78
|
+
children: [
|
|
79
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
80
|
+
className: "plugin-seo__field",
|
|
81
|
+
children: [
|
|
82
|
+
/*#__PURE__*/ _jsx(RenderCustomComponent, {
|
|
83
|
+
CustomComponent: Label,
|
|
84
|
+
Fallback: /*#__PURE__*/ _jsx(FieldLabel, {
|
|
85
|
+
label: label,
|
|
86
|
+
localized: localized,
|
|
87
|
+
path: path,
|
|
88
|
+
required: required
|
|
89
|
+
})
|
|
90
|
+
}),
|
|
91
|
+
hasGenerateImageFn && /*#__PURE__*/ _jsxs(React.Fragment, {
|
|
92
|
+
children: [
|
|
93
|
+
" — ",
|
|
94
|
+
/*#__PURE__*/ _jsx("button", {
|
|
95
|
+
disabled: readOnly,
|
|
96
|
+
onClick: ()=>{
|
|
97
|
+
void regenerateImage();
|
|
98
|
+
},
|
|
99
|
+
style: {
|
|
100
|
+
background: 'none',
|
|
101
|
+
backgroundColor: 'transparent',
|
|
102
|
+
border: 'none',
|
|
103
|
+
color: 'currentcolor',
|
|
104
|
+
cursor: 'pointer',
|
|
105
|
+
padding: 0,
|
|
106
|
+
textDecoration: 'underline'
|
|
107
|
+
},
|
|
108
|
+
type: "button",
|
|
109
|
+
children: t('plugin-seo:autoGenerate')
|
|
110
|
+
})
|
|
111
|
+
]
|
|
112
|
+
})
|
|
113
|
+
]
|
|
114
|
+
}),
|
|
115
|
+
hasGenerateImageFn && /*#__PURE__*/ _jsx("div", {
|
|
116
|
+
style: {
|
|
117
|
+
color: '#9A9A9A'
|
|
118
|
+
},
|
|
119
|
+
children: t('plugin-seo:imageAutoGenerationTip')
|
|
120
|
+
})
|
|
121
|
+
]
|
|
122
|
+
}),
|
|
123
|
+
/*#__PURE__*/ _jsx("div", {
|
|
124
|
+
style: {
|
|
125
|
+
marginBottom: '10px',
|
|
126
|
+
position: 'relative'
|
|
127
|
+
},
|
|
128
|
+
children: /*#__PURE__*/ _jsx(UploadInput, {
|
|
129
|
+
Error: Error,
|
|
130
|
+
api: api,
|
|
131
|
+
collection: collection,
|
|
132
|
+
filterOptions: field.filterOptions,
|
|
133
|
+
onChange: (incomingImage)=>{
|
|
134
|
+
if (incomingImage !== null) {
|
|
135
|
+
if (typeof incomingImage === 'object') {
|
|
136
|
+
const { id: incomingID } = incomingImage;
|
|
137
|
+
setValue(incomingID);
|
|
138
|
+
} else {
|
|
139
|
+
setValue(incomingImage);
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
setValue(null);
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
path: path,
|
|
146
|
+
readOnly: readOnly,
|
|
147
|
+
relationTo: relationTo,
|
|
148
|
+
required: required,
|
|
149
|
+
serverURL: serverURL,
|
|
150
|
+
showError: showError,
|
|
151
|
+
style: {
|
|
152
|
+
marginBottom: 0
|
|
153
|
+
},
|
|
154
|
+
value: value
|
|
155
|
+
})
|
|
156
|
+
}),
|
|
157
|
+
/*#__PURE__*/ _jsx("div", {
|
|
158
|
+
style: {
|
|
159
|
+
alignItems: 'center',
|
|
160
|
+
display: 'flex',
|
|
161
|
+
width: '100%'
|
|
162
|
+
},
|
|
163
|
+
children: /*#__PURE__*/ _jsx(Pill, {
|
|
164
|
+
backgroundColor: hasImage ? 'green' : 'red',
|
|
165
|
+
color: "white",
|
|
166
|
+
label: hasImage ? t('plugin-seo:good') : t('plugin-seo:noImage')
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
]
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
//# sourceMappingURL=MetaImageComponent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/fields/MetaImage/MetaImageComponent.tsx"],"sourcesContent":["'use client'\n\nimport type { FieldType, Options } from '@payloadcms/ui'\nimport {\n FieldLabel,\n RenderCustomComponent,\n UploadInput,\n useConfig,\n useDocumentInfo,\n useField,\n useForm,\n useLocale,\n useTranslation,\n} from '@payloadcms/ui'\nimport { reduceToSerializableFields } from '@payloadcms/ui/shared'\nimport type { UploadFieldClientProps } from 'payload'\nimport React, { useCallback } from 'react'\n\nimport type { PluginSEOTranslationKeys, PluginSEOTranslations } from '../../translations'\nimport type { GenerateImage } from '../../types'\nimport { Pill } from '../../ui/Pill'\n\ntype MetaImageProps = {\n readonly hasGenerateImageFn: boolean\n} & UploadFieldClientProps\n\nexport const MetaImageComponent: React.FC<MetaImageProps> = (props) => {\n const {\n field: { label, localized, relationTo, required },\n hasGenerateImageFn,\n path,\n readOnly,\n } = props || {}\n\n const {\n config: {\n collections,\n routes: { api },\n serverURL,\n },\n } = useConfig()\n\n const field: FieldType<string> = useField({ ...props, path } as Options)\n\n const { customComponents } = field\n\n const {\n // biome-ignore lint/suspicious/noShadowRestrictedNames: <explanation>\n Error,\n Label,\n } = customComponents || {}\n\n const { t } = useTranslation<PluginSEOTranslations, PluginSEOTranslationKeys>()\n\n const locale = useLocale()\n\n const { getData } = useForm()\n\n const docInfo = useDocumentInfo()\n\n const { setValue, showError, value } = field\n\n const regenerateImage = useCallback(async () => {\n if (!hasGenerateImageFn) {\n return\n }\n\n const endpoint = `${serverURL}${api}/plugin-seo/generate-image`\n\n const genImageResponse = await fetch(endpoint, {\n body: JSON.stringify({\n collectionSlug: docInfo.collectionSlug,\n doc: getData(),\n docPermissions: docInfo.docPermissions,\n globalSlug: docInfo.globalSlug,\n hasPublishPermission: docInfo.hasPublishPermission,\n hasSavePermission: docInfo.hasSavePermission,\n id: docInfo.id,\n initialData: docInfo.initialData,\n initialState: docInfo.initialState\n ? reduceToSerializableFields(docInfo.initialState)\n : undefined,\n locale: typeof locale === 'object' ? locale?.code : locale,\n title: docInfo.title,\n } satisfies Omit<\n Parameters<GenerateImage>[0],\n 'collectionConfig' | 'globalConfig' | 'hasPublishedDoc' | 'req' | 'versionCount'\n >),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const generatedImage = await genImageResponse.text()\n\n setValue(generatedImage || '')\n }, [\n hasGenerateImageFn,\n serverURL,\n api,\n docInfo.id,\n docInfo.collectionSlug,\n docInfo.docPermissions,\n docInfo.globalSlug,\n docInfo.hasPublishPermission,\n docInfo.hasSavePermission,\n docInfo.initialData,\n docInfo.initialState,\n docInfo.title,\n getData,\n locale,\n setValue,\n ])\n\n const hasImage = Boolean(value)\n\n const collection = collections?.find((coll) => coll.slug === relationTo) || undefined\n\n return (\n <div\n style={{\n marginBottom: '20px',\n }}\n >\n <div\n style={{\n marginBottom: '5px',\n position: 'relative',\n }}\n >\n <div className=\"plugin-seo__field\">\n <RenderCustomComponent\n CustomComponent={Label}\n Fallback={\n <FieldLabel label={label} localized={localized} path={path} required={required} />\n }\n />\n {hasGenerateImageFn && (\n <React.Fragment>\n — \n <button\n disabled={readOnly}\n onClick={() => {\n void regenerateImage()\n }}\n style={{\n background: 'none',\n backgroundColor: 'transparent',\n border: 'none',\n color: 'currentcolor',\n cursor: 'pointer',\n padding: 0,\n textDecoration: 'underline',\n }}\n type=\"button\"\n >\n {t('plugin-seo:autoGenerate')}\n </button>\n </React.Fragment>\n )}\n </div>\n {hasGenerateImageFn && (\n <div\n style={{\n color: '#9A9A9A',\n }}\n >\n {t('plugin-seo:imageAutoGenerationTip')}\n </div>\n )}\n </div>\n <div\n style={{\n marginBottom: '10px',\n position: 'relative',\n }}\n >\n <UploadInput\n Error={Error}\n api={api}\n collection={collection}\n filterOptions={field.filterOptions}\n onChange={(incomingImage) => {\n if (incomingImage !== null) {\n if (typeof incomingImage === 'object') {\n const { id: incomingID } = incomingImage\n\n setValue(incomingID)\n } else {\n setValue(incomingImage)\n }\n } else {\n setValue(null)\n }\n }}\n path={path}\n readOnly={readOnly}\n relationTo={relationTo}\n required={required}\n serverURL={serverURL}\n showError={showError}\n style={{\n marginBottom: 0,\n }}\n value={value}\n />\n </div>\n <div\n style={{\n alignItems: 'center',\n display: 'flex',\n width: '100%',\n }}\n >\n <Pill\n backgroundColor={hasImage ? 'green' : 'red'}\n color=\"white\"\n label={hasImage ? t('plugin-seo:good') : t('plugin-seo:noImage')}\n />\n </div>\n </div>\n )\n}\n"],"names":["FieldLabel","RenderCustomComponent","UploadInput","useConfig","useDocumentInfo","useField","useForm","useLocale","useTranslation","reduceToSerializableFields","React","useCallback","Pill","MetaImageComponent","props","field","label","localized","relationTo","required","hasGenerateImageFn","path","readOnly","config","collections","routes","api","serverURL","customComponents","Error","Label","t","locale","getData","docInfo","setValue","showError","value","regenerateImage","endpoint","genImageResponse","fetch","body","JSON","stringify","collectionSlug","doc","docPermissions","globalSlug","hasPublishPermission","hasSavePermission","id","initialData","initialState","undefined","code","title","credentials","headers","method","generatedImage","text","hasImage","Boolean","collection","find","coll","slug","div","style","marginBottom","position","className","CustomComponent","Fallback","Fragment","button","disabled","onClick","background","backgroundColor","border","color","cursor","padding","textDecoration","type","filterOptions","onChange","incomingImage","incomingID","alignItems","display","width"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
export const MetaImageField = ({ hasGenerateFn = false, overrides, relationTo })=>{
|
|
3
|
+
return {
|
|
4
|
+
admin: {
|
|
5
|
+
components: {
|
|
6
|
+
Field: {
|
|
7
|
+
clientProps: {
|
|
8
|
+
hasGenerateImageFn: hasGenerateFn
|
|
9
|
+
},
|
|
10
|
+
path: '@justanarthur/payload-plugin-seo/fields-components#MetaImageComponent'
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
description: 'Maximum upload file size: 12MB. Recommended file size for images is <500KB.'
|
|
14
|
+
},
|
|
15
|
+
label: 'Meta Image',
|
|
16
|
+
localized: true,
|
|
17
|
+
name: 'image',
|
|
18
|
+
relationTo: relationTo,
|
|
19
|
+
type: 'upload',
|
|
20
|
+
...overrides ?? {}
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/fields/MetaImage/index.ts"],"sourcesContent":["// @ts-nocheck\nimport type { CollectionSlug, UploadField } from 'payload'\n\ntype FieldFunctionProps = {\n /**\n * Tell the component if the generate function is available as configured in the plugin config\n */\n hasGenerateFn?: boolean\n overrides?: Partial<UploadField>\n relationTo: string\n}\n\ntype FieldFunction = ({ hasGenerateFn, overrides }: FieldFunctionProps) => UploadField\n\nexport const MetaImageField: FieldFunction = ({ hasGenerateFn = false, overrides, relationTo }) => {\n return {\n admin: {\n components: {\n Field: {\n clientProps: {\n hasGenerateImageFn: hasGenerateFn,\n },\n path: '@justanarthur/payload-plugin-seo/fields-components#MetaImageComponent',\n },\n },\n description: 'Maximum upload file size: 12MB. Recommended file size for images is <500KB.',\n },\n label: 'Meta Image',\n localized: true,\n name: 'image',\n relationTo: relationTo as CollectionSlug,\n type: 'upload',\n ...((overrides as unknown as UploadField) ?? {}),\n }\n}\n"],"names":["MetaImageField","hasGenerateFn","overrides","relationTo","admin","components","Field","clientProps","hasGenerateImageFn","path","description","label","localized","name","type"],"mappings":"AAAA,cAAc;AAcd,OAAO,MAAMA,iBAAgC,CAAC,EAAEC,gBAAgB,KAAK,EAAEC,SAAS,EAAEC,UAAU,EAAE;IAC5F,OAAO;QACLC,OAAO;YACLC,YAAY;gBACVC,OAAO;oBACLC,aAAa;wBACXC,oBAAoBP;oBACtB;oBACAQ,MAAM;gBACR;YACF;YACAC,aAAa;QACf;QACAC,OAAO;QACPC,WAAW;QACXC,MAAM;QACNV,YAAYA;QACZW,MAAM;QACN,GAAI,AAACZ,aAAwC,CAAC,CAAC;IACjD;AACF,EAAC"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import '../index.scss';
|
|
4
|
+
import { FieldLabel, TextInput, useConfig, useDocumentInfo, useField, useForm, useLocale, useTranslation } from '@payloadcms/ui';
|
|
5
|
+
import { reduceToSerializableFields } from '@payloadcms/ui/shared';
|
|
6
|
+
import React, { useCallback } from 'react';
|
|
7
|
+
import { defaults } from '../../defaults';
|
|
8
|
+
import { LengthIndicator } from '../../ui/LengthIndicator';
|
|
9
|
+
const { maxLength: maxLengthDefault, minLength: minLengthDefault } = defaults.title;
|
|
10
|
+
export const MetaTitleComponent = (props)=>{
|
|
11
|
+
const { field: { label, maxLength: maxLengthFromProps, minLength: minLengthFromProps, required }, hasGenerateTitleAi, hasGenerateTitleFn, path, readOnly } = props || {};
|
|
12
|
+
const { t } = useTranslation();
|
|
13
|
+
const { config: { routes: { api }, serverURL } } = useConfig();
|
|
14
|
+
const field = useField({
|
|
15
|
+
path
|
|
16
|
+
});
|
|
17
|
+
const { customComponents: { AfterInput, BeforeInput, Label } = {} } = field;
|
|
18
|
+
const locale = useLocale();
|
|
19
|
+
const { getData } = useForm();
|
|
20
|
+
const docInfo = useDocumentInfo();
|
|
21
|
+
const minLength = minLengthFromProps || minLengthDefault;
|
|
22
|
+
const maxLength = maxLengthFromProps || maxLengthDefault;
|
|
23
|
+
const { errorMessage, setValue, showError, value } = field;
|
|
24
|
+
const regenerateTitle = useCallback(async ()=>{
|
|
25
|
+
if (!hasGenerateTitleFn) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const endpoint = `${serverURL}${api}/plugin-seo/generate-title`;
|
|
29
|
+
const genTitleResponse = await fetch(endpoint, {
|
|
30
|
+
body: JSON.stringify({
|
|
31
|
+
collectionSlug: docInfo.collectionSlug,
|
|
32
|
+
doc: getData(),
|
|
33
|
+
docPermissions: docInfo.docPermissions,
|
|
34
|
+
globalSlug: docInfo.globalSlug,
|
|
35
|
+
hasPublishPermission: docInfo.hasPublishPermission,
|
|
36
|
+
hasSavePermission: docInfo.hasSavePermission,
|
|
37
|
+
id: docInfo.id,
|
|
38
|
+
initialData: docInfo.initialData,
|
|
39
|
+
initialState: docInfo.initialState ? reduceToSerializableFields(docInfo.initialState) : undefined,
|
|
40
|
+
locale: typeof locale === 'object' ? locale?.code : locale,
|
|
41
|
+
title: docInfo.title
|
|
42
|
+
}),
|
|
43
|
+
credentials: 'include',
|
|
44
|
+
headers: {
|
|
45
|
+
'Content-Type': 'application/json'
|
|
46
|
+
},
|
|
47
|
+
method: 'POST'
|
|
48
|
+
});
|
|
49
|
+
const { result: generatedTitle } = await genTitleResponse.json();
|
|
50
|
+
setValue(generatedTitle || '');
|
|
51
|
+
}, [
|
|
52
|
+
hasGenerateTitleFn,
|
|
53
|
+
serverURL,
|
|
54
|
+
api,
|
|
55
|
+
docInfo.id,
|
|
56
|
+
docInfo.collectionSlug,
|
|
57
|
+
docInfo.docPermissions,
|
|
58
|
+
docInfo.globalSlug,
|
|
59
|
+
docInfo.hasPublishPermission,
|
|
60
|
+
docInfo.hasSavePermission,
|
|
61
|
+
docInfo.initialData,
|
|
62
|
+
docInfo.initialState,
|
|
63
|
+
docInfo.title,
|
|
64
|
+
getData,
|
|
65
|
+
locale,
|
|
66
|
+
setValue
|
|
67
|
+
]);
|
|
68
|
+
const regenerateTitleAi = useCallback(async ()=>{
|
|
69
|
+
if (!hasGenerateTitleAi) return;
|
|
70
|
+
const genTitleResponse = await fetch('/api/plugin-seo/generate-title-ai', {
|
|
71
|
+
body: JSON.stringify({
|
|
72
|
+
collectionSlug: docInfo.collectionSlug,
|
|
73
|
+
doc: getData(),
|
|
74
|
+
docPermissions: docInfo.docPermissions,
|
|
75
|
+
globalSlug: docInfo.globalSlug,
|
|
76
|
+
hasPublishPermission: docInfo.hasPublishPermission,
|
|
77
|
+
hasSavePermission: docInfo.hasSavePermission,
|
|
78
|
+
id: docInfo.id,
|
|
79
|
+
initialData: docInfo.initialData,
|
|
80
|
+
initialState: docInfo.initialState ? reduceToSerializableFields(docInfo.initialState) : undefined,
|
|
81
|
+
locale: typeof locale === 'object' ? locale?.code : locale,
|
|
82
|
+
title: docInfo.title
|
|
83
|
+
}),
|
|
84
|
+
credentials: 'include',
|
|
85
|
+
headers: {
|
|
86
|
+
'Content-Type': 'application/json'
|
|
87
|
+
},
|
|
88
|
+
method: 'POST'
|
|
89
|
+
});
|
|
90
|
+
const { result: generatedTitle } = await genTitleResponse.json();
|
|
91
|
+
setValue(generatedTitle || '');
|
|
92
|
+
}, [
|
|
93
|
+
setValue,
|
|
94
|
+
hasGenerateTitleAi,
|
|
95
|
+
locale,
|
|
96
|
+
docInfo.id,
|
|
97
|
+
docInfo.collectionSlug,
|
|
98
|
+
docInfo.docPermissions,
|
|
99
|
+
docInfo.globalSlug,
|
|
100
|
+
docInfo.hasPublishPermission,
|
|
101
|
+
docInfo.hasSavePermission,
|
|
102
|
+
docInfo.initialData,
|
|
103
|
+
docInfo.initialState,
|
|
104
|
+
docInfo.title,
|
|
105
|
+
getData
|
|
106
|
+
]);
|
|
107
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
108
|
+
style: {
|
|
109
|
+
marginBottom: '20px'
|
|
110
|
+
},
|
|
111
|
+
children: [
|
|
112
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
113
|
+
style: {
|
|
114
|
+
marginBottom: '5px',
|
|
115
|
+
position: 'relative'
|
|
116
|
+
},
|
|
117
|
+
children: [
|
|
118
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
119
|
+
className: "plugin-seo__field",
|
|
120
|
+
children: [
|
|
121
|
+
Label ?? /*#__PURE__*/ _jsx(FieldLabel, {
|
|
122
|
+
label: label,
|
|
123
|
+
path: path,
|
|
124
|
+
required: required
|
|
125
|
+
}),
|
|
126
|
+
hasGenerateTitleFn && /*#__PURE__*/ _jsxs(React.Fragment, {
|
|
127
|
+
children: [
|
|
128
|
+
" — ",
|
|
129
|
+
/*#__PURE__*/ _jsx("button", {
|
|
130
|
+
disabled: readOnly,
|
|
131
|
+
onClick: ()=>{
|
|
132
|
+
void regenerateTitle();
|
|
133
|
+
},
|
|
134
|
+
style: {
|
|
135
|
+
background: 'none',
|
|
136
|
+
backgroundColor: 'transparent',
|
|
137
|
+
border: 'none',
|
|
138
|
+
color: 'currentcolor',
|
|
139
|
+
cursor: 'pointer',
|
|
140
|
+
padding: 0,
|
|
141
|
+
textDecoration: 'underline'
|
|
142
|
+
},
|
|
143
|
+
type: "button",
|
|
144
|
+
children: t('plugin-seo:autoGenerate')
|
|
145
|
+
})
|
|
146
|
+
]
|
|
147
|
+
}),
|
|
148
|
+
hasGenerateTitleAi && /*#__PURE__*/ _jsxs(React.Fragment, {
|
|
149
|
+
children: [
|
|
150
|
+
" — ",
|
|
151
|
+
/*#__PURE__*/ _jsx("button", {
|
|
152
|
+
onClick: regenerateTitleAi,
|
|
153
|
+
style: {
|
|
154
|
+
background: 'none',
|
|
155
|
+
backgroundColor: 'transparent',
|
|
156
|
+
border: 'none',
|
|
157
|
+
color: 'currentcolor',
|
|
158
|
+
cursor: 'pointer',
|
|
159
|
+
padding: 0,
|
|
160
|
+
textDecoration: 'underline'
|
|
161
|
+
},
|
|
162
|
+
type: "button",
|
|
163
|
+
children: t('plugin-seo:generateAi')
|
|
164
|
+
})
|
|
165
|
+
]
|
|
166
|
+
})
|
|
167
|
+
]
|
|
168
|
+
}),
|
|
169
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
170
|
+
style: {
|
|
171
|
+
color: '#9A9A9A'
|
|
172
|
+
},
|
|
173
|
+
children: [
|
|
174
|
+
t('plugin-seo:lengthTipTitle', {
|
|
175
|
+
maxLength,
|
|
176
|
+
minLength
|
|
177
|
+
}),
|
|
178
|
+
/*#__PURE__*/ _jsx("a", {
|
|
179
|
+
href: "https://developers.google.com/search/docs/advanced/appearance/title-link#page-titles",
|
|
180
|
+
rel: "noopener noreferrer",
|
|
181
|
+
target: "_blank",
|
|
182
|
+
children: t('plugin-seo:bestPractices')
|
|
183
|
+
}),
|
|
184
|
+
"."
|
|
185
|
+
]
|
|
186
|
+
})
|
|
187
|
+
]
|
|
188
|
+
}),
|
|
189
|
+
/*#__PURE__*/ _jsx("div", {
|
|
190
|
+
style: {
|
|
191
|
+
marginBottom: '10px',
|
|
192
|
+
position: 'relative'
|
|
193
|
+
},
|
|
194
|
+
children: /*#__PURE__*/ _jsx(TextInput, {
|
|
195
|
+
AfterInput: AfterInput,
|
|
196
|
+
BeforeInput: BeforeInput,
|
|
197
|
+
Error: errorMessage,
|
|
198
|
+
onChange: setValue,
|
|
199
|
+
path: path,
|
|
200
|
+
readOnly: readOnly,
|
|
201
|
+
required: required,
|
|
202
|
+
showError: showError,
|
|
203
|
+
style: {
|
|
204
|
+
marginBottom: 0
|
|
205
|
+
},
|
|
206
|
+
value: value
|
|
207
|
+
})
|
|
208
|
+
}),
|
|
209
|
+
/*#__PURE__*/ _jsx("div", {
|
|
210
|
+
style: {
|
|
211
|
+
alignItems: 'center',
|
|
212
|
+
display: 'flex',
|
|
213
|
+
width: '100%'
|
|
214
|
+
},
|
|
215
|
+
children: /*#__PURE__*/ _jsx(LengthIndicator, {
|
|
216
|
+
maxLength: maxLength,
|
|
217
|
+
minLength: minLength,
|
|
218
|
+
text: value
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
]
|
|
222
|
+
});
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
//# sourceMappingURL=MetaTitleComponent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/fields/MetaTitle/MetaTitleComponent.tsx"],"sourcesContent":["'use client'\n\nimport '../index.scss'\n\nimport type { FieldType, Options } from '@payloadcms/ui'\nimport {\n FieldLabel,\n TextInput,\n useConfig,\n useDocumentInfo,\n useField,\n useForm,\n useLocale,\n useTranslation,\n} from '@payloadcms/ui'\nimport { reduceToSerializableFields } from '@payloadcms/ui/shared'\nimport type { TextFieldClientProps } from 'payload'\nimport React, { useCallback } from 'react'\n\nimport { defaults } from '../../defaults'\nimport type { PluginSEOTranslationKeys, PluginSEOTranslations } from '../../translations'\nimport type { GenerateTitle } from '../../types'\nimport { LengthIndicator } from '../../ui/LengthIndicator'\n\nconst { maxLength: maxLengthDefault, minLength: minLengthDefault } = defaults.title\n\ntype MetaTitleProps = {\n readonly hasGenerateTitleAi: boolean\n readonly hasGenerateTitleFn: boolean\n} & TextFieldClientProps\n\nexport const MetaTitleComponent: React.FC<MetaTitleProps> = (props) => {\n const {\n field: { label, maxLength: maxLengthFromProps, minLength: minLengthFromProps, required },\n hasGenerateTitleAi,\n hasGenerateTitleFn,\n path,\n readOnly,\n } = props || {}\n\n const { t } = useTranslation<PluginSEOTranslations, PluginSEOTranslationKeys>()\n\n const {\n config: {\n routes: { api },\n serverURL,\n },\n } = useConfig()\n\n const field: FieldType<string> = useField({ path } as Options)\n\n const { customComponents: { AfterInput, BeforeInput, Label } = {} } = field\n\n const locale = useLocale()\n\n const { getData } = useForm()\n\n const docInfo = useDocumentInfo()\n\n const minLength = minLengthFromProps || minLengthDefault\n\n const maxLength = maxLengthFromProps || maxLengthDefault\n\n const { errorMessage, setValue, showError, value } = field\n\n const regenerateTitle = useCallback(async () => {\n if (!hasGenerateTitleFn) {\n return\n }\n\n const endpoint = `${serverURL}${api}/plugin-seo/generate-title`\n\n const genTitleResponse = await fetch(endpoint, {\n body: JSON.stringify({\n collectionSlug: docInfo.collectionSlug,\n doc: getData(),\n docPermissions: docInfo.docPermissions,\n globalSlug: docInfo.globalSlug,\n hasPublishPermission: docInfo.hasPublishPermission,\n hasSavePermission: docInfo.hasSavePermission,\n id: docInfo.id,\n initialData: docInfo.initialData,\n initialState: docInfo.initialState\n ? reduceToSerializableFields(docInfo.initialState)\n : undefined,\n locale: typeof locale === 'object' ? locale?.code : locale,\n title: docInfo.title,\n } satisfies Omit<\n Parameters<GenerateTitle>[0],\n 'collectionConfig' | 'globalConfig' | 'hasPublishedDoc' | 'req' | 'versionCount'\n >),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: generatedTitle } = await genTitleResponse.json()\n\n setValue(generatedTitle || '')\n }, [\n hasGenerateTitleFn,\n serverURL,\n api,\n docInfo.id,\n docInfo.collectionSlug,\n docInfo.docPermissions,\n docInfo.globalSlug,\n docInfo.hasPublishPermission,\n docInfo.hasSavePermission,\n docInfo.initialData,\n docInfo.initialState,\n docInfo.title,\n getData,\n locale,\n setValue,\n ])\n\n const regenerateTitleAi = useCallback(async () => {\n if (!hasGenerateTitleAi) return\n\n const genTitleResponse = await fetch('/api/plugin-seo/generate-title-ai', {\n body: JSON.stringify({\n collectionSlug: docInfo.collectionSlug,\n doc: getData(),\n docPermissions: docInfo.docPermissions,\n globalSlug: docInfo.globalSlug,\n hasPublishPermission: docInfo.hasPublishPermission,\n hasSavePermission: docInfo.hasSavePermission,\n id: docInfo.id,\n initialData: docInfo.initialData,\n initialState: docInfo.initialState\n ? reduceToSerializableFields(docInfo.initialState)\n : undefined,\n locale: typeof locale === 'object' ? locale?.code : locale,\n title: docInfo.title,\n }),\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n const { result: generatedTitle } = await genTitleResponse.json()\n\n setValue(generatedTitle || '')\n }, [\n setValue,\n hasGenerateTitleAi,\n locale,\n docInfo.id,\n docInfo.collectionSlug,\n docInfo.docPermissions,\n docInfo.globalSlug,\n docInfo.hasPublishPermission,\n docInfo.hasSavePermission,\n docInfo.initialData,\n docInfo.initialState,\n docInfo.title,\n getData,\n ])\n\n return (\n <div\n style={{\n marginBottom: '20px',\n }}\n >\n <div\n style={{\n marginBottom: '5px',\n position: 'relative',\n }}\n >\n <div className=\"plugin-seo__field\">\n {Label ?? <FieldLabel label={label} path={path} required={required} />}\n {hasGenerateTitleFn && (\n <React.Fragment>\n — \n <button\n disabled={readOnly}\n onClick={() => {\n void regenerateTitle()\n }}\n style={{\n background: 'none',\n backgroundColor: 'transparent',\n border: 'none',\n color: 'currentcolor',\n cursor: 'pointer',\n padding: 0,\n textDecoration: 'underline',\n }}\n type=\"button\"\n >\n {t('plugin-seo:autoGenerate')}\n </button>\n </React.Fragment>\n )}\n {hasGenerateTitleAi && (\n <React.Fragment>\n — \n <button\n onClick={regenerateTitleAi}\n style={{\n background: 'none',\n backgroundColor: 'transparent',\n border: 'none',\n color: 'currentcolor',\n cursor: 'pointer',\n padding: 0,\n textDecoration: 'underline',\n }}\n type=\"button\"\n >\n {t('plugin-seo:generateAi')}\n </button>\n </React.Fragment>\n )}\n </div>\n <div\n style={{\n color: '#9A9A9A',\n }}\n >\n {t('plugin-seo:lengthTipTitle', { maxLength, minLength })}\n <a\n href=\"https://developers.google.com/search/docs/advanced/appearance/title-link#page-titles\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n {t('plugin-seo:bestPractices')}\n </a>\n .\n </div>\n </div>\n <div\n style={{\n marginBottom: '10px',\n position: 'relative',\n }}\n >\n <TextInput\n AfterInput={AfterInput}\n BeforeInput={BeforeInput}\n Error={errorMessage}\n onChange={setValue}\n path={path}\n readOnly={readOnly}\n required={required}\n showError={showError}\n style={{\n marginBottom: 0,\n }}\n value={value}\n />\n </div>\n <div\n style={{\n alignItems: 'center',\n display: 'flex',\n width: '100%',\n }}\n >\n <LengthIndicator maxLength={maxLength} minLength={minLength} text={value} />\n </div>\n </div>\n )\n}\n"],"names":["FieldLabel","TextInput","useConfig","useDocumentInfo","useField","useForm","useLocale","useTranslation","reduceToSerializableFields","React","useCallback","defaults","LengthIndicator","maxLength","maxLengthDefault","minLength","minLengthDefault","title","MetaTitleComponent","props","field","label","maxLengthFromProps","minLengthFromProps","required","hasGenerateTitleAi","hasGenerateTitleFn","path","readOnly","t","config","routes","api","serverURL","customComponents","AfterInput","BeforeInput","Label","locale","getData","docInfo","errorMessage","setValue","showError","value","regenerateTitle","endpoint","genTitleResponse","fetch","body","JSON","stringify","collectionSlug","doc","docPermissions","globalSlug","hasPublishPermission","hasSavePermission","id","initialData","initialState","undefined","code","credentials","headers","method","result","generatedTitle","json","regenerateTitleAi","div","style","marginBottom","position","className","Fragment","button","disabled","onClick","background","backgroundColor","border","color","cursor","padding","textDecoration","type","a","href","rel","target","Error","onChange","alignItems","display","width","text"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
export const MetaTitleField = ({ hasGenerateAi = false, hasGenerateFn = false, overrides })=>{
|
|
3
|
+
return {
|
|
4
|
+
admin: {
|
|
5
|
+
components: {
|
|
6
|
+
Field: {
|
|
7
|
+
clientProps: {
|
|
8
|
+
hasGenerateTitleAi: hasGenerateAi,
|
|
9
|
+
hasGenerateTitleFn: hasGenerateFn
|
|
10
|
+
},
|
|
11
|
+
path: '@justanarthur/payload-plugin-seo/fields-components#MetaTitleComponent'
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
localized: true,
|
|
16
|
+
name: 'title',
|
|
17
|
+
type: 'text',
|
|
18
|
+
...overrides ?? {}
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/fields/MetaTitle/index.ts"],"sourcesContent":["// @ts-nocheck\nimport type { TextField } from 'payload'\n\ntype FieldFunctionProps = {\n /**\n * Tell the component if the generate AI function is available as configured in the plugin config\n */\n hasGenerateAi?: boolean\n /**\n * Tell the component if the generate function is available as configured in the plugin config\n */\n hasGenerateFn?: boolean\n overrides?: Partial<TextField>\n}\n\ntype FieldFunction = ({ hasGenerateAi, hasGenerateFn, overrides }: FieldFunctionProps) => TextField\n\nexport const MetaTitleField: FieldFunction = ({\n hasGenerateAi = false,\n hasGenerateFn = false,\n overrides,\n}) => {\n return {\n admin: {\n components: {\n Field: {\n clientProps: {\n hasGenerateTitleAi: hasGenerateAi,\n hasGenerateTitleFn: hasGenerateFn,\n },\n path: '@justanarthur/payload-plugin-seo/fields-components#MetaTitleComponent',\n },\n },\n },\n localized: true,\n name: 'title',\n type: 'text',\n ...((overrides as unknown as TextField) ?? {}),\n }\n}\n"],"names":["MetaTitleField","hasGenerateAi","hasGenerateFn","overrides","admin","components","Field","clientProps","hasGenerateTitleAi","hasGenerateTitleFn","path","localized","name","type"],"mappings":"AAAA,cAAc;AAiBd,OAAO,MAAMA,iBAAgC,CAAC,EAC5CC,gBAAgB,KAAK,EACrBC,gBAAgB,KAAK,EACrBC,SAAS,EACV;IACC,OAAO;QACLC,OAAO;YACLC,YAAY;gBACVC,OAAO;oBACLC,aAAa;wBACXC,oBAAoBP;wBACpBQ,oBAAoBP;oBACtB;oBACAQ,MAAM;gBACR;YACF;QACF;QACAC,WAAW;QACXC,MAAM;QACNC,MAAM;QACN,GAAI,AAACV,aAAsC,CAAC,CAAC;IAC/C;AACF,EAAC"}
|