وبلاگ: دکمه «نوشتن مقاله جدید» بالای صفحه + ویرایشگر متن در ابتدای کشو
- دکمه پررنگ «نوشتن مقاله جدید» بالای صفحه وبلاگ (فقط در حالت ویرایش) — ساخت مقاله جدید و باز شدن مستقیم کشوی نوشتن - ترتیب فیلدهای کشوی مقاله: عنوان، سپس ویرایشگر WYSIWYG — نوشتن اول، متادیتا (دسته/تاریخ/اسلاگ و...) بعد - رفع باگ: ساخت رکورد قبلاً کل درخت را reload میکرد و کشوی تازهساختهشده بیدرنگ بسته میشد؛ حالا آیتم ساختهشده بهصورت خوشبینانه به لیست اضافه میشود و کشو باز میماند
This commit is contained in:
@@ -3,6 +3,7 @@ import type { ReactNode } from 'react'
|
|||||||
import { ArrowDownIcon, ArrowUpIcon, PencilIcon, PlusIcon, Trash2Icon } from 'lucide-react'
|
import { ArrowDownIcon, ArrowUpIcon, PencilIcon, PlusIcon, Trash2Icon } from 'lucide-react'
|
||||||
import Swal from 'sweetalert2'
|
import Swal from 'sweetalert2'
|
||||||
import { useSiteData } from '../api'
|
import { useSiteData } from '../api'
|
||||||
|
import type { SiteData } from '../api'
|
||||||
import { useAdmin } from './AdminContext'
|
import { useAdmin } from './AdminContext'
|
||||||
import { adminApi } from './adminClient'
|
import { adminApi } from './adminClient'
|
||||||
import { ENTITIES } from './entities'
|
import { ENTITIES } from './entities'
|
||||||
@@ -142,9 +143,17 @@ export function EditableItem({
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** دکمه افزودن آیتم جدید به یک مجموعه — فقط در حالت ویرایش */
|
/** دکمه افزودن آیتم جدید به یک مجموعه — فقط در حالت ویرایش */
|
||||||
export function AddItemButton({ resource }: { resource: string }) {
|
export function AddItemButton({
|
||||||
|
resource,
|
||||||
|
label,
|
||||||
|
variant = 'cell',
|
||||||
|
}: {
|
||||||
|
resource: string
|
||||||
|
label?: string
|
||||||
|
variant?: 'cell' | 'button'
|
||||||
|
}) {
|
||||||
const { isAuthenticated, isEditMode, runSave } = useAdmin()
|
const { isAuthenticated, isEditMode, runSave } = useAdmin()
|
||||||
const { reload } = useSiteData()
|
const { updateSite } = useSiteData()
|
||||||
const config = ENTITIES[resource]
|
const config = ENTITIES[resource]
|
||||||
const [newItem, setNewItem] = useState<ItemWithId | null>(null)
|
const [newItem, setNewItem] = useState<ItemWithId | null>(null)
|
||||||
|
|
||||||
@@ -153,11 +162,35 @@ export function AddItemButton({ resource }: { resource: string }) {
|
|||||||
const create = () => {
|
const create = () => {
|
||||||
void runSave(async () => {
|
void runSave(async () => {
|
||||||
const created = await adminApi.create<ItemWithId>(config.resource, config.defaults)
|
const created = await adminApi.create<ItemWithId>(config.resource, config.defaults)
|
||||||
reload()
|
// درج خوشبینانه — reload کل درخت را بازسازی میکند و کشوی تازهساختهشده میمیرد
|
||||||
|
updateSite((d) => {
|
||||||
|
const list = d[config.dataKey as keyof SiteData] as unknown as ItemWithId[]
|
||||||
|
if (Array.isArray(list)) list.push(created)
|
||||||
|
})
|
||||||
setNewItem(created)
|
setNewItem(created)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const drawer = newItem ? (
|
||||||
|
<EntityDrawer config={config} item={newItem} deletable onClose={() => setNewItem(null)} />
|
||||||
|
) : null
|
||||||
|
|
||||||
|
if (variant === 'button') {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={create}
|
||||||
|
className="flex items-center gap-2 bg-copper px-6 py-3 text-sm font-bold text-char transition-transform duration-200 hover:scale-105"
|
||||||
|
>
|
||||||
|
<PlusIcon className="h-4 w-4" />
|
||||||
|
{label ?? `افزودن ${config.title}`}
|
||||||
|
</button>
|
||||||
|
{drawer}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
@@ -169,9 +202,7 @@ export function AddItemButton({ resource }: { resource: string }) {
|
|||||||
<span className="text-sm font-light">افزودن {config.title}</span>
|
<span className="text-sm font-light">افزودن {config.title}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{newItem && (
|
{drawer}
|
||||||
<EntityDrawer config={config} item={newItem} deletable onClose={() => setNewItem(null)} />
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,9 +55,14 @@ export const ENTITIES: Record<string, EntityConfig> = {
|
|||||||
resource: 'articles', dataKey: 'articles', title: 'مقالات', kind: 'collection',
|
resource: 'articles', dataKey: 'articles', title: 'مقالات', kind: 'collection',
|
||||||
titleKey: 'title',
|
titleKey: 'title',
|
||||||
fields: [
|
fields: [
|
||||||
F('title', 'عنوان'), F('slug', 'نشانی (slug)'), F('date', 'تاریخ'), F('category', 'دسته'),
|
F('title', 'عنوان'),
|
||||||
F('image', 'تصویر شاخص', 'image'), F('read', 'زمان مطالعه'), F('excerpt', 'چکیده', 'textarea'),
|
|
||||||
F('body', 'متن مقاله', 'wysiwyg'),
|
F('body', 'متن مقاله', 'wysiwyg'),
|
||||||
|
F('excerpt', 'چکیده', 'textarea'),
|
||||||
|
F('image', 'تصویر شاخص', 'image'),
|
||||||
|
F('category', 'دسته'),
|
||||||
|
F('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: '', category: '', image: '', read: '', excerpt: '', body: { type: 'doc', content: [{ type: 'paragraph' }] } },
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ export function Blog() {
|
|||||||
|
|
||||||
<section className="bg-ink py-24 lg:py-32" aria-label="مقالات">
|
<section className="bg-ink py-24 lg:py-32" aria-label="مقالات">
|
||||||
<div className="mx-auto max-w-site px-6 lg:px-10">
|
<div className="mx-auto max-w-site px-6 lg:px-10">
|
||||||
|
<div className="mb-10 flex justify-start">
|
||||||
|
<AddItemButton resource="articles" label="نوشتن مقاله جدید" variant="button" />
|
||||||
|
</div>
|
||||||
<Reveal>
|
<Reveal>
|
||||||
<EditableItem resource="articles" item={featured}>
|
<EditableItem resource="articles" item={featured}>
|
||||||
<Link
|
<Link
|
||||||
@@ -64,7 +67,6 @@ export function Blog() {
|
|||||||
</EditableItem>
|
</EditableItem>
|
||||||
</Reveal>
|
</Reveal>
|
||||||
))}
|
))}
|
||||||
<AddItemButton resource="articles" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user