From 17345daa816c21108bad6c4ca825ce31de7057cf Mon Sep 17 00:00:00 2001 From: MMD Date: Mon, 7 Sep 2026 02:35:41 +0330 Subject: [PATCH] =?UTF-8?q?=D9=88=D8=A8=D9=84=D8=A7=DA=AF:=20=D8=B5=D9=81?= =?UTF-8?q?=D8=AD=D9=87=20=D8=AA=D9=85=D8=A7=D9=85=E2=80=8C=D8=B9=D8=B1?= =?UTF-8?q?=D8=B6=20=C2=AB=D9=86=D9=88=D8=B4=D8=AA=D9=86=20=D9=85=D9=82?= =?UTF-8?q?=D8=A7=D9=84=D9=87=C2=BB=20=E2=80=94=20=D9=85=D8=AD=DB=8C=D8=B7?= =?UTF-8?q?=20=D9=86=D9=88=D8=B4=D8=AA=D9=86=20=D9=85=D8=AA=D9=85=D8=B1?= =?UTF-8?q?=DA=A9=D8=B2=20=D8=A8=D8=B1=D8=A7=DB=8C=20=D8=A7=D8=AF=D9=85?= =?UTF-8?q?=DB=8C=D9=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /admin/write (مقاله جدید) و /admin/write/:id (ویرایش) — صفحه کامل بدون چرخه سایت: نوار بالا (بازگشت، وضعیت ذخیره، ذخیره، دیدن در سایت، حذف)، عنوان بزرگ، تصویر شاخص، ویرایشگر TipTap تمام‌ارتفاع و بخش جزئیات انتشار (چکیده، دسته، تاریخ، زمان مطالعه، slug) - ذخیره خودکار با debounce + flush هنگام خروج؛ اولین ذخیره مقاله را منتشر می‌کند و مسیر به /admin/write/:id تغییر می‌کند - قلم‌ویژه مقاله‌ها (مداد روی کارت) ادمین را به همین صفحه می‌برد (editHref روی EditableItem)؛ لینک‌های data-admin-link در حالت ویرایش کار می‌کنند - رفع: create-on-unmount حذف شد (با draft قدیمی مقاله سرگردانی می‌ساخت) — unmount فقط برای مقاله ساخته‌شده PATCH می‌زند --- frontend/src/App.tsx | 13 +- frontend/src/admin/AdminContext.tsx | 5 +- frontend/src/admin/ArticleWritePage.tsx | 301 ++++++++++++++++++++++ frontend/src/admin/Editable.tsx | 22 +- frontend/src/components/home/Articles.tsx | 2 +- frontend/src/pages/Blog.tsx | 16 +- 6 files changed, 344 insertions(+), 15 deletions(-) create mode 100644 frontend/src/admin/ArticleWritePage.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index f7e4a50..8cb9a24 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -19,6 +19,7 @@ import { SiteProvider, useSiteData } from './api'; import { AdminProvider, useAdmin } from './admin/AdminContext'; import { AdminBar } from './admin/AdminBar'; import { AdminLoginPage } from './admin/AdminLoginPage'; +import { ArticleWritePage } from './admin/ArticleWritePage'; function ScrollToTop() { const { pathname } = useLocation(); @@ -41,6 +42,8 @@ function AnimatedRoutes() { } /> + } /> + } /> } /> } /> } /> @@ -61,15 +64,15 @@ function AnimatedRoutes() { function AppChrome() { const { pathname } = useLocation(); const { isAuthenticated } = useAdmin(); - const isLoginPage = pathname === '/admin/login'; + const isAdminPage = pathname.startsWith('/admin'); return ( <> - {!isLoginPage &&
} + {!isAdminPage &&
} - {!isLoginPage &&