Update blog editor features
This commit is contained in:
@@ -1,37 +1,51 @@
|
||||
import type { SiteData } from '../api'
|
||||
|
||||
export type FieldType = 'text' | 'textarea' | 'number' | 'image' | 'list' | 'wysiwyg'
|
||||
export type FieldType = 'text' | 'textarea' | 'number' | 'image' | 'list' | 'wysiwyg' | 'select' | 'date'
|
||||
|
||||
export type FieldConfig = {
|
||||
name: string
|
||||
label: string
|
||||
type: FieldType
|
||||
hint?: string
|
||||
/** فقط برای type === 'select' — گزینههای ثابت react-select */
|
||||
options?: string[]
|
||||
/** ویجت سفارشی نوع list — 'tags' یعنی react-select قابل ساخت (Creatable) */
|
||||
ui?: 'lines' | 'tags'
|
||||
}
|
||||
|
||||
export type EntityConfig = {
|
||||
/** مسیر منبع در پنل مدیریت، مثل services یا why-us */
|
||||
resource: string
|
||||
/** کلید همان منبع در پاسخ GET /api/site */
|
||||
dataKey: string
|
||||
title: string
|
||||
/** مجموعه یا رکورد یگانه */
|
||||
kind: 'collection' | 'singleton'
|
||||
/** فیلدی که عنوان آیتم را نشان میدهد */
|
||||
titleKey: string
|
||||
fields: FieldConfig[]
|
||||
/** مقادیر پیشفرض برای «افزودن» */
|
||||
defaults: Record<string, unknown>
|
||||
}
|
||||
|
||||
const F = (name: string, label: string, type: FieldType = 'text', hint?: string): FieldConfig => ({
|
||||
const F = (
|
||||
name: string,
|
||||
label: string,
|
||||
type: FieldType = 'text',
|
||||
hint?: string,
|
||||
extra?: Partial<FieldConfig>,
|
||||
): FieldConfig => ({
|
||||
name,
|
||||
label,
|
||||
type,
|
||||
hint,
|
||||
...extra,
|
||||
})
|
||||
|
||||
/** پیکربندی همه منابع قابل ویرایش — هم مجموعهها و هم رکوردهای یگانه */
|
||||
/** دستهبندیهای استاندارد مقاله — با react-select در کشو و صفحه نوشتن نمایش داده میشوند */
|
||||
export const ARTICLE_CATEGORIES = [
|
||||
'معماری و ساخت',
|
||||
'سرمایهگذاری ملکی',
|
||||
'طراحی داخلی',
|
||||
'اخبار و اطلاعیهها',
|
||||
'یادداشت مدیریت',
|
||||
]
|
||||
|
||||
export const ENTITIES: Record<string, EntityConfig> = {
|
||||
services: {
|
||||
resource: 'services', dataKey: 'services', title: 'خدمات', kind: 'collection',
|
||||
@@ -57,14 +71,31 @@ export const ENTITIES: Record<string, EntityConfig> = {
|
||||
fields: [
|
||||
F('title', 'عنوان'),
|
||||
F('body', 'متن مقاله', 'wysiwyg'),
|
||||
F('excerpt', 'چکیده', 'textarea'),
|
||||
F('excerpt', 'چکیده (روی کارت مقاله)'),
|
||||
F('meta_description', 'توضیحات سئو (Meta Description)', 'textarea', '۱۵۰ تا ۱۶۰ کاراکتر — زیر عنوان در نتایج گوگل نمایش داده میشود'),
|
||||
F('image', 'تصویر شاخص', 'image'),
|
||||
F('category', 'دسته'),
|
||||
F('date', 'تاریخ'),
|
||||
F('read', 'زمان مطالعه'),
|
||||
F('category', 'دستهبندی (Category)', 'select', undefined, { options: ARTICLE_CATEGORIES }),
|
||||
F('tags', 'هشتگها / برچسبها', 'list', 'با Enter هر هشتگ جدید را اضافه کنید', { ui: 'tags' }),
|
||||
F('author', 'نویسنده'),
|
||||
F('date', 'تاریخ انتشار (شمسی)', 'date'),
|
||||
F('read', 'زمان مطالعه (دقیقه)'),
|
||||
F('slug', 'نشانی (slug)'),
|
||||
],
|
||||
defaults: { title: 'مقاله جدید', slug: `article-${Date.now()}`, date: '', category: '', image: '', read: '', excerpt: '', body: { type: 'doc', content: [{ type: 'paragraph' }] } },
|
||||
defaults: {
|
||||
title: 'مقاله جدید',
|
||||
slug: `article-${Date.now()}`,
|
||||
date: new Date().toISOString().split('T')[0],
|
||||
category: ARTICLE_CATEGORIES[0],
|
||||
tags: ['مدیریت پروژه', 'ساختوساز'],
|
||||
image: '',
|
||||
image_alt: '',
|
||||
author: '',
|
||||
meta_description: '',
|
||||
read: '۵ دقیقه',
|
||||
excerpt: '',
|
||||
seo_keyphrase: '',
|
||||
body: { type: 'doc', content: [{ type: 'paragraph' }] }
|
||||
},
|
||||
},
|
||||
testimonials: {
|
||||
resource: 'testimonials', dataKey: 'testimonials', title: 'نظرات مشتریان', kind: 'collection',
|
||||
@@ -132,7 +163,6 @@ export const ENTITIES: Record<string, EntityConfig> = {
|
||||
fields: [F('label', 'عنوان'), F('href', 'مسیر (مثل /about)')],
|
||||
defaults: { label: 'آیتم جدید', href: '/' },
|
||||
},
|
||||
|
||||
seo_meta: {
|
||||
resource: 'seo-meta', dataKey: 'seo_meta', title: 'سئوی صفحه', kind: 'collection',
|
||||
titleKey: 'page_key',
|
||||
@@ -143,8 +173,6 @@ export const ENTITIES: Record<string, EntityConfig> = {
|
||||
],
|
||||
defaults: { page_key: '', title: '', description: '' },
|
||||
},
|
||||
|
||||
// ---------- رکوردهای یگانه ----------
|
||||
brand: {
|
||||
resource: 'brand', dataKey: 'brand', title: 'برند و تماس', kind: 'singleton',
|
||||
titleKey: 'name',
|
||||
@@ -197,7 +225,6 @@ export const ENTITIES: Record<string, EntityConfig> = {
|
||||
},
|
||||
}
|
||||
|
||||
/** دسترسی به آرایه/شیء منبع از درخت داده سایت */
|
||||
export function getEntityData(data: SiteData, config: EntityConfig): Record<string, unknown> & { id: number }[] | (Record<string, unknown> & { id: number }) {
|
||||
return data[config.dataKey as keyof SiteData] as never
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user