Add e-payment UI, checkout payment result, and legacy migrate domain lookup.

Wire Mellat settings in business dashboard, customer bank return page with payment details, and super-admin migrate modal domain confirmation.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-13 09:51:22 +03:30
co-authored by Cursor
parent a11f9643bb
commit cc94b929e0
54 changed files with 6415 additions and 96 deletions
+499 -18
View File
@@ -38,6 +38,11 @@ const en = {
'nav.finance.invoices': 'Invoices',
'nav.finance.transactions': 'Transactions',
'nav.settings': 'Settings',
'nav.content': 'Content Management',
'nav.content.blog': 'News & Articles',
'nav.content.videos': 'Videos',
'nav.content.instructions': 'Instructions',
'nav.content.overview': 'Overview',
'nav.blog': 'Blog',
'nav.blog.overview': 'Overview',
'nav.blog.list': 'My Blogs',
@@ -50,6 +55,24 @@ const en = {
'nav.portfolios.new': 'Add New Portfolio',
'nav.portfolios.categories': 'Categories',
'nav.portfolios.settings': 'Settings',
'nav.videos': 'Videos',
'nav.videos.overview': 'Overview',
'nav.videos.list': 'My Videos',
'nav.videos.new': 'Add New Video',
'nav.videos.categories': 'Categories',
'nav.videos.settings': 'Settings',
'nav.instructions': 'Instructions',
'nav.instructions.overview': 'Overview',
'nav.instructions.list': 'My Instructions',
'nav.instructions.new': 'Add New Instruction',
'nav.instructions.categories': 'Categories',
'nav.instructions.settings': 'Settings',
'nav.instructions': 'Instructions',
'nav.instructions.overview': 'Overview',
'nav.instructions.list': 'My Instructions',
'nav.instructions.new': 'Add New Instruction',
'nav.instructions.categories': 'Categories',
'nav.instructions.settings': 'Settings',
'nav.website': 'Website',
'nav.website.overview': 'Overview',
'nav.website.sliders': 'Sliders',
@@ -154,6 +177,10 @@ const en = {
'bc.blogDetails': 'Blog Details',
'bc.editPortfolio': 'Edit Portfolio',
'bc.portfolioDetails': 'Portfolio Details',
'bc.editVideo': 'Edit Video',
'bc.videoDetails': 'Video Details',
'bc.editInstruction': 'Edit Instruction',
'bc.instructionDetails': 'Instruction Details',
'home.welcome': 'Welcome back, {name}!',
'home.welcomeFallback': 'there',
@@ -173,10 +200,25 @@ const en = {
'home.card.settings.title': 'Settings',
'home.card.settings.desc': 'Configure your store preferences and system settings.',
'home.card.settings.link': 'View settings',
'home.card.content.title': 'Content',
'home.card.content.desc': 'Manage blog posts, videos, and other published content.',
'home.card.content.link': 'Manage content',
'home.card.content.count': 'items',
'content.page.subtitle': 'Blog, videos, and other content types for your website.',
'content.card.blog.desc': 'Create and manage blog posts and categories.',
'content.card.blog.link': 'Open blog',
'content.card.videos.desc': 'Embed YouTube and Aparat videos with categories and comments.',
'content.card.videos.link': 'Open videos',
'content.card.instructions.desc': 'Tutorials with rich text and optional embedded video.',
'content.card.instructions.link': 'Open instructions',
'home.card.blog.title': 'Blog',
'home.card.blog.desc': 'Create and manage blog posts and categories.',
'home.card.blog.link': 'View blog',
'home.card.blog.count': 'posts',
'home.card.videos.title': 'Videos',
'home.card.videos.desc': 'Embed YouTube and Aparat videos with categories and comments.',
'home.card.videos.link': 'View videos',
'home.card.videos.count': 'videos',
'home.card.portfolios.title': 'Portfolios',
'home.card.portfolios.desc': 'Manage your portfolio items and showcase projects.',
'home.card.portfolios.link': 'View portfolios',
@@ -968,6 +1010,162 @@ const en = {
'blog.details.noContent': 'No content yet.',
'blog.details.author': 'Author',
'video.page.subtitle': 'Embed and manage YouTube and Aparat videos for your website.',
'video.card.list.desc': 'View, edit and manage all your videos.',
'video.card.list.link': 'View videos',
'video.card.new.desc': 'Add a new embedded video with cover image and description.',
'video.card.new.link': 'Add video',
'video.card.categories.title': 'Video Categories',
'video.card.categories.desc': 'Organize videos into categories and subcategories.',
'video.card.categories.link': 'View categories',
'video.card.settings.desc': 'Configure video comment moderation options.',
'video.card.settings.link': 'View settings',
'video.list.subtitle': '{count} videos · View, edit and manage your video content.',
'video.list.loading': 'Loading videos...',
'video.list.empty': 'No videos yet.',
'video.list.emptyHint': 'Share embedded videos from YouTube or Aparat with your audience.',
'video.list.emptyCta': 'Add your first video',
'video.list.errorLoad': 'Unable to load videos.',
'video.list.errorDelete': 'Unable to delete video.',
'video.list.toast.removed': 'Video removed.',
'video.list.deleteTitle': 'Delete Video',
'video.list.deleteMessage':
'Are you sure you want to delete "{name}"? This action cannot be undone.',
'video.list.addNew': 'Add new video',
'video.card.edit': 'Edit video',
'video.card.comments': 'View comments',
'video.card.remove': 'Remove video',
'video.card.noSummary': 'No summary yet.',
'video.settings.title': 'Video settings',
'video.settings.subtitle': 'Configure how video comments are moderated.',
'video.settings.commentsAuto': 'Auto-approve comments',
'video.settings.commentsAutoDesc':
'When enabled, new comments on videos are published immediately without manual approval.',
'video.settings.commentsAutoAria': 'Auto-approve video comments',
'video.categories.title': 'Video Categories',
'video.categories.subtitle': 'Organize your videos into categories and subcategories.',
'video.categories.empty': 'No categories yet. Click + to add one.',
'video.categories.errorLoad': 'Unable to load categories.',
'video.categories.errorSave': 'Unable to save category.',
'video.categories.errorDelete': 'Unable to delete category.',
'video.form.add.subtitle': 'Add an embedded video from YouTube or Aparat.',
'video.form.edit.subtitle': 'Update video details and save changes.',
'video.form.cancel': 'Cancel',
'video.form.saving': 'Saving...',
'video.form.save': 'Save Video',
'video.form.update': 'Update Video',
'video.form.errorSave': 'Unable to save video.',
'video.form.toast.created': 'Video created.',
'video.form.toast.updated': 'Video updated.',
'video.form.coverImage': 'Cover Image',
'video.form.uploadCoverImage': 'Upload cover image',
'video.form.changeCoverImage': 'Change cover image',
'video.form.cropHint': 'Click to select, then crop (3:2)',
'video.form.provider': 'Video Provider',
'video.form.category': 'Category',
'video.form.categoryPlaceholder': 'Search and select category...',
'video.form.titleFa': 'Title (FA)',
'video.form.titleFaPlaceholder': 'عنوان فارسی',
'video.form.titleEn': 'Title (EN)',
'video.form.titleEnPlaceholder': 'English title',
'video.form.abstract': 'Abstract',
'video.form.abstractPlaceholder': 'Short summary shown in video listings',
'video.form.embedCode': 'Embed Code',
'video.form.embedCodePlaceholder': 'Paste the full iframe embed code from YouTube or Aparat',
'video.form.description': 'Description',
'video.form.descriptionPlaceholder': 'Full video description with formatting...',
'video.form.tags': 'Tags',
'video.details.loading': 'Loading video...',
'video.details.notFound': 'Video not found.',
'video.details.errorLoad': 'Unable to load video.',
'video.details.back': 'Back to My Videos',
'video.details.noDescription': 'No description yet.',
'video.details.author': 'Author',
'instruction.page.subtitle': 'Create and manage tutorials with rich text and optional embedded video.',
'instruction.card.list.desc': 'View, edit and manage all your instructions.',
'instruction.card.list.link': 'View instructions',
'instruction.card.new.desc': 'Add a new tutorial with cover image, rich text, and optional video embed.',
'instruction.card.new.link': 'Add instruction',
'instruction.card.categories.title': 'Instruction Categories',
'instruction.card.categories.desc': 'Organize instructions into categories and subcategories.',
'instruction.card.categories.link': 'View categories',
'instruction.card.settings.desc': 'Configure instruction comment moderation options.',
'instruction.card.settings.link': 'View settings',
'instruction.list.subtitle': '{count} instructions · View, edit and manage your tutorials.',
'instruction.list.loading': 'Loading instructions...',
'instruction.list.empty': 'No instructions yet.',
'instruction.list.emptyHint': 'Publish tutorials with rich text and optional video for your audience.',
'instruction.list.emptyCta': 'Add your first instruction',
'instruction.list.errorLoad': 'Unable to load instructions.',
'instruction.list.errorDelete': 'Unable to delete instruction.',
'instruction.list.toast.removed': 'Instruction removed.',
'instruction.list.deleteTitle': 'Delete Instruction',
'instruction.list.deleteMessage':
'Are you sure you want to delete "{name}"? This action cannot be undone.',
'instruction.list.addNew': 'Add new instruction',
'instruction.card.edit': 'Edit instruction',
'instruction.card.comments': 'View comments',
'instruction.card.remove': 'Remove instruction',
'instruction.card.noSummary': 'No summary yet.',
'instruction.settings.title': 'Instruction settings',
'instruction.settings.subtitle': 'Configure how instruction comments are moderated.',
'instruction.settings.commentsAuto': 'Auto-approve comments',
'instruction.settings.commentsAutoDesc':
'When enabled, new comments on instructions are published immediately without manual approval.',
'instruction.settings.commentsAutoAria': 'Auto-approve instruction comments',
'instruction.categories.title': 'Instruction Categories',
'instruction.categories.subtitle': 'Organize your instructions into categories and subcategories.',
'instruction.categories.empty': 'No categories yet. Click + to add one.',
'instruction.categories.errorLoad': 'Unable to load categories.',
'instruction.categories.errorSave': 'Unable to save category.',
'instruction.categories.errorDelete': 'Unable to delete category.',
'instruction.form.add.subtitle': 'Add a tutorial with rich text and optional embedded video.',
'instruction.form.edit.subtitle': 'Update instruction details and save changes.',
'instruction.form.cancel': 'Cancel',
'instruction.form.saving': 'Saving...',
'instruction.form.save': 'Save Instruction',
'instruction.form.update': 'Update Instruction',
'instruction.form.errorSave': 'Unable to save instruction.',
'instruction.form.toast.created': 'Instruction created.',
'instruction.form.toast.updated': 'Instruction updated.',
'instruction.form.coverImage': 'Cover Image',
'instruction.form.uploadCoverImage': 'Upload cover image',
'instruction.form.changeCoverImage': 'Change cover image',
'instruction.form.cropHint': 'Click to select, then crop (3:2)',
'instruction.form.provider': 'Video provider',
'instruction.form.category': 'Category',
'instruction.form.categoryPlaceholder': 'Search and select category...',
'instruction.form.titleFa': 'Title (FA)',
'instruction.form.titleFaPlaceholder': 'عنوان فارسی',
'instruction.form.titleEn': 'Title (EN)',
'instruction.form.titleEnPlaceholder': 'English title',
'instruction.form.abstract': 'Abstract',
'instruction.form.abstractPlaceholder': 'Short summary shown in instruction listings',
'instruction.form.embedCode': 'Embed Code',
'instruction.form.embedCodePlaceholder': 'Paste the full iframe embed code from YouTube or Aparat',
'instruction.form.description': 'Description',
'instruction.form.descriptionPlaceholder': 'Full instruction description with formatting...',
'instruction.form.tags': 'Tags',
'instruction.details.loading': 'Loading instruction...',
'instruction.details.notFound': 'Instruction not found.',
'instruction.details.errorLoad': 'Unable to load instruction.',
'instruction.details.back': 'Back to My Instructions',
'instruction.details.noDescription': 'No description yet.',
'instruction.details.author': 'Author',
'portfolio.page.subtitle': 'Manage your portfolio items and showcase projects.',
'portfolio.card.list.desc': 'View, edit and manage all your portfolio items.',
'portfolio.card.list.link': 'View portfolios',
@@ -1266,11 +1464,32 @@ const en = {
'website.badges.feature.toggle': 'Toggle visibility per badge',
'website.ePayment.subtitle': 'Configure online payment methods for your website checkout.',
'website.ePayment.lead': 'Connect payment gateways so customers can pay online through your store.',
'website.ePayment.note': 'E-payment settings will be connected here. Planned options include:',
'website.ePayment.feature.enable': 'Enable or disable online payments',
'website.ePayment.feature.credentials': 'Configure payment provider credentials',
'website.ePayment.feature.methods': 'Set supported payment methods and test mode',
'website.ePayment.master': 'Enable online payments',
'website.ePayment.masterDesc':
'When enabled, customers can pay through a configured gateway at website checkout.',
'website.ePayment.gateway.mellat': 'Bank Mellat (Behpardakht)',
'website.ePayment.gateway.mellatDesc':
'First gateway. Enter terminal ID, username, and password from the Mellat merchant panel.',
'website.ePayment.gateway.sep': 'SEP (Saman Kish)',
'website.ePayment.gateway.sepDesc': 'Saman electronic payment — coming soon.',
'website.ePayment.gateway.snappay': 'Snapp Pay',
'website.ePayment.gateway.snappayDesc': 'Snapp Pay checkout — coming soon.',
'website.ePayment.gateway.digipay': 'DigiPay',
'website.ePayment.gateway.digipayDesc': 'DigiPay checkout — coming soon.',
'website.ePayment.gateway.zarinpal': 'Zarinpal',
'website.ePayment.gateway.zarinpalDesc': 'Zarinpal gateway — coming soon.',
'website.ePayment.comingSoon': 'Coming soon',
'website.ePayment.terminalId': 'Terminal ID',
'website.ePayment.username': 'Username',
'website.ePayment.password': 'Password',
'website.ePayment.passwordSet': 'saved',
'website.ePayment.passwordPlaceholder': 'Enter gateway password',
'website.ePayment.passwordPlaceholderSet': 'Leave blank to keep current password',
'website.ePayment.showPassword': 'Show password',
'website.ePayment.hidePassword': 'Hide password',
'website.ePayment.saveCredentials': 'Save credentials',
'website.ePayment.error.credentials': 'Terminal ID and username are required when Mellat is enabled.',
'website.ePayment.error.passwordRequired': 'Password is required the first time you enable Mellat.',
'title.signIn': 'Sign in',
'title.home': 'Home',
@@ -1290,11 +1509,22 @@ const en = {
'title.shoppingCards': 'Shopping Cards',
'title.customers': 'Users',
'title.customerProducts': 'Customer products',
'title.content': 'Content',
'title.blog': 'Blog',
'title.myBlogs': 'My Blogs',
'title.addBlog': 'Add New Blog',
'title.editBlog': 'Edit Blog',
'title.blogDetails': 'Blog Details',
'title.videos': 'Videos',
'title.instructions': 'Instructions',
'title.myInstructions': 'My Instructions',
'title.addInstruction': 'Add New Instruction',
'title.editInstruction': 'Edit Instruction',
'title.instructionDetails': 'Instruction Details',
'title.myVideos': 'My Videos',
'title.addVideo': 'Add New Video',
'title.editVideo': 'Edit Video',
'title.videoDetails': 'Video Details',
'title.portfolios': 'Portfolios',
'title.myPortfolios': 'My Portfolios',
'title.addPortfolio': 'Add New Portfolio',
@@ -1650,6 +1880,11 @@ const fa: Record<MessageKey, string> = {
'nav.finance.invoices': 'فاکتورها',
'nav.finance.transactions': 'تراکنش‌ها',
'nav.settings': 'تنظیمات',
'nav.content': 'مدیریت محتوا',
'nav.content.blog': 'اخبار و مطالب',
'nav.content.videos': 'ویدیوها',
'nav.content.instructions': 'آموزش‌ها',
'nav.content.overview': 'نمای کلی',
'nav.blog': 'بلاگ',
'nav.blog.overview': 'نمای کلی',
'nav.blog.list': 'بلاگ‌های من',
@@ -1662,6 +1897,18 @@ const fa: Record<MessageKey, string> = {
'nav.portfolios.new': 'افزودن نمونه کار',
'nav.portfolios.categories': 'دسته‌بندی‌ها',
'nav.portfolios.settings': 'تنظیمات',
'nav.videos': 'ویدیوها',
'nav.videos.overview': 'نمای کلی',
'nav.videos.list': 'ویدیوهای من',
'nav.videos.new': 'افزودن ویدیو',
'nav.videos.categories': 'دسته‌بندی‌ها',
'nav.videos.settings': 'تنظیمات',
'nav.instructions': 'آموزش‌ها',
'nav.instructions.overview': 'نمای کلی',
'nav.instructions.list': 'آموزش‌های من',
'nav.instructions.new': 'افزودن آموزش',
'nav.instructions.categories': 'دسته‌بندی‌ها',
'nav.instructions.settings': 'تنظیمات',
'nav.website': 'وب‌سایت',
'nav.website.overview': 'نمای کلی',
'nav.website.sliders': 'اسلایدرها',
@@ -1766,6 +2013,10 @@ const fa: Record<MessageKey, string> = {
'bc.blogDetails': 'جزئیات بلاگ',
'bc.editPortfolio': 'ویرایش نمونه کار',
'bc.portfolioDetails': 'جزئیات نمونه کار',
'bc.editVideo': 'ویرایش ویدیو',
'bc.videoDetails': 'جزئیات ویدیو',
'bc.editInstruction': 'ویرایش آموزش',
'bc.instructionDetails': 'جزئیات آموزش',
'home.welcome': '{name} عزیز، خوش آمدی.',
'home.welcomeFallback': 'کاربر',
@@ -1785,6 +2036,17 @@ const fa: Record<MessageKey, string> = {
'home.card.settings.title': 'تنظیمات',
'home.card.settings.desc': 'ترجیحات فروشگاه و تنظیمات سیستم را پیکربندی کنید.',
'home.card.settings.link': 'مشاهده تنظیمات',
'home.card.content.title': 'مدیریت محتوا',
'home.card.content.desc': 'بلاگ، ویدیو و سایر محتوای منتشرشده را مدیریت کنید.',
'home.card.content.link': 'مدیریت محتوا',
'home.card.content.count': 'مورد',
'content.page.subtitle': 'بلاگ، ویدیو و سایر انواع محتوا برای وب‌سایت شما.',
'content.card.blog.desc': 'مطالب و دسته‌بندی‌های بلاگ را ایجاد و مدیریت کنید.',
'content.card.blog.link': 'ورود به بلاگ',
'content.card.videos.desc': 'ویدیوهای یوتیوب و آپارات را با دسته‌بندی و نظرات مدیریت کنید.',
'content.card.videos.link': 'ورود به ویدیوها',
'content.card.instructions.desc': 'آموزش‌ها با متن غنی و ویدیوی جاسازی‌شده اختیاری.',
'content.card.instructions.link': 'ورود به آموزش‌ها',
'home.card.blog.title': 'بلاگ',
'home.card.blog.desc': 'مطالب و دسته‌بندی‌های بلاگ را ایجاد و مدیریت کنید.',
'home.card.blog.link': 'مشاهده بلاگ',
@@ -1793,6 +2055,10 @@ const fa: Record<MessageKey, string> = {
'home.card.portfolios.desc': 'نمونه کارها و پروژه‌های نمایشی را مدیریت کنید.',
'home.card.portfolios.link': 'مشاهده نمونه کارها',
'home.card.portfolios.count': 'نمونه کار',
'home.card.videos.title': 'ویدیوها',
'home.card.videos.desc': 'ویدیوهای یوتیوب و آپارات را با دسته‌بندی و نظرات مدیریت کنید.',
'home.card.videos.link': 'مشاهده ویدیوها',
'home.card.videos.count': 'ویدیو',
'home.card.website.title': 'وب‌سایت',
'home.card.website.desc': 'فرم تماس، سوالات متداول، نشان‌ها، عضویت‌ها و پرداخت الکترونیک.',
'home.card.website.link': 'مشاهده وب‌سایت',
@@ -2578,6 +2844,162 @@ const fa: Record<MessageKey, string> = {
'blog.details.noContent': 'هنوز محتوایی نیست.',
'blog.details.author': 'نویسنده',
'video.page.subtitle': 'ویدیوهای یوتیوب و آپارات را برای وب‌سایت خود مدیریت کنید.',
'video.card.list.desc': 'همه ویدیوها را مشاهده، ویرایش و مدیریت کنید.',
'video.card.list.link': 'مشاهده ویدیوها',
'video.card.new.desc': 'یک ویدیوی جاسازی‌شده با تصویر کاور و توضیحات اضافه کنید.',
'video.card.new.link': 'افزودن ویدیو',
'video.card.categories.title': 'دسته‌بندی‌های ویدیو',
'video.card.categories.desc': 'ویدیوها را در دسته‌بندی‌ها و زیردسته‌ها سازماندهی کنید.',
'video.card.categories.link': 'مشاهده دسته‌بندی‌ها',
'video.card.settings.desc': 'تأیید نظرات ویدیو را پیکربندی کنید.',
'video.card.settings.link': 'مشاهده تنظیمات',
'video.list.subtitle': '{count} ویدیو · مشاهده، ویرایش و مدیریت محتوای ویدیو.',
'video.list.loading': 'در حال بارگذاری ویدیوها...',
'video.list.empty': 'هنوز ویدیویی نیست.',
'video.list.emptyHint': 'ویدیوهای جاسازی‌شده از یوتیوب یا آپارات را با مخاطبان به اشتراک بگذارید.',
'video.list.emptyCta': 'اولین ویدیو را اضافه کنید',
'video.list.errorLoad': 'بارگذاری ویدیوها ممکن نشد.',
'video.list.errorDelete': 'حذف ویدیو ممکن نشد.',
'video.list.toast.removed': 'ویدیو حذف شد.',
'video.list.deleteTitle': 'حذف ویدیو',
'video.list.deleteMessage':
'آیا از حذف «{name}» مطمئن هستید؟ این عمل قابل بازگشت نیست.',
'video.list.addNew': 'افزودن ویدیو',
'video.card.edit': 'ویرایش ویدیو',
'video.card.comments': 'مشاهده نظرات',
'video.card.remove': 'حذف ویدیو',
'video.card.noSummary': 'هنوز خلاصه‌ای نیست.',
'video.settings.title': 'تنظیمات ویدیو',
'video.settings.subtitle': 'نحوه تأیید نظرات ویدیو را پیکربندی کنید.',
'video.settings.commentsAuto': 'تأیید خودکار نظرات',
'video.settings.commentsAutoDesc':
'در صورت فعال بودن، نظرات جدید روی ویدیوها بدون تأیید دستی منتشر می‌شوند.',
'video.settings.commentsAutoAria': 'تأیید خودکار نظرات ویدیو',
'video.categories.title': 'دسته‌بندی‌های ویدیو',
'video.categories.subtitle': 'ویدیوها را در دسته‌بندی‌ها و زیردسته‌ها سازماندهی کنید.',
'video.categories.empty': 'هنوز دسته‌بندی‌ای نیست. برای افزودن روی + بزنید.',
'video.categories.errorLoad': 'بارگذاری دسته‌بندی‌ها ممکن نشد.',
'video.categories.errorSave': 'ذخیره دسته‌بندی ممکن نشد.',
'video.categories.errorDelete': 'حذف دسته‌بندی ممکن نشد.',
'video.form.add.subtitle': 'یک ویدیوی جاسازی‌شده از یوتیوب یا آپارات اضافه کنید.',
'video.form.edit.subtitle': 'جزئیات ویدیو را به‌روزرسانی و ذخیره کنید.',
'video.form.cancel': 'انصراف',
'video.form.saving': 'در حال ذخیره...',
'video.form.save': 'ذخیره ویدیو',
'video.form.update': 'به‌روزرسانی ویدیو',
'video.form.errorSave': 'ذخیره ویدیو ممکن نشد.',
'video.form.toast.created': 'ویدیو ایجاد شد.',
'video.form.toast.updated': 'ویدیو به‌روزرسانی شد.',
'video.form.coverImage': 'تصویر کاور',
'video.form.uploadCoverImage': 'بارگذاری تصویر کاور',
'video.form.changeCoverImage': 'تغییر تصویر کاور',
'video.form.cropHint': 'برای انتخاب و برش (۳:۲) کلیک کنید',
'video.form.provider': 'ارائه‌دهنده ویدیو',
'video.form.category': 'دسته‌بندی',
'video.form.categoryPlaceholder': 'جستجو و انتخاب دسته‌بندی...',
'video.form.titleFa': 'عنوان (فارسی)',
'video.form.titleFaPlaceholder': 'عنوان فارسی',
'video.form.titleEn': 'عنوان (انگلیسی)',
'video.form.titleEnPlaceholder': 'English title',
'video.form.abstract': 'چکیده',
'video.form.abstractPlaceholder': 'خلاصه کوتاه در فهرست ویدیوها',
'video.form.embedCode': 'کد جاسازی',
'video.form.embedCodePlaceholder': 'کد iframe کامل را از یوتیوب یا آپارات بچسبانید',
'video.form.description': 'توضیحات',
'video.form.descriptionPlaceholder': 'توضیحات کامل ویدیو با قالب‌بندی...',
'video.form.tags': 'برچسب‌ها',
'video.details.loading': 'در حال بارگذاری ویدیو...',
'video.details.notFound': 'ویدیو یافت نشد.',
'video.details.errorLoad': 'بارگذاری ویدیو ممکن نشد.',
'video.details.back': 'بازگشت به ویدیوهای من',
'video.details.noDescription': 'هنوز توضیحاتی نیست.',
'video.details.author': 'نویسنده',
'instruction.page.subtitle': 'آموزش‌ها را با متن غنی و ویدیوی جاسازی‌شده اختیاری ایجاد و مدیریت کنید.',
'instruction.card.list.desc': 'همه آموزش‌ها را مشاهده، ویرایش و مدیریت کنید.',
'instruction.card.list.link': 'مشاهده آموزش‌ها',
'instruction.card.new.desc': 'یک آموزش جدید با تصویر کاور، متن غنی و ویدیوی اختیاری اضافه کنید.',
'instruction.card.new.link': 'افزودن آموزش',
'instruction.card.categories.title': 'دسته‌بندی‌های آموزش',
'instruction.card.categories.desc': 'آموزش‌ها را در دسته‌بندی‌ها و زیردسته‌ها سازماندهی کنید.',
'instruction.card.categories.link': 'مشاهده دسته‌بندی‌ها',
'instruction.card.settings.desc': 'تأیید نظرات آموزش را پیکربندی کنید.',
'instruction.card.settings.link': 'مشاهده تنظیمات',
'instruction.list.subtitle': '{count} آموزش · مشاهده، ویرایش و مدیریت محتوای آموزشی.',
'instruction.list.loading': 'در حال بارگذاری آموزش‌ها...',
'instruction.list.empty': 'هنوز آموزشی نیست.',
'instruction.list.emptyHint': 'آموزش‌ها را با متن غنی و ویدیوی اختیاری برای مخاطبان منتشر کنید.',
'instruction.list.emptyCta': 'اولین آموزش را اضافه کنید',
'instruction.list.errorLoad': 'بارگذاری آموزش‌ها ممکن نشد.',
'instruction.list.errorDelete': 'حذف آموزش ممکن نشد.',
'instruction.list.toast.removed': 'آموزش حذف شد.',
'instruction.list.deleteTitle': 'حذف آموزش',
'instruction.list.deleteMessage':
'آیا از حذف «{name}» مطمئن هستید؟ این عمل قابل بازگشت نیست.',
'instruction.list.addNew': 'افزودن آموزش',
'instruction.card.edit': 'ویرایش آموزش',
'instruction.card.comments': 'مشاهده نظرات',
'instruction.card.remove': 'حذف آموزش',
'instruction.card.noSummary': 'هنوز خلاصه‌ای نیست.',
'instruction.settings.title': 'تنظیمات آموزش',
'instruction.settings.subtitle': 'نحوه تأیید نظرات آموزش را پیکربندی کنید.',
'instruction.settings.commentsAuto': 'تأیید خودکار نظرات',
'instruction.settings.commentsAutoDesc':
'در صورت فعال بودن، نظرات جدید روی آموزش‌ها بدون تأیید دستی منتشر می‌شوند.',
'instruction.settings.commentsAutoAria': 'تأیید خودکار نظرات آموزش',
'instruction.categories.title': 'دسته‌بندی‌های آموزش',
'instruction.categories.subtitle': 'آموزش‌ها را در دسته‌بندی‌ها و زیردسته‌ها سازماندهی کنید.',
'instruction.categories.empty': 'هنوز دسته‌بندی‌ای نیست. برای افزودن روی + بزنید.',
'instruction.categories.errorLoad': 'بارگذاری دسته‌بندی‌ها ممکن نشد.',
'instruction.categories.errorSave': 'ذخیره دسته‌بندی ممکن نشد.',
'instruction.categories.errorDelete': 'حذف دسته‌بندی ممکن نشد.',
'instruction.form.add.subtitle': 'یک آموزش با متن غنی و ویدیوی جاسازی‌شده اختیاری اضافه کنید.',
'instruction.form.edit.subtitle': 'جزئیات آموزش را به‌روزرسانی و ذخیره کنید.',
'instruction.form.cancel': 'انصراف',
'instruction.form.saving': 'در حال ذخیره...',
'instruction.form.save': 'ذخیره آموزش',
'instruction.form.update': 'به‌روزرسانی آموزش',
'instruction.form.errorSave': 'ذخیره آموزش ممکن نشد.',
'instruction.form.toast.created': 'آموزش ایجاد شد.',
'instruction.form.toast.updated': 'آموزش به‌روزرسانی شد.',
'instruction.form.coverImage': 'تصویر کاور',
'instruction.form.uploadCoverImage': 'بارگذاری تصویر کاور',
'instruction.form.changeCoverImage': 'تغییر تصویر کاور',
'instruction.form.cropHint': 'برای انتخاب و برش (۳:۲) کلیک کنید',
'instruction.form.provider': 'ارائه‌دهنده ویدیو',
'instruction.form.category': 'دسته‌بندی',
'instruction.form.categoryPlaceholder': 'جستجو و انتخاب دسته‌بندی...',
'instruction.form.titleFa': 'عنوان (فارسی)',
'instruction.form.titleFaPlaceholder': 'عنوان فارسی',
'instruction.form.titleEn': 'عنوان (انگلیسی)',
'instruction.form.titleEnPlaceholder': 'English title',
'instruction.form.abstract': 'چکیده',
'instruction.form.abstractPlaceholder': 'خلاصه کوتاه در فهرست آموزش‌ها',
'instruction.form.embedCode': 'کد جاسازی',
'instruction.form.embedCodePlaceholder': 'کد iframe کامل را از یوتیوب یا آپارات بچسبانید',
'instruction.form.description': 'توضیحات',
'instruction.form.descriptionPlaceholder': 'توضیحات کامل آموزش با قالب‌بندی...',
'instruction.form.tags': 'برچسب‌ها',
'instruction.details.loading': 'در حال بارگذاری آموزش...',
'instruction.details.notFound': 'آموزش یافت نشد.',
'instruction.details.errorLoad': 'بارگذاری آموزش ممکن نشد.',
'instruction.details.back': 'بازگشت به آموزش‌های من',
'instruction.details.noDescription': 'هنوز توضیحاتی نیست.',
'instruction.details.author': 'نویسنده',
'portfolio.page.subtitle': 'نمونه کارها را مدیریت کنید و پروژه‌ها را به نمایش بگذارید.',
'portfolio.card.list.desc': 'همه نمونه کارها را مشاهده، ویرایش و مدیریت کنید.',
'portfolio.card.list.link': 'مشاهده نمونه کارها',
@@ -2874,12 +3296,34 @@ const fa: Record<MessageKey, string> = {
'website.badges.feature.toggle': 'نمایش یا مخفی کردن هر نشان',
'website.ePayment.subtitle': 'روش‌های پرداخت آنلاین برای تسویه حساب وب‌سایت را پیکربندی کنید.',
'website.ePayment.lead':
'درگاه‌های پرداخت را متصل کنید تا مشتریان از طریق فروشگاه آنلاین پرداخت کنند.',
'website.ePayment.note': 'تنظیمات پرداخت الکترونیک به‌زودی اینجا متصل می‌شود. گزینه‌های برنامه‌ریزی‌شده:',
'website.ePayment.feature.enable': 'فعال یا غیرفعال کردن پرداخت آنلاین',
'website.ePayment.feature.credentials': 'پیکربندی اطلاعات درگاه پرداخت',
'website.ePayment.feature.methods': 'تنظیم روش‌های پرداخت و حالت آزمایشی',
'website.ePayment.master': 'فعال‌سازی پرداخت آنلاین',
'website.ePayment.masterDesc':
'با فعال بودن این گزینه، مشتریان در تسویه حساب وب‌سایت می‌توانند از درگاه پیکربندی‌شده پرداخت کنند.',
'website.ePayment.gateway.mellat': 'بانک ملت (به‌پرداخت)',
'website.ePayment.gateway.mellatDesc':
'اولین درگاه. شناسه ترمینال، نام کاربری و رمز عبور را از پنل پذیرنده ملت وارد کنید.',
'website.ePayment.gateway.sep': 'سپ (سامان کیش)',
'website.ePayment.gateway.sepDesc': 'درگاه پرداخت سامان — به‌زودی.',
'website.ePayment.gateway.snappay': 'اسنپ‌پی',
'website.ePayment.gateway.snappayDesc': 'پرداخت اسنپ‌پی — به‌زودی.',
'website.ePayment.gateway.digipay': 'دیجی‌پی',
'website.ePayment.gateway.digipayDesc': 'پرداخت دیجی‌پی — به‌زودی.',
'website.ePayment.gateway.zarinpal': 'زرین‌پال',
'website.ePayment.gateway.zarinpalDesc': 'درگاه زرین‌پال — به‌زودی.',
'website.ePayment.comingSoon': 'به‌زودی',
'website.ePayment.terminalId': 'شناسه ترمینال',
'website.ePayment.username': 'نام کاربری',
'website.ePayment.password': 'رمز عبور',
'website.ePayment.passwordSet': 'ذخیره‌شده',
'website.ePayment.passwordPlaceholder': 'رمز عبور درگاه را وارد کنید',
'website.ePayment.passwordPlaceholderSet': 'برای حفظ رمز فعلی خالی بگذارید',
'website.ePayment.showPassword': 'نمایش رمز',
'website.ePayment.hidePassword': 'مخفی کردن رمز',
'website.ePayment.saveCredentials': 'ذخیره اطلاعات',
'website.ePayment.error.credentials':
'با فعال بودن ملت، شناسه ترمینال و نام کاربری الزامی است.',
'website.ePayment.error.passwordRequired':
'برای اولین بار فعال‌سازی ملت، رمز عبور الزامی است.',
'title.signIn': 'ورود',
'title.home': 'خانه',
@@ -2899,11 +3343,22 @@ const fa: Record<MessageKey, string> = {
'title.shoppingCards': 'کارت‌های خرید',
'title.customers': 'کاربران',
'title.customerProducts': 'محصولات مشتریان',
'title.content': 'مدیریت محتوا',
'title.blog': 'بلاگ',
'title.myBlogs': 'بلاگ‌های من',
'title.addBlog': 'افزودن بلاگ',
'title.editBlog': 'ویرایش بلاگ',
'title.blogDetails': 'جزئیات بلاگ',
'title.videos': 'ویدیوها',
'title.instructions': 'آموزش‌ها',
'title.myInstructions': 'آموزش‌های من',
'title.addInstruction': 'افزودن آموزش',
'title.editInstruction': 'ویرایش آموزش',
'title.instructionDetails': 'جزئیات آموزش',
'title.myVideos': 'ویدیوهای من',
'title.addVideo': 'افزودن ویدیو',
'title.editVideo': 'ویرایش ویدیو',
'title.videoDetails': 'جزئیات ویدیو',
'title.portfolios': 'نمونه کارها',
'title.myPortfolios': 'نمونه کارهای من',
'title.addPortfolio': 'افزودن نمونه کار',
@@ -3249,15 +3704,26 @@ const BREADCRUMB_LABEL_KEYS: Record<string, MessageKey> = {
Customers: 'nav.customers',
'Customer products': 'nav.customerProducts',
Blog: 'nav.blog',
Content: 'nav.content',
'My Blogs': 'nav.blog.list',
'Add New Blog': 'nav.blog.new',
'Edit Blog': 'bc.editBlog',
'Blog Details': 'bc.blogDetails',
Videos: 'nav.videos',
Instructions: 'nav.instructions',
'My Instructions': 'nav.instructions.list',
'Add New Instruction': 'nav.instructions.new',
'Edit Instruction': 'bc.editInstruction',
'Instruction Details': 'bc.instructionDetails',
Portfolios: 'nav.portfolios',
'My Portfolios': 'nav.portfolios.list',
'Add New Portfolio': 'nav.portfolios.new',
'Edit Portfolio': 'bc.editPortfolio',
'Portfolio Details': 'bc.portfolioDetails',
'My Videos': 'nav.videos.list',
'Add New Video': 'nav.videos.new',
'Edit Video': 'bc.editVideo',
'Video Details': 'bc.videoDetails',
Website: 'nav.website',
Sliders: 'nav.website.sliders',
'Special Categories': 'nav.website.specialCategories',
@@ -3337,13 +3803,28 @@ export function getBusinessRouteTitleRules(locale: DashboardLocale): RouteTitleR
},
{ match: '/invoices', labels: [t('title.finance'), t('title.invoices')] },
{ match: '/transactions', labels: [t('title.finance'), t('title.transactions')] },
{ match: '/blog/list', labels: [t('title.blog'), t('title.myBlogs')] },
{ match: /^\/blog\/detail\/[^/]+$/, labels: [t('title.blog'), t('title.blogDetails')] },
{ match: '/blog/new', labels: [t('title.blog'), t('title.addBlog')] },
{ match: /^\/blog\/edit\/[^/]+$/, labels: [t('title.blog'), t('title.editBlog')] },
{ match: '/blog/categories', labels: [t('title.blog'), t('title.categories')] },
{ match: '/blog/settings', labels: [t('title.blog'), t('title.settings')] },
{ match: '/blog', labels: [t('title.blog')] },
{ match: '/content', labels: [t('title.content')] },
{ match: '/blog/list', labels: [t('title.content'), t('title.blog'), t('title.myBlogs')] },
{ match: /^\/blog\/detail\/[^/]+$/, labels: [t('title.content'), t('title.blog'), t('title.blogDetails')] },
{ match: '/blog/new', labels: [t('title.content'), t('title.blog'), t('title.addBlog')] },
{ match: /^\/blog\/edit\/[^/]+$/, labels: [t('title.content'), t('title.blog'), t('title.editBlog')] },
{ match: '/blog/categories', labels: [t('title.content'), t('title.blog'), t('title.categories')] },
{ match: '/blog/settings', labels: [t('title.content'), t('title.blog'), t('title.settings')] },
{ match: '/blog', labels: [t('title.content'), t('title.blog')] },
{ match: '/videos/list', labels: [t('title.content'), t('title.videos'), t('title.myVideos')] },
{ match: /^\/videos\/detail\/[^/]+$/, labels: [t('title.content'), t('title.videos'), t('title.videoDetails')] },
{ match: '/videos/new', labels: [t('title.content'), t('title.videos'), t('title.addVideo')] },
{ match: /^\/videos\/edit\/[^/]+$/, labels: [t('title.content'), t('title.videos'), t('title.editVideo')] },
{ match: '/videos/categories', labels: [t('title.content'), t('title.videos'), t('title.categories')] },
{ match: '/videos/settings', labels: [t('title.content'), t('title.videos'), t('title.settings')] },
{ match: '/videos', labels: [t('title.content'), t('title.videos')] },
{ match: '/instructions/list', labels: [t('title.content'), t('title.instructions'), t('title.myInstructions')] },
{ match: /^\/instructions\/detail\/[^/]+$/, labels: [t('title.content'), t('title.instructions'), t('title.instructionDetails')] },
{ match: '/instructions/new', labels: [t('title.content'), t('title.instructions'), t('title.addInstruction')] },
{ match: /^\/instructions\/edit\/[^/]+$/, labels: [t('title.content'), t('title.instructions'), t('title.editInstruction')] },
{ match: '/instructions/categories', labels: [t('title.content'), t('title.instructions'), t('title.categories')] },
{ match: '/instructions/settings', labels: [t('title.content'), t('title.instructions'), t('title.settings')] },
{ match: '/instructions', labels: [t('title.content'), t('title.instructions')] },
{ match: '/portfolios/list', labels: [t('title.portfolios'), t('title.myPortfolios')] },
{
match: /^\/portfolios\/detail\/[^/]+$/,