feat(admin): صفحهٔ اختصاصی ویرایش/ساخت پروژه + گالری فقط با آپلود به MinIO

- /admin/projects/new و /admin/projects/:id — همهٔ فیلدها در یک صفحه با
  ورودی دوزبانهٔ صریح (فارسی/English)، ذخیره، حذف
- GalleryField تازه: گالری چندتصویری فقط با آپلود به MinIO (حذف/جابه‌جایی/
  افزودن چندفایلی) — فیلد «هر خط یک URL» دیگر استفاده نمی‌شود
- مدادِ کارت پروژه و دکمهٔ «افزودن پروژه» به صفحهٔ اختصاصی هدایت می‌شوند؛
  دکمهٔ ویرایش روی صفحهٔ جزئیات هم لینک همان صفحه است
This commit is contained in:
aramesh-site deploy
2026-09-28 10:33:05 +00:00
parent edcbd0dc58
commit 0c87a287a3
6 changed files with 521 additions and 10 deletions
+9 -8
View File
@@ -10,7 +10,6 @@ import { useEffect } from 'react';
import { useSite, useStatusLabel } from '../api';
import { useLang } from '../i18n/lang';
import { applySeo } from '../seo';
import { SingletonPill } from '../admin/Editable';
export function ProjectDetail() {
const { slug } = useParams<{ slug: string }>()
@@ -86,13 +85,15 @@ export function ProjectDetail() {
</nav>
<h1 className="mt-5 max-w-[700px] text-hero font-bold text-ivory">{project.title}</h1>
<p className="mt-5 max-w-2xl text-base font-light leading-9 text-ivory/70">{project.summary}</p>
{/* ویرایش این پروژه — فقط در حالت ویرایش ادمین */}
<div className="mt-5 flex items-start gap-3 [&>div]:!mt-0">
<SingletonPill
resource="projects"
label="ویرایش این پروژه (عنوان، مشخصات، گالری، متن)"
select={(d) => d.projects.find((p) => p.slug === slug)}
/>
{/* ویرایش این پروژه — صفحهٔ اختصاصی ویرایش */}
<div className="mt-5">
<Link
to={`/admin/projects/${project.id}`}
data-admin-link
className="inline-flex items-center gap-2 rounded-full border border-copper/50 bg-ink/90 px-4 py-2 text-xs font-light text-copper backdrop-blur-sm transition-colors duration-200 hover:bg-copper hover:text-char"
>
ویرایش این پروژه (عنوان، مشخصات، گالری، متن)
</Link>
</div>
</div>
</section>
+2 -2
View File
@@ -160,7 +160,7 @@ export function Projects() {
return (
<Reveal key={project.id} delay={0.05 * (index % itemsPerPage)} className="h-full">
{fromDb ? (
<EditableItem resource="projects" item={project} className="h-full">
<EditableItem resource="projects" item={project} editHref={`/admin/projects/${project.id}`} className="h-full">
{card}
</EditableItem>
) : (
@@ -169,7 +169,7 @@ export function Projects() {
</Reveal>
);
})}
{fromDb && <AddItemButton resource="projects" />}
{fromDb && <AddItemButton resource="projects" editHrefBase="/admin/projects" />}
</div>
{/* Load More Button */}