feat(content): public Blog + Learn sections and static CMS pages (full-stack)

Adds the missing public-facing content pages and their admin authoring, all
powered by the existing content-svc Blog entity discriminated by `kind`.

Backend (content-svc):
- BlogKind enum += Learn, Page (reuses Blog CRUD/SEO/slug/publish for all three).
- SQL migration services/content/migrations/001_blog_kind_learn_page.sql
  (ALTER TYPE content.blog_kind ADD VALUE 'Learn','Page').

Frontend (public, Next.js):
- lib/content-api.ts: fetchArticles(kind) / fetchArticle(slug) / fetchPage(slug)
  with safe empty/null fallbacks.
- components/content: article-ui (card/list/detail + RTL prose), CmsPageContent,
  CmsRoute (admin-authored page or localized built-in fallback copy).
- Routes: /blog, /blog/[slug], /learn, /learn/[slug] and static pages
  /about /contact /careers /privacy /terms /cookies /help.
- Navbar "tutorials" → /learn; all footer links now resolve.

Admin:
- AdminResource: new `fixedValues` option (injects kind on create/update).
- learnConfig (kind=Learn) + pagesConfig (kind=Page) reuse the /v1/blogs endpoint;
  /admin/learn + /admin/pages routes + nav items.

i18n: blog, learn and 7 *Page namespaces added to both fa.json and en.json
(verified key parity); admin nav labels learn/pages. Frontend tsc clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-11 22:43:25 +03:30
parent 6cf8716d7e
commit c92de06c28
25 changed files with 802 additions and 3 deletions
+55
View File
@@ -187,6 +187,59 @@
"socialLinkedIn": "لینکدین",
"socialYouTube": "یوتیوب"
},
"blog": {
"metaTitle": "وبلاگ فلت‌رندر",
"metaDescription": "مقاله‌ها، خبرها و راهنماهای ساخت ویدیو و تصویر.",
"pageTitle": "وبلاگ",
"pageDescription": "تازه‌ترین مقاله‌ها، خبرها و ایده‌ها دربارهٔ ساخت ویدیو و تصویر.",
"readMore": "ادامهٔ مطلب",
"views": "بازدید",
"empty": "هنوز مقاله‌ای منتشر نشده است."
},
"learn": {
"metaTitle": "آموزش فلت‌رندر",
"metaDescription": "آموزش‌های گام‌به‌گام برای ساخت ویدیو و تصویر حرفه‌ای.",
"pageTitle": "آموزش",
"pageDescription": "آموزش‌های گام‌به‌گام و راهنماهای کاربردی برای استفاده از فلت‌رندر.",
"readMore": "مشاهدهٔ آموزش",
"views": "بازدید",
"empty": "هنوز آموزشی منتشر نشده است."
},
"aboutPage": {
"title": "دربارهٔ ما",
"lead": "فلت‌رندر، ساخت ویدیو و تصویر حرفه‌ای را برای همه ساده می‌کند.",
"body": "فلت‌رندر یک پلتفرم آنلاین برای ساخت ویدیو و تصویر با کمک قالب‌های آماده و ابزارهای هوشمند است.\n\nمأموریت ما این است که هر کسی، بدون نیاز به دانش تخصصی طراحی یا موشن‌گرافیک، بتواند در چند دقیقه محتوای حرفه‌ای بسازد."
},
"contactPage": {
"title": "تماس با ما",
"lead": "خوشحال می‌شویم از شما بشنویم.",
"body": "برای پشتیبانی، همکاری یا هر پرسشی با ما در تماس باشید.\n\nایمیل: support@flatrender.com"
},
"careersPage": {
"title": "فرصت‌های شغلی",
"lead": "به تیم فلت‌رندر بپیوندید.",
"body": "ما همیشه به دنبال افراد بااستعداد و علاقه‌مند هستیم.\n\nبرای آگاهی از موقعیت‌های شغلی، رزومهٔ خود را به jobs@flatrender.com ارسال کنید."
},
"privacyPage": {
"title": "حریم خصوصی",
"lead": "نحوهٔ نگهداری و استفادهٔ ما از اطلاعات شما.",
"body": "حفظ حریم خصوصی شما برای ما اهمیت دارد. این صفحه نحوهٔ گردآوری، استفاده و محافظت از اطلاعات شما را توضیح می‌دهد.\n\nاین متن نمونه است و باید پیش از انتشار نهایی توسط مدیر تکمیل شود."
},
"termsPage": {
"title": "شرایط استفاده",
"lead": "قوانین استفاده از خدمات فلت‌رندر.",
"body": "با استفاده از فلت‌رندر، شرایط زیر را می‌پذیرید.\n\nاین متن نمونه است و باید پیش از انتشار نهایی توسط مدیر تکمیل شود."
},
"cookiesPage": {
"title": "سیاست کوکی",
"lead": "نحوهٔ استفادهٔ ما از کوکی‌ها.",
"body": "ما از کوکی‌ها برای بهبود تجربهٔ شما در سایت استفاده می‌کنیم.\n\nاین متن نمونه است و باید پیش از انتشار نهایی توسط مدیر تکمیل شود."
},
"helpPage": {
"title": "مرکز راهنما",
"lead": "پاسخ پرسش‌های پرتکرار و راهنمای استفاده.",
"body": "به مرکز راهنمای فلت‌رندر خوش آمدید.\n\nبرای پرسش‌های بیشتر، بخش آموزش را ببینید یا با پشتیبانی تماس بگیرید."
},
"auth": {
"signIn": "ورود",
"signUp": "ثبت‌نام",
@@ -324,6 +377,8 @@
"tags": "برچسب‌ها",
"fonts": "فونت‌ها",
"blogs": "بلاگ",
"learn": "آموزش‌ها",
"pages": "برگه‌ها",
"slides": "اسلایدها",
"users": "کاربران",
"plans": "پلن‌ها",