Improve blog editor, details modal, and header display of first and last name.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
8008ea4db1
commit
27d5cd0186
+50
-25
@@ -2,13 +2,27 @@
|
||||
|
||||
import Link from "next/link";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { ChangeEvent, FormEvent, Suspense, useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
ChangeEvent,
|
||||
FormEvent,
|
||||
Suspense,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import ClothesShell from "@/components/clothes/ClothesShell";
|
||||
import CategoryTreeSelect from "@/components/ui/CategoryTreeSelect";
|
||||
import ImageCropper from "@/components/ui/ImageCropper";
|
||||
import { FormModal } from "@/components/ui/Modal";
|
||||
import RichTextArea from "@/components/ui/RichTextArea";
|
||||
import { CategoryNode } from "@/data/clothes";
|
||||
import { ApiError, uploadMedia } from "@/lib/api";
|
||||
import { createBlog, fetchBlog, updateBlog } from "@/lib/blog-api";
|
||||
import {
|
||||
createBlog,
|
||||
fetchBlog,
|
||||
fetchBlogCategoriesTree,
|
||||
updateBlog,
|
||||
} from "@/lib/blog-api";
|
||||
|
||||
const DEFAULT_IMAGE = "/images/ahmad-ebadi-r5IzkiO08JU-unsplash.jpg";
|
||||
|
||||
@@ -19,8 +33,8 @@ function NewBlogPostForm() {
|
||||
const fileRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const [title, setTitle] = useState("");
|
||||
const [date, setDate] = useState(() => new Date().toISOString().slice(0, 10));
|
||||
const [author, setAuthor] = useState("");
|
||||
const [categoryId, setCategoryId] = useState("");
|
||||
const [categoryTree, setCategoryTree] = useState<CategoryNode[]>([]);
|
||||
const [abstract, setAbstract] = useState("");
|
||||
const [body, setBody] = useState("");
|
||||
const [imagePreview, setImagePreview] = useState(DEFAULT_IMAGE);
|
||||
@@ -39,6 +53,21 @@ function NewBlogPostForm() {
|
||||
metaTitle.trim() || metaDescription.trim() || metaKeywords.trim(),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
try {
|
||||
const cats = await fetchBlogCategoriesTree();
|
||||
if (!cancelled) setCategoryTree(cats);
|
||||
} catch {
|
||||
/* optional */
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!editId) return;
|
||||
let cancelled = false;
|
||||
@@ -49,8 +78,7 @@ function NewBlogPostForm() {
|
||||
const post = await fetchBlog(editId);
|
||||
if (cancelled) return;
|
||||
setTitle(post.title);
|
||||
setDate(post.date);
|
||||
setAuthor(post.author);
|
||||
setCategoryId(post.categoryId || "");
|
||||
setAbstract(post.abstract);
|
||||
setBody(post.body);
|
||||
setImagePreview(post.image);
|
||||
@@ -111,10 +139,14 @@ function NewBlogPostForm() {
|
||||
title: title.trim(),
|
||||
summary: abstract.trim() || undefined,
|
||||
body: body || undefined,
|
||||
author: author.trim() || undefined,
|
||||
metaTitle: metaTitle.trim() || undefined,
|
||||
metaDescription: metaDescription.trim() || undefined,
|
||||
published: true,
|
||||
...(categoryId
|
||||
? { categoryId }
|
||||
: editId
|
||||
? { categoryId: null }
|
||||
: {}),
|
||||
...(imageUrl ? { imageUrl, imageKey } : {}),
|
||||
};
|
||||
|
||||
@@ -145,7 +177,7 @@ function NewBlogPostForm() {
|
||||
<ClothesShell
|
||||
eyebrow={editId ? "Edit Post" : "New Post"}
|
||||
title={editId ? "ویرایش مطلب" : "مطلب جدید"}
|
||||
description="کاور ۳:۲ را برش دهید و محتوای مطلب را کامل کنید."
|
||||
description="کاور ۳:۲ را برش دهید و محتوای مطلب را کامل کنید. تاریخ و نویسنده بهصورت خودکار ثبت میشوند."
|
||||
breadcrumbs={[
|
||||
{ label: "داشبورد", href: "/" },
|
||||
{ label: "بلاگ", href: "/blog" },
|
||||
@@ -206,22 +238,13 @@ function NewBlogPostForm() {
|
||||
/>
|
||||
</div>
|
||||
<div className="clothes-field sm:col-span-4">
|
||||
<label htmlFor="blog-date">تاریخ</label>
|
||||
<input
|
||||
id="blog-date"
|
||||
type="date"
|
||||
dir="ltr"
|
||||
value={date}
|
||||
onChange={(e) => setDate(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="clothes-field sm:col-span-12">
|
||||
<label htmlFor="blog-author">نویسنده</label>
|
||||
<input
|
||||
id="blog-author"
|
||||
value={author}
|
||||
onChange={(e) => setAuthor(e.target.value)}
|
||||
placeholder="نام نویسنده"
|
||||
<label htmlFor="blog-category">دستهبندی</label>
|
||||
<CategoryTreeSelect
|
||||
id="blog-category"
|
||||
nodes={categoryTree}
|
||||
value={categoryId}
|
||||
onChange={setCategoryId}
|
||||
placeholder="انتخاب دسته بلاگ..."
|
||||
/>
|
||||
</div>
|
||||
<div className="clothes-field sm:col-span-12">
|
||||
@@ -367,7 +390,9 @@ function NewBlogPostForm() {
|
||||
|
||||
export default function NewBlogPostPage() {
|
||||
return (
|
||||
<Suspense fallback={<p className="p-6 text-sm text-muted">در حال بارگذاری...</p>}>
|
||||
<Suspense
|
||||
fallback={<p className="p-6 text-sm text-muted">در حال بارگذاری...</p>}
|
||||
>
|
||||
<NewBlogPostForm />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user