Add website schema settings, SEO meta overrides, and resilient bulk SMS.
Business admins can configure site-wide Schema.org and optional per-item SEO title/description; mass SMS continues on failures with an end report. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
15aad9f9d8
commit
c2ede07e73
@@ -4,6 +4,7 @@ import { SearchableSelect } from '../components/SearchableSelect'
|
||||
import { ImageCropper } from '../components/ImageCropper'
|
||||
import { TagInput } from '../components/TagInput'
|
||||
import { RichTextEditor } from '../components/RichTextEditor'
|
||||
import { SeoMetaFields } from '../components/SeoMetaFields'
|
||||
import { Breadcrumbs } from '../components/Breadcrumbs'
|
||||
import { useToast } from '../context/ToastContext'
|
||||
import { useT } from '../i18n/useT'
|
||||
@@ -26,6 +27,7 @@ import type { Category } from '../types/category'
|
||||
import type { VideoProvider } from '../types/video'
|
||||
import { VIDEO_PROVIDER_OPTIONS } from '../types/video'
|
||||
import { flattenCategories } from '../utils/categories'
|
||||
import { seoMetaPayload } from '../utils/seoMeta'
|
||||
import pageStyles from '../components/PageContent.module.css'
|
||||
import styles from './AddNewProductPage.module.css'
|
||||
|
||||
@@ -46,6 +48,8 @@ export function AddNewVideoPage() {
|
||||
const [embedCode, setEmbedCode] = useState('')
|
||||
const [coverImage, setCoverImage] = useState<string | null>(null)
|
||||
const [tags, setTags] = useState<string[]>([])
|
||||
const [seoMetaTitle, setSeoMetaTitle] = useState('')
|
||||
const [seoMetaDescription, setSeoMetaDescription] = useState('')
|
||||
const [featuredMediaId, setFeaturedMediaId] = useState<string | null>(null)
|
||||
const [loaded, setLoaded] = useState(!isEdit)
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
@@ -93,6 +97,8 @@ export function AddNewVideoPage() {
|
||||
setEmbedCode(form.embedCode)
|
||||
setCoverImage(form.coverImage)
|
||||
setTags(form.tags)
|
||||
setSeoMetaTitle(form.seoMetaTitle)
|
||||
setSeoMetaDescription(form.seoMetaDescription)
|
||||
setFeaturedMediaId(form.featuredMediaId)
|
||||
setLoaded(true)
|
||||
} catch (err) {
|
||||
@@ -130,6 +136,7 @@ export function AddNewVideoPage() {
|
||||
categoryId: categoryId || undefined,
|
||||
featuredMediaId: nextFeaturedMediaId ?? undefined,
|
||||
tags,
|
||||
...seoMetaPayload(seoMetaTitle, seoMetaDescription),
|
||||
status: 'published' as const,
|
||||
}
|
||||
|
||||
@@ -322,6 +329,19 @@ export function AddNewVideoPage() {
|
||||
<label>{t('video.form.tags')}</label>
|
||||
<TagInput tags={tags} onChange={setTags} />
|
||||
</div>
|
||||
|
||||
<SeoMetaFields
|
||||
seoMetaTitle={seoMetaTitle}
|
||||
seoMetaDescription={seoMetaDescription}
|
||||
onTitleChange={setSeoMetaTitle}
|
||||
onDescriptionChange={setSeoMetaDescription}
|
||||
disabled={isSubmitting}
|
||||
hint={t('seo.meta.hint')}
|
||||
titleLabel={t('seo.meta.title')}
|
||||
descriptionLabel={t('seo.meta.description')}
|
||||
titlePlaceholder={t('seo.meta.titlePlaceholder')}
|
||||
descriptionPlaceholder={t('seo.meta.descriptionPlaceholder')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.actions}>
|
||||
|
||||
Reference in New Issue
Block a user