Add business Finance hub with invoices and templates.

Ship invoice issue/list/templates under Finance, fix tenant theme reset and owner role badge, and show customers-joined charts by Persian months.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-11 15:17:03 +03:30
co-authored by Cursor
parent 722933dda9
commit 917b840ee5
44 changed files with 5136 additions and 105 deletions
+475 -4
View File
@@ -30,6 +30,13 @@ const en = {
'nav.store.settings': 'Settings',
'nav.customers': 'Users',
'nav.customerProducts': 'Customer products',
'nav.invoices': 'Invoices',
'nav.invoices.list': 'Invoices',
'nav.invoices.templates': 'Templates',
'nav.finance': 'Finance Management',
'nav.finance.overview': 'Overview',
'nav.finance.invoices': 'Invoices',
'nav.finance.transactions': 'Transactions',
'nav.settings': 'Settings',
'nav.blog': 'Blog',
'nav.blog.overview': 'Overview',
@@ -177,6 +184,9 @@ const en = {
'home.card.website.title': 'Website',
'home.card.website.desc': 'Manage contact forms, FAQ, badges, subscriptions, and e-payment.',
'home.card.website.link': 'View website',
'home.card.finance.title': 'Finance Management',
'home.card.finance.desc': 'Manage invoices and financial transactions.',
'home.card.finance.link': 'View finance',
'home.chart.orders.title': 'Orders',
'home.chart.orders.subtitle': 'Orders and cart adds in the last 30 days',
@@ -200,8 +210,8 @@ const en = {
'home.chart.customersJoined.activeLegend': 'Active ({count})',
'home.chart.customersJoined.loading': 'Loading chart...',
'home.chart.customersJoined.error': 'Unable to load customer activity.',
'home.chart.customersJoined.bar': '{day}: {count} registered',
'home.chart.customersJoined.activeBar': '{day}: {count} active',
'home.chart.customersJoined.bar': '{month}: {count} registered',
'home.chart.customersJoined.activeBar': '{month}: {count} active',
'home.chart.blogViews.title': 'Article views',
'home.chart.blogViews.subtitle': 'Blog article views in the last 30 days',
'home.chart.placeholder.title': 'Chart',
@@ -802,6 +812,7 @@ const en = {
'customers.edit': 'Edit customer',
'customers.sms': 'Send SMS',
'customers.tickets': 'Tickets',
'customers.invoices': 'View invoices',
'customers.remove': 'Remove customer',
'customers.add': 'Add customer',
'customers.error.load': 'Unable to load customers.',
@@ -1290,6 +1301,222 @@ const en = {
'title.faq': 'FAQ',
'title.badges': 'Badges',
'title.ePayment': 'E-Payment',
'title.invoices': 'Invoices',
'title.finance': 'Finance Management',
'title.issueInvoice': 'Issue Invoice',
'title.editInvoice': 'Edit Invoice',
'title.invoiceTemplates': 'Invoice Templates',
'title.addInvoiceTemplate': 'Add Invoice Template',
'title.editInvoiceTemplate': 'Edit Invoice Template',
'title.transactions': 'Transactions',
'finance.page.subtitle': 'Manage invoices and financial transactions.',
'finance.card.invoices.desc': 'Issue and track invoices for your customers.',
'finance.card.transactions.desc': 'View payment and financial transactions.',
'transactions.subtitle': 'View payment and financial transactions.',
'transactions.lead': 'Transactions will appear here.',
'transactions.note': 'This section is coming soon. You can still review order payment details from Orders.',
'invoices.subtitle': 'Manage invoices issued to your customers.',
'invoices.templatesLink': 'Template management',
'invoices.issue': 'Issue invoice',
'invoices.tableTitle': 'Invoices',
'invoices.countOne': '{count} invoice',
'invoices.countMany': '{count} invoices',
'invoices.loading': 'Loading…',
'invoices.empty': 'No invoices yet.',
'invoices.col.name': 'Name',
'invoices.col.customer': 'Customer',
'invoices.col.issued': 'Issued',
'invoices.col.status': 'Status',
'invoices.col.total': 'Total',
'invoices.col.link': 'Link',
'invoices.col.actions': 'Actions',
'invoices.itemCountOne': '{count} item',
'invoices.itemCountMany': '{count} items',
'invoices.changeStatus': 'Change status',
'invoices.changeStatusAria': 'Change status ({status})',
'invoices.view': 'View',
'invoices.viewAria': 'View invoice',
'invoices.edit': 'Edit',
'invoices.editAria': 'Edit invoice',
'invoices.editDisabledTitle': 'Approved invoices cannot be edited',
'invoices.editDisabledAria': 'Edit invoice (disabled — approved)',
'invoices.remove': 'Remove',
'invoices.removeAria': 'Remove invoice',
'invoices.copyLink': 'Copy link',
'invoices.copyLinkAria': 'Copy invoice link',
'invoices.linkCopied': 'Invoice link copied.',
'invoices.linkCopyError': 'Unable to copy link.',
'invoices.deleteTitle': 'Remove invoice?',
'invoices.deleteMessage': 'Remove this invoice permanently? This cannot be undone.',
'invoices.removed': 'Invoice removed.',
'invoices.removeError': 'Unable to remove invoice.',
'invoices.statusUpdated': 'Invoice status updated.',
'invoices.statusUpdateError': 'Unable to update status.',
'invoices.loadError': 'Unable to load invoices.',
'invoices.filterBannerNamed': "{name}'s invoices",
'invoices.filterBannerGeneric': "This customer's invoices",
'invoices.filterCancel': 'Cancel',
'invoices.filterClear': 'Clear filter',
'invoices.issueForCustomer': 'Issue invoice for this customer',
'invoices.detailFallbackTitle': 'Invoice',
'invoices.detail.status': 'Status',
'invoices.detail.total': 'Total',
'invoices.detail.link': 'Public link',
'invoices.detail.billedTo': 'Billed to',
'invoices.detail.notes': 'Notes: {notes}',
'invoices.status.draft': 'Draft',
'invoices.status.issued': 'Issued',
'invoices.status.approved': 'Approved',
'invoices.status.paid': 'Paid',
'invoices.status.cancelled': 'Cancelled',
'issueInvoice.subtitleNew': 'Select an invoice template and edit it, or create a blank invoice.',
'issueInvoice.subtitleEdit': 'Update invoice content. Approved invoices cannot be changed.',
'issueInvoice.startFromTemplate': 'Start from template',
'issueInvoice.blankInvoice': 'Without template',
'issueInvoice.name': 'Name (optional)',
'issueInvoice.namePlaceholder': 'e.g. Website redesign package',
'issueInvoice.noTemplatesHint': 'No invoice templates yet. Manage them in {link}, or fill a blank invoice below.',
'issueInvoice.noTemplatesLink': 'Invoice Templates',
'issueInvoice.topText': 'Top text',
'issueInvoice.topTextPlaceholder': 'Optional intro text at the top of the invoice',
'issueInvoice.notes': 'Notes',
'issueInvoice.notesPlaceholder': 'Optional internal notes',
'issueInvoice.total': 'Total: {total}',
'issueInvoice.totalLabel': 'Total',
'issueInvoice.cancel': 'Cancel',
'issueInvoice.save': 'Save changes',
'issueInvoice.saving': 'Saving…',
'issueInvoice.issue': 'Issue invoice',
'issueInvoice.issuing': 'Issuing…',
'issueInvoice.backToInvoices': 'Back to invoices',
'issueInvoice.approvedLocked': 'This invoice is approved and can no longer be edited.',
'issueInvoice.loadError': 'Unable to load invoice form.',
'issueInvoice.updateError': 'Unable to update invoice.',
'issueInvoice.createError': 'Unable to create invoice.',
'issueInvoice.updated': 'Invoice updated.',
'issueInvoice.issued': 'Invoice issued.',
'issueInvoice.recipient': 'Issue invoice for',
'issueInvoice.recipientFor': 'Issue invoice for {name}',
'issueInvoice.recipientRequired': 'Select a customer to bill this invoice to.',
'issueInvoice.pickCustomer': 'Select customer',
'issueInvoice.pickCustomerPlaceholder': 'Search by name or cell number…',
'issueInvoice.pickCustomerNoResults': 'No customers found.',
'issueInvoice.pickCustomerHint': 'Type at least 2 characters to search.',
'issueInvoice.changeCustomer': 'Change',
'issueInvoice.unknownCustomer': 'Customer',
'issueInvoice.loading': 'Loading…',
'invoiceDraft.itemLabel': 'Item {index}',
'invoiceDraft.removeItem': 'Remove item',
'invoiceDraft.fieldTitle': 'Title',
'invoiceDraft.fieldTitlePlaceholder': 'Service title',
'invoiceDraft.fieldDuration': 'Duration',
'invoiceDraft.fieldDurationPlaceholder': 'e.g. 3 months',
'invoiceDraft.fieldWorktime': 'Worktime',
'invoiceDraft.fieldWorktimePlaceholder': 'e.g. 40 hours',
'invoiceDraft.fieldPrice': 'Price (IRT)',
'invoiceDraft.fieldDiscountedPrice': 'Discounted price (IRT)',
'invoiceDraft.fieldDiscountedPricePlaceholder': 'Optional',
'invoiceDraft.optional': 'Optional',
'invoiceDraft.fieldDescription': 'Description',
'invoiceDraft.fieldDescriptionPlaceholder': 'Optional details',
'invoiceDraft.addFromTemplate': 'Add from template…',
'invoiceDraft.addFromTemplateAria': 'Add from item template',
'invoiceDraft.add': 'Add',
'invoiceDraft.addCustomItem': 'Add custom item',
'invoiceDraft.keyPoints': 'Key points',
'invoiceDraft.addPoint': 'Add point',
'invoiceDraft.noKeyPoints': 'No key points yet.',
'invoiceDraft.keyPointPlaceholder': 'e.g. Payment due within 7 days',
'invoiceDraft.keyPointAria': 'Key point {index}',
'invoiceDraft.removeKeyPoint': 'Remove key point',
'invoiceDraft.accounts': 'Account numbers',
'invoiceDraft.addAccount': 'Add account',
'invoiceDraft.noAccounts': 'No bank accounts yet.',
'invoiceDraft.bankName': 'Bank name',
'invoiceDraft.accountHolder': 'Account holder',
'invoiceDraft.cardNumber': 'Card number',
'invoiceDraft.iban': 'IBAN',
'invoiceDraft.removeAccount': 'Remove account',
'invoiceDraft.error.itemTitle': 'Each item needs a title.',
'invoiceDraft.error.itemPrice': 'Price is required for "{title}".',
'invoiceDraft.error.itemDiscountInvalid': 'Discounted price is invalid for "{title}".',
'invoiceDraft.error.itemDiscountExceeds': 'Discounted price cannot exceed price for "{title}".',
'invoiceTemplates.subtitle': 'Manage reusable invoice templates and predefined line items.',
'invoiceTemplates.section.templates.title': 'Invoice templates',
'invoiceTemplates.section.templates.desc':
'Full blueprints for faster issuing — pick one and edit, or start blank.',
'invoiceTemplates.addTemplate': 'Add template',
'invoiceTemplates.templatesTableTitle': 'Templates',
'invoiceTemplates.countTemplatesOne': '{count} template',
'invoiceTemplates.countTemplatesMany': '{count} templates',
'invoiceTemplates.col.name': 'Name',
'invoiceTemplates.col.items': 'Items',
'invoiceTemplates.col.keyPoints': 'Key points',
'invoiceTemplates.col.accounts': 'Accounts',
'invoiceTemplates.col.actions': 'Actions',
'invoiceTemplates.emptyTemplates': 'No invoice templates yet. Add one to speed up issuing invoices.',
'invoiceTemplates.section.items.title': 'Invoice item templates',
'invoiceTemplates.section.items.desc':
'Reusable line items you can drop into invoice templates or when issuing an invoice.',
'invoiceTemplates.addItem': 'Add item',
'invoiceTemplates.itemsTableTitle': 'Predefined line items',
'invoiceTemplates.countItemsOne': '{count} item',
'invoiceTemplates.countItemsMany': '{count} items',
'invoiceTemplates.col.title': 'Title',
'invoiceTemplates.col.duration': 'Duration',
'invoiceTemplates.col.worktime': 'Worktime',
'invoiceTemplates.col.price': 'Price',
'invoiceTemplates.col.discounted': 'Discounted',
'invoiceTemplates.emptyItems': 'No predefined items yet.',
'invoiceTemplates.editTemplate': 'Edit',
'invoiceTemplates.removeTemplate': 'Remove',
'invoiceTemplates.editItem': 'Edit',
'invoiceTemplates.removeItem': 'Remove',
'invoiceTemplates.deleteTemplateTitle': 'Remove invoice template',
'invoiceTemplates.deleteTemplateMessage': 'Remove "{name}" from invoice templates?',
'invoiceTemplates.deleteItemTitle': 'Remove item template',
'invoiceTemplates.deleteItemMessage': 'Remove "{title}" from predefined line items?',
'invoiceTemplates.itemModalAddTitle': 'Add item template',
'invoiceTemplates.itemModalEditTitle': 'Edit item template',
'invoiceTemplates.itemUpdated': 'Item template updated.',
'invoiceTemplates.itemCreated': 'Item template created.',
'invoiceTemplates.itemRemoved': 'Item template removed.',
'invoiceTemplates.templateRemoved': 'Invoice template removed.',
'invoiceTemplates.loadError': 'Unable to load invoice settings.',
'invoiceTemplates.itemSaveError': 'Unable to save item template.',
'invoiceTemplates.itemRemoveError': 'Unable to remove item.',
'invoiceTemplates.templateRemoveError': 'Unable to remove template.',
'invoiceTemplates.saveItem': 'Save changes',
'invoiceTemplates.savingItem': 'Saving…',
'invoiceTemplates.createItem': 'Create item',
'invoiceTemplates.cancel': 'Cancel',
'invoiceTemplates.hint': 'Tip: issue an invoice from the Invoices page using a template or from scratch.',
'invoiceTemplateEditor.addTitle': 'Add invoice template',
'invoiceTemplateEditor.editTitle': 'Edit invoice template',
'invoiceTemplateEditor.subtitle':
'Define name, top text, line items, key points, and bank accounts for reuse when issuing invoices.',
'invoiceTemplateEditor.name': 'Name',
'invoiceTemplateEditor.namePlaceholder': 'e.g. Standard website package',
'invoiceTemplateEditor.topText': 'Top text',
'invoiceTemplateEditor.topTextPlaceholder': 'Optional intro shown at the top of the invoice',
'invoiceTemplateEditor.nameRequired': 'Template name is required.',
'invoiceTemplateEditor.loadError': 'Unable to load template editor.',
'invoiceTemplateEditor.saveError': 'Unable to save invoice template.',
'invoiceTemplateEditor.updated': 'Invoice template updated.',
'invoiceTemplateEditor.created': 'Invoice template created.',
'invoiceTemplateEditor.backToTemplates': 'Back to templates',
'invoiceTemplateEditor.create': 'Create template',
'invoiceTemplateEditor.save': 'Save changes',
'invoiceTemplateEditor.saving': 'Saving…',
'invoiceTemplateEditor.cancel': 'Cancel',
'invoiceTemplateEditor.loading': 'Loading…',
'login.welcome': 'Welcome back',
'login.subtitle': 'Sign in with your mobile number',
@@ -1406,6 +1633,13 @@ const fa: Record<MessageKey, string> = {
'nav.store.settings': 'تنظیمات',
'nav.customers': 'کاربران',
'nav.customerProducts': 'محصولات مشتریان',
'nav.invoices': 'فاکتورها',
'nav.invoices.list': 'فاکتورها',
'nav.invoices.templates': 'قالب‌ها',
'nav.finance': 'مدیریت مالی',
'nav.finance.overview': 'نمای کلی',
'nav.finance.invoices': 'فاکتورها',
'nav.finance.transactions': 'تراکنش‌ها',
'nav.settings': 'تنظیمات',
'nav.blog': 'بلاگ',
'nav.blog.overview': 'نمای کلی',
@@ -1553,6 +1787,9 @@ const fa: Record<MessageKey, string> = {
'home.card.website.title': 'وب‌سایت',
'home.card.website.desc': 'فرم تماس، سوالات متداول، نشان‌ها، عضویت‌ها و پرداخت الکترونیک.',
'home.card.website.link': 'مشاهده وب‌سایت',
'home.card.finance.title': 'مدیریت مالی',
'home.card.finance.desc': 'فاکتورها و تراکنش‌های مالی را مدیریت کنید.',
'home.card.finance.link': 'مشاهده مالی',
'home.chart.orders.title': 'سفارش‌ها',
'home.chart.orders.subtitle': 'سفارش‌ها در ۳۰ روز گذشته',
@@ -1576,8 +1813,8 @@ const fa: Record<MessageKey, string> = {
'home.chart.customersJoined.activeLegend': 'فعال ({count})',
'home.chart.customersJoined.loading': 'در حال بارگذاری نمودار...',
'home.chart.customersJoined.error': 'بارگذاری فعالیت مشتریان ممکن نشد.',
'home.chart.customersJoined.bar': '{day}: {count} ثبت‌نام',
'home.chart.customersJoined.activeBar': '{day}: {count} فعال',
'home.chart.customersJoined.bar': '{month}: {count} ثبت‌نام',
'home.chart.customersJoined.activeBar': '{month}: {count} فعال',
'home.chart.blogViews.title': 'بازدید مقالات',
'home.chart.blogViews.subtitle': 'بازدید مقالات در ۳۰ روز گذشته',
'home.chart.placeholder.title': 'نمودار',
@@ -2176,6 +2413,7 @@ const fa: Record<MessageKey, string> = {
'customers.edit': 'ویرایش مشتری',
'customers.sms': 'ارسال پیامک',
'customers.tickets': 'تیکت‌ها',
'customers.invoices': 'مشاهده فاکتورها',
'customers.remove': 'حذف مشتری',
'customers.add': 'افزودن مشتری',
'customers.error.load': 'بارگذاری مشتریان ممکن نشد.',
@@ -2663,6 +2901,222 @@ const fa: Record<MessageKey, string> = {
'title.faq': 'سوالات متداول',
'title.badges': 'نشان‌ها',
'title.ePayment': 'پرداخت الکترونیک',
'title.invoices': 'فاکتورها',
'title.finance': 'مدیریت مالی',
'title.issueInvoice': 'صدور فاکتور',
'title.editInvoice': 'ویرایش فاکتور',
'title.invoiceTemplates': 'قالب‌های فاکتور',
'title.addInvoiceTemplate': 'افزودن قالب فاکتور',
'title.editInvoiceTemplate': 'ویرایش قالب فاکتور',
'title.transactions': 'تراکنش‌ها',
'finance.page.subtitle': 'فاکتورها و تراکنش‌های مالی را مدیریت کنید.',
'finance.card.invoices.desc': 'صدور و پیگیری فاکتور برای مشتریان.',
'finance.card.transactions.desc': 'مشاهده تراکنش‌های پرداختی و مالی.',
'transactions.subtitle': 'تراکنش‌های پرداختی و مالی را مشاهده کنید.',
'transactions.lead': 'تراکنش‌ها اینجا نمایش داده می‌شوند.',
'transactions.note': 'این بخش به‌زودی آماده می‌شود. فعلاً می‌توانید جزئیات پرداخت سفارش را از صفحه سفارش‌ها ببینید.',
'invoices.subtitle': 'فاکتورهای صادر شده برای مشتریان خود را مدیریت کنید.',
'invoices.templatesLink': 'مدیریت قالب ها',
'invoices.issue': 'صدور فاکتور',
'invoices.tableTitle': 'فاکتورها',
'invoices.countOne': '{count} فاکتور',
'invoices.countMany': '{count} فاکتور',
'invoices.loading': 'در حال بارگذاری...',
'invoices.empty': 'هنوز فاکتوری ثبت نشده است.',
'invoices.col.name': 'نام',
'invoices.col.customer': 'مشتری',
'invoices.col.issued': 'تاریخ صدور',
'invoices.col.status': 'وضعیت',
'invoices.col.total': 'مبلغ کل',
'invoices.col.link': 'لینک',
'invoices.col.actions': 'عملیات',
'invoices.itemCountOne': '{count} آیتم',
'invoices.itemCountMany': '{count} آیتم',
'invoices.changeStatus': 'تغییر وضعیت',
'invoices.changeStatusAria': 'تغییر وضعیت ({status})',
'invoices.view': 'مشاهده',
'invoices.viewAria': 'مشاهده فاکتور',
'invoices.edit': 'ویرایش',
'invoices.editAria': 'ویرایش فاکتور',
'invoices.editDisabledTitle': 'فاکتورهای تاییدشده قابل ویرایش نیستند',
'invoices.editDisabledAria': 'ویرایش فاکتور (غیرفعال — تاییدشده)',
'invoices.remove': 'حذف',
'invoices.removeAria': 'حذف فاکتور',
'invoices.copyLink': 'کپی لینک',
'invoices.copyLinkAria': 'کپی لینک فاکتور',
'invoices.linkCopied': 'لینک فاکتور کپی شد.',
'invoices.linkCopyError': 'کپی لینک ممکن نشد.',
'invoices.deleteTitle': 'حذف فاکتور؟',
'invoices.deleteMessage': 'این فاکتور برای همیشه حذف شود؟ این عملیات قابل بازگشت نیست.',
'invoices.removed': 'فاکتور حذف شد.',
'invoices.removeError': 'حذف فاکتور ممکن نشد.',
'invoices.statusUpdated': 'وضعیت فاکتور به‌روزرسانی شد.',
'invoices.statusUpdateError': 'به‌روزرسانی وضعیت ممکن نشد.',
'invoices.loadError': 'بارگذاری فاکتورها ممکن نشد.',
'invoices.filterBannerNamed': 'فاکتور های {name}',
'invoices.filterBannerGeneric': 'فاکتور های این مشتری',
'invoices.filterCancel': 'انصراف',
'invoices.filterClear': 'پاک کردن فیلتر',
'invoices.issueForCustomer': 'صدور فاکتور برای این مشتری',
'invoices.detailFallbackTitle': 'فاکتور',
'invoices.detail.status': 'وضعیت',
'invoices.detail.total': 'مبلغ کل',
'invoices.detail.link': 'لینک عمومی',
'invoices.detail.billedTo': 'صادر شده برای',
'invoices.detail.notes': 'یادداشت: {notes}',
'invoices.status.draft': 'پیش‌نویس',
'invoices.status.issued': 'صادرشده',
'invoices.status.approved': 'تاییدشده',
'invoices.status.paid': 'پرداخت‌شده',
'invoices.status.cancelled': 'لغوشده',
'issueInvoice.subtitleNew': 'یک قالب فاکتور انتخاب و ویرایش کنید یا یک فاکتور خالی بسازید.',
'issueInvoice.subtitleEdit': 'محتوای فاکتور را به‌روزرسانی کنید. فاکتورهای تاییدشده قابل تغییر نیستند.',
'issueInvoice.startFromTemplate': 'شروع از قالب',
'issueInvoice.blankInvoice': 'بدون قالب',
'issueInvoice.name': 'نام (اختیاری)',
'issueInvoice.namePlaceholder': 'مثلاً بسته طراحی سایت',
'issueInvoice.noTemplatesHint': 'هنوز قالب فاکتوری ندارید. آن‌ها را در {link} مدیریت کنید یا فاکتور خالی زیر را تکمیل کنید.',
'issueInvoice.noTemplatesLink': 'قالب‌های فاکتور',
'issueInvoice.topText': 'متن بالای فاکتور',
'issueInvoice.topTextPlaceholder': 'متن مقدماتی اختیاری در بالای فاکتور',
'issueInvoice.notes': 'یادداشت‌ها',
'issueInvoice.notesPlaceholder': 'یادداشت داخلی اختیاری',
'issueInvoice.total': 'مبلغ کل: {total}',
'issueInvoice.totalLabel': 'مبلغ کل',
'issueInvoice.cancel': 'انصراف',
'issueInvoice.save': 'ذخیره تغییرات',
'issueInvoice.saving': 'در حال ذخیره...',
'issueInvoice.issue': 'صدور فاکتور',
'issueInvoice.issuing': 'در حال صدور...',
'issueInvoice.backToInvoices': 'بازگشت به فاکتورها',
'issueInvoice.approvedLocked': 'این فاکتور تاییدشده و دیگر قابل ویرایش نیست.',
'issueInvoice.loadError': 'بارگذاری فرم فاکتور ممکن نشد.',
'issueInvoice.updateError': 'به‌روزرسانی فاکتور ممکن نشد.',
'issueInvoice.createError': 'ایجاد فاکتور ممکن نشد.',
'issueInvoice.updated': 'فاکتور به‌روزرسانی شد.',
'issueInvoice.issued': 'فاکتور صادر شد.',
'issueInvoice.recipient': 'صدور فاکتور برای',
'issueInvoice.recipientFor': 'صدور فاکتور برای {name}',
'issueInvoice.recipientRequired': 'یک مشتری برای صدور این فاکتور انتخاب کنید.',
'issueInvoice.pickCustomer': 'انتخاب مشتری',
'issueInvoice.pickCustomerPlaceholder': 'جستجو بر اساس نام یا شماره تماس...',
'issueInvoice.pickCustomerNoResults': 'مشتری‌ای یافت نشد.',
'issueInvoice.pickCustomerHint': 'برای جستجو حداقل ۲ کاراکتر وارد کنید.',
'issueInvoice.changeCustomer': 'تغییر',
'issueInvoice.unknownCustomer': 'مشتری',
'issueInvoice.loading': 'در حال بارگذاری...',
'invoiceDraft.itemLabel': 'آیتم {index}',
'invoiceDraft.removeItem': 'حذف آیتم',
'invoiceDraft.fieldTitle': 'عنوان',
'invoiceDraft.fieldTitlePlaceholder': 'عنوان خدمت',
'invoiceDraft.fieldDuration': 'مدت',
'invoiceDraft.fieldDurationPlaceholder': 'مثلاً ۳ ماه',
'invoiceDraft.fieldWorktime': 'ساعت کاری',
'invoiceDraft.fieldWorktimePlaceholder': 'مثلاً ۴۰ ساعت',
'invoiceDraft.fieldPrice': 'قیمت (تومان)',
'invoiceDraft.fieldDiscountedPrice': 'قیمت با تخفیف (تومان)',
'invoiceDraft.fieldDiscountedPricePlaceholder': 'اختیاری',
'invoiceDraft.optional': 'اختیاری',
'invoiceDraft.fieldDescription': 'توضیحات',
'invoiceDraft.fieldDescriptionPlaceholder': 'جزئیات اختیاری',
'invoiceDraft.addFromTemplate': 'افزودن از قالب...',
'invoiceDraft.addFromTemplateAria': 'افزودن از قالب آیتم',
'invoiceDraft.add': 'افزودن',
'invoiceDraft.addCustomItem': 'افزودن آیتم سفارشی',
'invoiceDraft.keyPoints': 'نکات کلیدی',
'invoiceDraft.addPoint': 'افزودن نکته',
'invoiceDraft.noKeyPoints': 'هنوز نکته کلیدی‌ای ثبت نشده است.',
'invoiceDraft.keyPointPlaceholder': 'مثلاً پرداخت ظرف ۷ روز',
'invoiceDraft.keyPointAria': 'نکته کلیدی {index}',
'invoiceDraft.removeKeyPoint': 'حذف نکته کلیدی',
'invoiceDraft.accounts': 'شماره حساب‌ها',
'invoiceDraft.addAccount': 'افزودن حساب',
'invoiceDraft.noAccounts': 'هنوز حساب بانکی‌ای ثبت نشده است.',
'invoiceDraft.bankName': 'نام بانک',
'invoiceDraft.accountHolder': 'صاحب حساب',
'invoiceDraft.cardNumber': 'شماره کارت',
'invoiceDraft.iban': 'شبا',
'invoiceDraft.removeAccount': 'حذف حساب',
'invoiceDraft.error.itemTitle': 'هر آیتم به عنوان نیاز دارد.',
'invoiceDraft.error.itemPrice': 'قیمت برای «{title}» الزامی است.',
'invoiceDraft.error.itemDiscountInvalid': 'قیمت با تخفیف برای «{title}» نامعتبر است.',
'invoiceDraft.error.itemDiscountExceeds': 'قیمت با تخفیف نمی‌تواند از قیمت اصلی «{title}» بیشتر باشد.',
'invoiceTemplates.subtitle': 'قالب‌های فاکتور و آیتم‌های از پیش تعریف‌شده را مدیریت کنید.',
'invoiceTemplates.section.templates.title': 'قالب‌های فاکتور',
'invoiceTemplates.section.templates.desc':
'الگوهای کامل برای صدور سریع‌تر فاکتور — یکی را انتخاب کنید یا از خالی شروع کنید.',
'invoiceTemplates.addTemplate': 'افزودن قالب',
'invoiceTemplates.templatesTableTitle': 'قالب‌ها',
'invoiceTemplates.countTemplatesOne': '{count} قالب',
'invoiceTemplates.countTemplatesMany': '{count} قالب',
'invoiceTemplates.col.name': 'نام',
'invoiceTemplates.col.items': 'آیتم‌ها',
'invoiceTemplates.col.keyPoints': 'نکات کلیدی',
'invoiceTemplates.col.accounts': 'حساب‌ها',
'invoiceTemplates.col.actions': 'عملیات',
'invoiceTemplates.emptyTemplates': 'هنوز قالب فاکتوری ندارید. یکی اضافه کنید تا صدور فاکتور سریع‌تر شود.',
'invoiceTemplates.section.items.title': 'قالب‌های آیتم فاکتور',
'invoiceTemplates.section.items.desc':
'آیتم‌های قابل استفاده مجدد که می‌توانید در قالب‌های فاکتور یا هنگام صدور فاکتور استفاده کنید.',
'invoiceTemplates.addItem': 'افزودن آیتم',
'invoiceTemplates.itemsTableTitle': 'آیتم‌های از پیش تعریف‌شده',
'invoiceTemplates.countItemsOne': '{count} آیتم',
'invoiceTemplates.countItemsMany': '{count} آیتم',
'invoiceTemplates.col.title': 'عنوان',
'invoiceTemplates.col.duration': 'مدت',
'invoiceTemplates.col.worktime': 'ساعت کاری',
'invoiceTemplates.col.price': 'قیمت',
'invoiceTemplates.col.discounted': 'با تخفیف',
'invoiceTemplates.emptyItems': 'هنوز آیتم از پیش تعریف‌شده‌ای ندارید.',
'invoiceTemplates.editTemplate': 'ویرایش',
'invoiceTemplates.removeTemplate': 'حذف',
'invoiceTemplates.editItem': 'ویرایش',
'invoiceTemplates.removeItem': 'حذف',
'invoiceTemplates.deleteTemplateTitle': 'حذف قالب فاکتور',
'invoiceTemplates.deleteTemplateMessage': '«{name}» از قالب‌های فاکتور حذف شود؟',
'invoiceTemplates.deleteItemTitle': 'حذف قالب آیتم',
'invoiceTemplates.deleteItemMessage': '«{title}» از آیتم‌های از پیش تعریف‌شده حذف شود؟',
'invoiceTemplates.itemModalAddTitle': 'افزودن قالب آیتم',
'invoiceTemplates.itemModalEditTitle': 'ویرایش قالب آیتم',
'invoiceTemplates.itemUpdated': 'قالب آیتم به‌روزرسانی شد.',
'invoiceTemplates.itemCreated': 'قالب آیتم ایجاد شد.',
'invoiceTemplates.itemRemoved': 'قالب آیتم حذف شد.',
'invoiceTemplates.templateRemoved': 'قالب فاکتور حذف شد.',
'invoiceTemplates.loadError': 'بارگذاری تنظیمات فاکتور ممکن نشد.',
'invoiceTemplates.itemSaveError': 'ذخیره قالب آیتم ممکن نشد.',
'invoiceTemplates.itemRemoveError': 'حذف آیتم ممکن نشد.',
'invoiceTemplates.templateRemoveError': 'حذف قالب ممکن نشد.',
'invoiceTemplates.saveItem': 'ذخیره تغییرات',
'invoiceTemplates.savingItem': 'در حال ذخیره...',
'invoiceTemplates.createItem': 'ایجاد آیتم',
'invoiceTemplates.cancel': 'انصراف',
'invoiceTemplates.hint': 'نکته: از صفحه فاکتورها با استفاده از یک قالب یا از ابتدا فاکتور صادر کنید.',
'invoiceTemplateEditor.addTitle': 'افزودن قالب فاکتور',
'invoiceTemplateEditor.editTitle': 'ویرایش قالب فاکتور',
'invoiceTemplateEditor.subtitle':
'نام، متن بالا، آیتم‌ها، نکات کلیدی و حساب‌های بانکی را برای استفاده مجدد هنگام صدور فاکتور تعریف کنید.',
'invoiceTemplateEditor.name': 'نام',
'invoiceTemplateEditor.namePlaceholder': 'مثلاً بسته استاندارد سایت',
'invoiceTemplateEditor.topText': 'متن بالای فاکتور',
'invoiceTemplateEditor.topTextPlaceholder': 'متن مقدماتی اختیاری در بالای فاکتور',
'invoiceTemplateEditor.nameRequired': 'نام قالب الزامی است.',
'invoiceTemplateEditor.loadError': 'بارگذاری ویرایشگر قالب ممکن نشد.',
'invoiceTemplateEditor.saveError': 'ذخیره قالب فاکتور ممکن نشد.',
'invoiceTemplateEditor.updated': 'قالب فاکتور به‌روزرسانی شد.',
'invoiceTemplateEditor.created': 'قالب فاکتور ایجاد شد.',
'invoiceTemplateEditor.backToTemplates': 'بازگشت به قالب‌ها',
'invoiceTemplateEditor.create': 'ایجاد قالب',
'invoiceTemplateEditor.save': 'ذخیره تغییرات',
'invoiceTemplateEditor.saving': 'در حال ذخیره...',
'invoiceTemplateEditor.cancel': 'انصراف',
'invoiceTemplateEditor.loading': 'در حال بارگذاری...',
'login.welcome': 'خوش آمدید',
'login.subtitle': 'با شماره موبایل وارد شوید',
@@ -2844,10 +3298,27 @@ export function getBusinessRouteTitleRules(locale: DashboardLocale): RouteTitleR
{ match: '/store/settings', labels: [t('title.store'), t('title.settings')] },
{ match: '/store', labels: [t('title.store')] },
{ match: '/customers', labels: [t('title.customers')] },
{ match: '/finance', labels: [t('title.finance')] },
{ match: '/customer-products/new', labels: [t('title.customerProducts'), t('customerProducts.add')] },
{ match: /^\/customer-products\/[^/]+\/edit$/, labels: [t('title.customerProducts'), t('customerProducts.edit')] },
{ match: /^\/customer-products\/[^/]+$/, labels: [t('title.customerProducts'), t('customerProducts.detailsTitle')] },
{ match: '/customer-products', labels: [t('title.customerProducts')] },
{
match: /^\/invoices\/templates\/new$/,
labels: [t('title.finance'), t('title.invoiceTemplates'), t('title.addInvoiceTemplate')],
},
{
match: /^\/invoices\/templates\/[^/]+$/,
labels: [t('title.finance'), t('title.invoiceTemplates'), t('title.editInvoiceTemplate')],
},
{ match: '/invoices/templates', labels: [t('title.finance'), t('title.invoiceTemplates')] },
{ match: '/invoices/new', labels: [t('title.finance'), t('title.invoices'), t('title.issueInvoice')] },
{
match: /^\/invoices\/[^/]+\/edit$/,
labels: [t('title.finance'), t('title.invoices'), t('title.editInvoice')],
},
{ 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')] },