chore: همگام‌سازی وضعیت زندهٔ سرور با مخزن
CI / tests (push) Waiting to run
CI / images (push) Blocked by required conditions

شامل کارهای چند نشست موازی که تا این‌جا فقط روی سرور بود:
- نقشهٔ دفتر مرکزی در فوتر (LazyOfficeMap) + MapViewport/LazyMaps/mapProjects
- صفحهٔ مدیریت مقالات (AdminArticlesPage) + میان‌بر ویرایش پیش‌نویس در وبلاگ
- مهاجرت ۰۰۰۴: updated_at مقالات/پروژه‌ها
- chatbot/Dockerfile: نصب دومرحله‌ای torch (کاربردی برای PyPI فیلترشده)
- seed: خالی‌کردن آمارهای دموی story
- docker-compose: اصلاح پسوند @file میان‌افزارهای Traefik
- حذف فایل موقت frontend/.tmp-style.json و اصلاحات جزئی UI

با این کامیت، آن‌چه روی سرور اجرا می‌شود Exactly همان چیزی است که در مخزن ثبت شده.
This commit is contained in:
aramesh-site deploy
2026-10-26 12:28:28 +00:00
parent 884902e054
commit 14660586c4
23 changed files with 488 additions and 2137 deletions
+30 -2
View File
@@ -24,10 +24,30 @@ function DraftBadge({ className = '' }: { className?: string }) {
)
}
/** میان‌بر ویرایش پیش‌نویس برای هر کارمند واردشده — creator هم بدون حالت ویرایش ادمین */
function DraftEditLink({ id, className = '' }: { id: number; className?: string }) {
const { lang } = useLang()
const { syncEditLang } = useAdmin()
return (
<Link
to={`/admin/write/${id}`}
onClick={() => {
// ویرایشگر با زبان همین صفحه باز شود — کلیک از وبلاگ انگلیسی نباید
// مقاله را در حالت فارسی باز کند (و «دیدن در سایت» را به وبلاگ فارسی ببرد)
syncEditLang(lang)
localStorage.setItem(`aramesh_write_lang_${id}`, lang)
}}
className={`border border-copper/60 bg-ink/90 px-2.5 py-1 text-xs font-bold text-copper backdrop-blur transition-colors duration-200 hover:bg-copper hover:text-char ${className}`}
>
{lang === 'en' ? 'Edit draft' : 'ویرایش پیش‌نویس'}
</Link>
)
}
export function Blog() {
const { articles } = useSite()
const { t, href, lang } = useLang()
const { isEditMode } = useAdmin()
const { isEditMode, isAuthenticated } = useAdmin()
// دکمه «نوشتن مقاله جدید» فقط در حالت ویرایش ادمین دیده می‌شود
const writeButton = isEditMode ? (
@@ -71,8 +91,9 @@ export function Blog() {
<div className="mb-10 flex justify-start">{writeButton}</div>
<Reveal>
<EditableItem resource="articles" item={featured} editHref={`/admin/write/${featured.id}`}>
<div className="relative">
<Link
to={href(`/blog/${featured.slug}`)}
to={href(`/blog/${encodeURIComponent(lang === 'en' && featured.slug_en ? featured.slug_en : featured.slug)}`)}
className="group grid items-stretch border border-ivory/10 bg-char transition-[transform,box-shadow,border-color] duration-300 ease-lux hover:-translate-y-2 hover:border-copper/50 hover:shadow-lift lg:grid-cols-2"
aria-label={`${t('readArticlePrefix')} ${featured.title}`}
>
@@ -109,6 +130,10 @@ export function Blog() {
</div>
</div>
</Link>
{isAuthenticated && featured.status === 'draft' && (
<DraftEditLink id={featured.id} className="absolute top-4 z-10 ltr:right-4 rtl:left-4" />
)}
</div>
</EditableItem>
</Reveal>
@@ -120,6 +145,9 @@ export function Blog() {
{article.status === 'draft' && (
<DraftBadge className="absolute top-3 ltr:left-3 rtl:right-3 z-10" />
)}
{isAuthenticated && article.status === 'draft' && (
<DraftEditLink id={article.id} className="absolute top-3 z-20 ltr:right-3 rtl:left-3" />
)}
<ArticleCard article={article} />
</div>
</EditableItem>