Exports the fields from the SEO plugin so that they can be used anywhere
inside a collection, new exports:
```ts
import { MetaDescriptionField, MetaImageField, MetaTitleField, OverviewField, PreviewField } from '@payloadcms/plugin-seo/fields'
// Used as fields
MetaImageField({
relationTo: 'media',
hasGenerateFn: true,
})
MetaDescriptionField({
hasGenerateFn: true,
})
MetaTitleField({
hasGenerateFn: true,
})
PreviewField({
hasGenerateFn: true,
titlePath: 'meta.title',
descriptionPath: 'meta.description',
})
OverviewField({
titlePath: 'meta.title',
descriptionPath: 'meta.description',
imagePath: 'meta.image',
})
```
84 lines
2.6 KiB
TypeScript
84 lines
2.6 KiB
TypeScript
'use client'
|
|
|
|
import type { FormField, UIField } from 'payload'
|
|
|
|
import { useAllFormFields, useForm, useTranslation } from '@payloadcms/ui'
|
|
import React, { useCallback, useEffect, useState } from 'react'
|
|
|
|
import type { PluginSEOTranslationKeys, PluginSEOTranslations } from '../../translations/index.js'
|
|
|
|
import { defaults } from '../../defaults.js'
|
|
|
|
const {
|
|
description: { maxLength: maxDesc, minLength: minDesc },
|
|
title: { maxLength: maxTitle, minLength: minTitle },
|
|
} = defaults
|
|
|
|
type OverviewProps = UIField & {
|
|
descriptionPath?: string
|
|
imagePath?: string
|
|
titlePath?: string
|
|
}
|
|
|
|
export const OverviewComponent: React.FC<OverviewProps> = ({
|
|
descriptionPath: descriptionPathFromContext,
|
|
imagePath: imagePathFromContext,
|
|
titlePath: titlePathFromContext,
|
|
}) => {
|
|
const {
|
|
// dispatchFields,
|
|
getFields,
|
|
} = useForm()
|
|
|
|
const descriptionPath = descriptionPathFromContext || 'meta.description'
|
|
const titlePath = titlePathFromContext || 'meta.title'
|
|
const imagePath = imagePathFromContext || 'meta.image'
|
|
|
|
const [
|
|
{
|
|
[descriptionPath]: { value: metaDesc } = {} as FormField,
|
|
[imagePath]: { value: metaImage } = {} as FormField,
|
|
[titlePath]: { value: metaTitle } = {} as FormField,
|
|
},
|
|
] = useAllFormFields()
|
|
const { t } = useTranslation<PluginSEOTranslations, PluginSEOTranslationKeys>()
|
|
|
|
const [titleIsValid, setTitleIsValid] = useState<boolean | undefined>()
|
|
const [descIsValid, setDescIsValid] = useState<boolean | undefined>()
|
|
const [imageIsValid, setImageIsValid] = useState<boolean | undefined>()
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
const resetAll = useCallback(() => {
|
|
const fields = getFields()
|
|
const fieldsWithoutMeta = fields
|
|
fieldsWithoutMeta['meta.title'].value = ''
|
|
fieldsWithoutMeta['meta.description'].value = ''
|
|
fieldsWithoutMeta['meta.image'].value = ''
|
|
// dispatchFields(fieldsWithoutMeta);
|
|
}, [getFields])
|
|
|
|
useEffect(() => {
|
|
if (typeof metaTitle === 'string')
|
|
setTitleIsValid(metaTitle.length >= minTitle && metaTitle.length <= maxTitle)
|
|
if (typeof metaDesc === 'string')
|
|
setDescIsValid(metaDesc.length >= minDesc && metaDesc.length <= maxDesc)
|
|
setImageIsValid(Boolean(metaImage))
|
|
}, [metaTitle, metaDesc, metaImage])
|
|
|
|
const testResults = [titleIsValid, descIsValid, imageIsValid]
|
|
|
|
const numberOfPasses = testResults.filter(Boolean).length
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
marginBottom: '20px',
|
|
}}
|
|
>
|
|
<div>
|
|
{t('plugin-seo:checksPassing', { current: numberOfPasses, max: testResults.length })}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|