"use client"; import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { FormEvent, useCallback, useEffect, useState } from "react"; import ClothesShell from "@/components/clothes/ClothesShell"; import IconButton, { ClearFilterIcon, EditIcon, FilterIcon, MetaTagsIcon, TrashIcon, } from "@/components/ui/IconButton"; import Modal, { FormModal } from "@/components/ui/Modal"; import Pagination, { usePagination } from "@/components/ui/Pagination"; import { BlogPost, formatBlogDate } from "@/data/blog"; import { ApiError } from "@/lib/api"; import { deleteBlog, fetchBlogs, updateBlog } from "@/lib/blog-api"; import { useConfirm } from "@/components/ui/ConfirmDialog"; const PAGE_SIZE = 3; type Filters = { name: string; dateFrom: string; dateTo: string; }; const emptyFilters: Filters = { name: "", dateFrom: "", dateTo: "", }; export default function BlogListPage() { const router = useRouter(); const confirmDialog = useConfirm(); const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [draft, setDraft] = useState(emptyFilters); const [applied, setApplied] = useState(emptyFilters); const [detailPost, setDetailPost] = useState(null); const [metaPost, setMetaPost] = useState(null); const [metaTitle, setMetaTitle] = useState(""); const [metaDescription, setMetaDescription] = useState(""); const [metaKeywords, setMetaKeywords] = useState(""); const [savingMeta, setSavingMeta] = useState(false); const reload = useCallback(async () => { setLoading(true); setError(null); try { setItems(await fetchBlogs()); } catch (err) { setError( err instanceof ApiError ? err.message : "بارگذاری بلاگ ناموفق بود.", ); } finally { setLoading(false); } }, []); useEffect(() => { void reload(); }, [reload]); const list = items.filter((post) => { const q = applied.name.trim(); const matchesName = !q || post.title.includes(q) || post.author.includes(q) || post.abstract.includes(q); const fromOk = !applied.dateFrom || post.date >= applied.dateFrom; const toOk = !applied.dateTo || post.date <= applied.dateTo; return matchesName && fromOk && toOk; }); const { page, setPage, pageItems, totalPages, totalItems, pageSize } = usePagination(list, PAGE_SIZE, JSON.stringify(applied)); function openMeta(post: BlogPost) { setMetaPost(post); setMetaTitle(post.metaTitle); setMetaDescription(post.metaDescription); setMetaKeywords(post.metaKeywords); } function closeMeta() { setMetaPost(null); } async function saveMeta(event: FormEvent) { event.preventDefault(); if (!metaPost) return; setSavingMeta(true); setError(null); try { const updated = await updateBlog(metaPost.id, { metaTitle: metaTitle.trim() || null, metaDescription: metaDescription.trim() || null, }); setItems((prev) => prev.map((post) => post.id === metaPost.id ? { ...updated, metaKeywords: metaKeywords.trim() } : post, ), ); closeMeta(); } catch (err) { setError( err instanceof ApiError ? err.message : "ذخیره متا ناموفق بود.", ); } finally { setSavingMeta(false); } } async function removePost(id: string) { if (!(await confirmDialog("این مطلب حذف شود؟"))) return; setError(null); try { await deleteBlog(id); setItems((prev) => prev.filter((post) => post.id !== id)); } catch (err) { setError( err instanceof ApiError ? err.message : "حذف مطلب ناموفق بود.", ); } } return ( <>
مدیریت دسته‌بندی‌ها
{error ? (

{error}

) : null}
setDraft((prev) => ({ ...prev, name: e.target.value })) } placeholder="عنوان، نویسنده..." />
setDraft((prev) => ({ ...prev, dateFrom: e.target.value })) } />
setDraft((prev) => ({ ...prev, dateTo: e.target.value })) } />
setApplied(draft)} > { setDraft(emptyFilters); setApplied(emptyFilters); }} >
{loading ? (

در حال بارگذاری...

) : ( <>
{pageItems.map((post, i) => (
setDetailPost(post)} >
{post.title}

{post.title}

{post.categoryName ? `${post.categoryName} · ${post.author}` : post.author}

{post.abstract}

{post.tags.length ? (
{post.tags.map((tag) => ( {tag} ))}
) : null}
e.stopPropagation()} > router.push(`/blog/new?edit=${post.id}`)} > openMeta(post)} > void removePost(post.id)} >
))} {list.length === 0 ? (

مطلبی با این فیلترها پیدا نشد.

) : null}
{list.length > 0 ? ( ) : null} )}
setDetailPost(null)} wide="full" footer={ } > {detailPost ? (
{detailPost.title}

{detailPost.title}

{detailPost.author ? ` · ${detailPost.author}` : null}

دسته‌بندی
{detailPost.categoryName || "—"}
نویسنده
{detailPost.author || "—"}
{detailPost.abstract ? (

خلاصه

{detailPost.abstract}

) : null} {detailPost.body ? (

متن

) : null} {detailPost.tags.length ? (

برچسب‌ها

{detailPost.tags.map((tag) => ( {tag} ))}
) : null}
) : null}
setMetaTitle(e.target.value)} placeholder="SEO title" />