Localize wallet and ticket pages.

Move the wallet page and all four ticket views (user list, ticket detail,
staff queue, admin overview) onto the i18n dictionaries — statuses,
priorities, departments, forms, stats, toasts and empty states — using
locale-aware Link/router and locale-aware date formatting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
keyhan
2026-06-11 12:54:19 +03:30
parent 2bc86c03b8
commit e99dccaff1
8 changed files with 309 additions and 123 deletions
+86
View File
@@ -249,6 +249,92 @@ const en: Dictionary = {
deleted: 'Service deleted',
deletedWithCredit: 'Service deleted. Prepaid resources are on your dashboard.',
},
wallet: {
title: 'Wallet',
subtitle: 'Manage your balance and transactions',
currentBalance: 'Current Balance',
toman: 'Toman',
topUp: 'Top Up',
amountPlaceholder: 'Amount (Toman) — min 1,000',
payNow: 'Pay Now',
transactionHistory: 'Transaction History',
noTransactions: 'No transactions yet',
balanceAfter: 'Balance: {amount} {unit}',
invoice: 'Invoice {number}',
minChargeError: 'Minimum charge amount is 1,000 Toman',
chargedSuccess: 'Wallet charged successfully',
chargeFailed: 'Failed to charge wallet',
paymentSuccess: 'Payment successful — wallet charged',
paymentFailed: 'Payment failed',
topUpDesc: 'Wallet top-up',
topUpGatewayDesc: 'Wallet top-up via gateway',
txTypes: {
charge: 'Deposit',
deduction: 'Payment',
refund: 'Refund',
gateway_payment: 'Gateway payment',
},
},
tickets: {
status: { open: 'Open', waiting: 'Waiting', answered: 'Answered', closed: 'Closed' },
priority: { low: 'Low', medium: 'Medium', high: 'High' },
department: { technical: 'Technical', sales: 'Sales' },
departmentFull: { technical: 'Technical Support', sales: 'Sales' },
role: { admin: 'Admin', technical: 'Technical', sales: 'Sales' },
myTickets: 'My Tickets',
myTicketsSubtitle: 'Support tickets and their status',
newTicket: 'New Ticket',
createNewTicket: 'Create New Ticket',
subject: 'Subject',
subjectPlaceholder: 'Brief description of your issue',
departmentField: 'Department',
priorityField: 'Priority',
messageField: 'Message',
messagePlaceholder: 'Describe your issue in detail...',
submitTicket: 'Submit Ticket',
creating: 'Creating...',
noTickets: 'No tickets yet',
noTicketsHint: 'Create a ticket if you need help',
createdSuccess: 'Ticket created successfully',
createFailed: 'Failed to create ticket',
messages: '{n} message(s)',
msg: '{n} msg',
back: 'Back',
notFound: 'Ticket not found',
by: 'by',
closeTicket: 'Close Ticket',
closedNotice: 'This ticket is closed. Create a new ticket if you need further assistance.',
replyPlaceholder: 'Type your reply...',
send: 'Send',
replySent: 'Reply sent',
replyFailed: 'Failed to send reply',
ticketClosed: 'Ticket closed',
unknown: 'Unknown',
ticketsTitle: '{dept} Tickets',
totalTickets: '{n} total tickets',
unanswered: 'Unanswered',
needResponse: 'Need response',
answered: 'Answered',
waitingForUser: 'Waiting for user',
totalOpen: 'Total Open',
excludingClosed: 'Excluding closed',
all: 'All',
noTicketsStaff: 'No tickets',
noStatusTickets: 'No {status} tickets',
noDeptTickets: 'No tickets in this department',
allTickets: 'All Tickets',
allTicketsSubtitle: 'Overview of all support tickets across departments',
totalTicketsStat: 'Total Tickets',
needStaffResponse: 'Need staff response',
avgResponseTime: 'Avg Response Time',
byDepartment: 'By Department',
departmentLabel: 'Department:',
statusLabel: 'Status:',
noTicketsFound: 'No tickets found',
minutes: '{n} min',
hours: '{n} hours',
days: '{n} days',
},
},
};
+86
View File
@@ -248,6 +248,92 @@ const fa = {
deleted: 'سرویس حذف شد',
deletedWithCredit: 'سرویس حذف شد. منابع پیش‌پرداختت روی داشبورد است.',
},
wallet: {
title: 'کیف‌پول',
subtitle: 'موجودی و تراکنش‌هایت را مدیریت کن',
currentBalance: 'موجودی فعلی',
toman: 'تومان',
topUp: 'افزایش موجودی',
amountPlaceholder: 'مبلغ (تومان) — حداقل ۱٬۰۰۰',
payNow: 'پرداخت',
transactionHistory: 'تاریخچهٔ تراکنش‌ها',
noTransactions: 'هنوز تراکنشی نداری',
balanceAfter: 'موجودی: {amount} {unit}',
invoice: 'فاکتور {number}',
minChargeError: 'حداقل مبلغ شارژ ۱٬۰۰۰ تومان است',
chargedSuccess: 'کیف‌پول با موفقیت شارژ شد',
chargeFailed: 'شارژ کیف‌پول ناموفق بود',
paymentSuccess: 'پرداخت موفق — کیف‌پول شارژ شد',
paymentFailed: 'پرداخت ناموفق بود',
topUpDesc: 'شارژ کیف‌پول',
topUpGatewayDesc: 'شارژ کیف‌پول از طریق درگاه',
txTypes: {
charge: 'واریز',
deduction: 'پرداخت',
refund: 'بازگشت وجه',
gateway_payment: 'پرداخت درگاهی',
},
},
tickets: {
status: { open: 'باز', waiting: 'در انتظار', answered: 'پاسخ‌داده‌شده', closed: 'بسته' },
priority: { low: 'کم', medium: 'متوسط', high: 'زیاد' },
department: { technical: 'فنی', sales: 'فروش' },
departmentFull: { technical: 'پشتیبانی فنی', sales: 'فروش' },
role: { admin: 'مدیر', technical: 'فنی', sales: 'فروش' },
myTickets: 'تیکت‌های من',
myTicketsSubtitle: 'تیکت‌های پشتیبانی و وضعیتشان',
newTicket: 'تیکت جدید',
createNewTicket: 'ساخت تیکت جدید',
subject: 'موضوع',
subjectPlaceholder: 'توضیح کوتاهی از مشکلت',
departmentField: 'بخش',
priorityField: 'اولویت',
messageField: 'پیام',
messagePlaceholder: 'مشکلت را با جزئیات توضیح بده…',
submitTicket: 'ثبت تیکت',
creating: 'در حال ساخت…',
noTickets: 'هنوز تیکتی نداری',
noTicketsHint: 'اگر به کمک نیاز داری یک تیکت بساز',
createdSuccess: 'تیکت با موفقیت ساخته شد',
createFailed: 'ساخت تیکت ناموفق بود',
messages: '{n} پیام',
msg: '{n} پیام',
back: 'بازگشت',
notFound: 'تیکت پیدا نشد',
by: 'توسط',
closeTicket: 'بستن تیکت',
closedNotice: 'این تیکت بسته شده است. اگر باز هم کمک خواستی، تیکت جدیدی بساز.',
replyPlaceholder: 'پاسخت را بنویس…',
send: 'ارسال',
replySent: 'پاسخ ارسال شد',
replyFailed: 'ارسال پاسخ ناموفق بود',
ticketClosed: 'تیکت بسته شد',
unknown: 'ناشناس',
ticketsTitle: 'تیکت‌های {dept}',
totalTickets: '{n} تیکت در مجموع',
unanswered: 'بی‌پاسخ',
needResponse: 'نیازمند پاسخ',
answered: 'پاسخ‌داده‌شده',
waitingForUser: 'منتظر کاربر',
totalOpen: 'مجموع باز',
excludingClosed: 'به‌جز بسته‌ها',
all: 'همه',
noTicketsStaff: 'تیکتی نیست',
noStatusTickets: 'تیکت «{status}» وجود ندارد',
noDeptTickets: 'در این بخش تیکتی نیست',
allTickets: 'همهٔ تیکت‌ها',
allTicketsSubtitle: 'نمای کلیِ همهٔ تیکت‌های پشتیبانی در همهٔ بخش‌ها',
totalTicketsStat: 'کل تیکت‌ها',
needStaffResponse: 'نیازمند پاسخ پشتیبان',
avgResponseTime: 'میانگین زمان پاسخ',
byDepartment: 'بر اساس بخش',
departmentLabel: 'بخش:',
statusLabel: 'وضعیت:',
noTicketsFound: 'تیکتی پیدا نشد',
minutes: '{n} دقیقه',
hours: '{n} ساعت',
days: '{n} روز',
},
},
};