Deploy rule, CRM enhancements, Company Employee category, bilingual, contacts module completion
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
541
frontend/src/contexts/LanguageContext.tsx
Normal file
541
frontend/src/contexts/LanguageContext.tsx
Normal file
@@ -0,0 +1,541 @@
|
||||
'use client'
|
||||
|
||||
import { createContext, useContext, useState, useEffect, ReactNode } from 'react'
|
||||
|
||||
type Language = 'en' | 'ar'
|
||||
|
||||
interface LanguageContextType {
|
||||
language: Language
|
||||
setLanguage: (lang: Language) => void
|
||||
t: (key: string) => string
|
||||
dir: 'ltr' | 'rtl'
|
||||
}
|
||||
|
||||
const LanguageContext = createContext<LanguageContextType | undefined>(undefined)
|
||||
|
||||
export function LanguageProvider({ children }: { children: ReactNode }) {
|
||||
const [language, setLanguageState] = useState<Language>('en')
|
||||
|
||||
useEffect(() => {
|
||||
// Load language from localStorage
|
||||
const savedLang = localStorage.getItem('language') as Language
|
||||
if (savedLang && (savedLang === 'en' || savedLang === 'ar')) {
|
||||
setLanguageState(savedLang)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
// Update document direction and lang attribute
|
||||
document.documentElement.lang = language
|
||||
document.documentElement.dir = language === 'ar' ? 'rtl' : 'ltr'
|
||||
}, [language])
|
||||
|
||||
const setLanguage = (lang: Language) => {
|
||||
setLanguageState(lang)
|
||||
localStorage.setItem('language', lang)
|
||||
}
|
||||
|
||||
const t = (key: string): string => {
|
||||
const keys = key.split('.')
|
||||
let value: any = translations[language]
|
||||
|
||||
for (const k of keys) {
|
||||
value = value?.[k]
|
||||
}
|
||||
|
||||
return value || key
|
||||
}
|
||||
|
||||
return (
|
||||
<LanguageContext.Provider
|
||||
value={{
|
||||
language,
|
||||
setLanguage,
|
||||
t,
|
||||
dir: language === 'ar' ? 'rtl' : 'ltr'
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</LanguageContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useLanguage() {
|
||||
const context = useContext(LanguageContext)
|
||||
if (!context) {
|
||||
throw new Error('useLanguage must be used within a LanguageProvider')
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
// Translation dictionary
|
||||
const translations = {
|
||||
en: {
|
||||
common: {
|
||||
save: 'Save',
|
||||
cancel: 'Cancel',
|
||||
delete: 'Delete',
|
||||
edit: 'Edit',
|
||||
add: 'Add',
|
||||
search: 'Search',
|
||||
filter: 'Filter',
|
||||
export: 'Export',
|
||||
import: 'Import',
|
||||
loading: 'Loading...',
|
||||
noData: 'No data available',
|
||||
error: 'An error occurred',
|
||||
success: 'Success',
|
||||
confirm: 'Confirm',
|
||||
back: 'Back',
|
||||
next: 'Next',
|
||||
finish: 'Finish',
|
||||
close: 'Close',
|
||||
yes: 'Yes',
|
||||
no: 'No',
|
||||
required: 'Required',
|
||||
optional: 'Optional',
|
||||
actions: 'Actions',
|
||||
status: 'Status',
|
||||
active: 'Active',
|
||||
inactive: 'Inactive',
|
||||
archived: 'Archived',
|
||||
deleted: 'Deleted'
|
||||
},
|
||||
nav: {
|
||||
dashboard: 'Dashboard',
|
||||
contacts: 'Contacts',
|
||||
crm: 'CRM',
|
||||
projects: 'Projects',
|
||||
inventory: 'Inventory',
|
||||
hr: 'HR',
|
||||
marketing: 'Marketing',
|
||||
settings: 'Settings',
|
||||
logout: 'Logout'
|
||||
},
|
||||
contacts: {
|
||||
title: 'Contacts',
|
||||
addContact: 'Add Contact',
|
||||
editContact: 'Edit Contact',
|
||||
deleteContact: 'Delete Contact',
|
||||
viewContact: 'View Contact',
|
||||
mergeContacts: 'Merge Contacts',
|
||||
importContacts: 'Import Contacts',
|
||||
exportContacts: 'Export Contacts',
|
||||
totalContacts: 'Total Contacts',
|
||||
searchPlaceholder: 'Search by name, email, or phone...',
|
||||
noContactsFound: 'No contacts found',
|
||||
contactDetails: 'Contact Details',
|
||||
contactInfo: 'Contact Information',
|
||||
companyInfo: 'Company Information',
|
||||
address: 'Address',
|
||||
categories: 'Categories & Tags',
|
||||
relationships: 'Relationships',
|
||||
hierarchy: 'Hierarchy',
|
||||
activities: 'Activities',
|
||||
history: 'History',
|
||||
type: 'Type',
|
||||
name: 'Name',
|
||||
nameAr: 'Name (Arabic)',
|
||||
email: 'Email',
|
||||
phone: 'Phone',
|
||||
mobile: 'Mobile',
|
||||
website: 'Website',
|
||||
companyName: 'Company Name',
|
||||
companyNameAr: 'Company Name (Arabic)',
|
||||
taxNumber: 'Tax Number',
|
||||
commercialRegister: 'Commercial Register',
|
||||
city: 'City',
|
||||
country: 'Country',
|
||||
postalCode: 'Postal Code',
|
||||
source: 'Source',
|
||||
rating: 'Rating',
|
||||
tags: 'Tags',
|
||||
individual: 'Individual',
|
||||
company: 'Company',
|
||||
holding: 'Holding',
|
||||
government: 'Government',
|
||||
addRelationship: 'Add Relationship',
|
||||
relationshipType: 'Relationship Type',
|
||||
startDate: 'Start Date',
|
||||
endDate: 'End Date',
|
||||
notes: 'Notes',
|
||||
representative: 'Representative',
|
||||
partner: 'Partner',
|
||||
supplier: 'Supplier',
|
||||
employee: 'Employee',
|
||||
subsidiary: 'Subsidiary',
|
||||
branch: 'Branch',
|
||||
parentCompany: 'Parent Company',
|
||||
customer: 'Customer',
|
||||
vendor: 'Vendor',
|
||||
companyEmployee: 'Company Employee',
|
||||
other: 'Other',
|
||||
duplicateFound: 'Potential Duplicates Found',
|
||||
duplicateWarning: 'Similar contacts found. Please review before continuing.',
|
||||
mergeInstead: 'Merge Instead',
|
||||
continueAnyway: 'Continue Anyway',
|
||||
sourceContact: 'Source Contact',
|
||||
targetContact: 'Target Contact',
|
||||
compareFields: 'Compare Fields',
|
||||
preview: 'Preview',
|
||||
mergeWarning: 'This action cannot be undone!',
|
||||
mergeReason: 'Reason for Merge',
|
||||
mergeSuccess: 'Contacts merged successfully!',
|
||||
importSuccess: 'Contacts imported successfully',
|
||||
exportSuccess: 'Contacts exported successfully',
|
||||
deleteConfirm: 'Are you sure you want to delete this contact?',
|
||||
deleteSuccess: 'Contact deleted successfully',
|
||||
createSuccess: 'Contact created successfully',
|
||||
updateSuccess: 'Contact updated successfully'
|
||||
},
|
||||
crm: {
|
||||
title: 'CRM',
|
||||
subtitle: 'CRM & Sales Pipeline',
|
||||
addDeal: 'Add Deal',
|
||||
editDeal: 'Edit Deal',
|
||||
dealName: 'Deal Name',
|
||||
contact: 'Contact',
|
||||
structure: 'Deal Structure',
|
||||
pipeline: 'Pipeline',
|
||||
stage: 'Stage',
|
||||
probability: 'Probability',
|
||||
estimatedValue: 'Estimated Value (SAR)',
|
||||
expectedCloseDate: 'Expected Close Date',
|
||||
searchPlaceholder: 'Search deals...',
|
||||
filterStructure: 'Structure',
|
||||
filterStage: 'Stage',
|
||||
filterStatus: 'Status',
|
||||
all: 'All',
|
||||
view: 'View',
|
||||
win: 'Win',
|
||||
lose: 'Lose',
|
||||
archive: 'Archive',
|
||||
deleteDeal: 'Delete Deal',
|
||||
markWon: 'Mark as Won',
|
||||
markLost: 'Mark as Lost',
|
||||
actualValue: 'Actual Value (SAR)',
|
||||
wonReason: 'Reason Won',
|
||||
lostReason: 'Reason Lost',
|
||||
noDealsFound: 'No deals found',
|
||||
createSuccess: 'Deal created successfully',
|
||||
updateSuccess: 'Deal updated successfully',
|
||||
winSuccess: 'Deal won successfully',
|
||||
loseSuccess: 'Deal marked as lost',
|
||||
deleteSuccess: 'Deal archived successfully',
|
||||
fixFormErrors: 'Please fix form errors',
|
||||
pipelineRequired: 'Pipeline is required',
|
||||
dealNameMin: 'Deal name must be at least 3 characters',
|
||||
contactRequired: 'Contact is required',
|
||||
structureRequired: 'Deal structure is required',
|
||||
stageRequired: 'Stage is required',
|
||||
valueRequired: 'Estimated value must be greater than 0',
|
||||
selectPipeline: 'Select Pipeline',
|
||||
selectContact: 'Select Contact',
|
||||
enterDealName: 'Enter deal name',
|
||||
structureB2B: 'B2B - شركة لشركة',
|
||||
structureB2C: 'B2C - شركة لفرد',
|
||||
structureB2G: 'B2G - شركة لحكومة',
|
||||
structurePartnership: 'Partnership - شراكة',
|
||||
dealDetail: 'Deal Details',
|
||||
quotes: 'Quotes',
|
||||
history: 'History',
|
||||
dealInfo: 'Deal Info',
|
||||
quickActions: 'Quick Actions',
|
||||
totalValue: 'Total Value',
|
||||
expectedValue: 'Expected Value',
|
||||
activeDeals: 'Active Deals',
|
||||
wonDeals: 'Won Deals',
|
||||
inPipeline: 'In pipeline',
|
||||
winRate: 'win rate',
|
||||
conversion: 'conversion',
|
||||
retry: 'Retry',
|
||||
createFirstDeal: 'Create First Deal',
|
||||
loadingDeals: 'Loading deals...',
|
||||
creating: 'Creating...',
|
||||
updating: 'Updating...',
|
||||
updateDeal: 'Update Deal',
|
||||
createDeal: 'Create Deal',
|
||||
newDeal: 'New Deal',
|
||||
allStructures: 'All Structures',
|
||||
allStages: 'All Stages',
|
||||
allStatus: 'All Status',
|
||||
deal: 'Deal',
|
||||
value: 'Value',
|
||||
owner: 'Owner',
|
||||
markDealWon: 'Mark Deal as Won',
|
||||
markDealLost: 'Mark Deal as Lost',
|
||||
reasonForWinning: 'Reason for Winning',
|
||||
reasonForLosing: 'Reason for Losing',
|
||||
winPlaceholder: 'Why did we win this deal?',
|
||||
losePlaceholder: 'Why did we lose this deal?',
|
||||
createNewDeal: 'Create New Deal',
|
||||
paginationPrevious: 'Previous',
|
||||
paginationNext: 'Next',
|
||||
processing: 'Processing...',
|
||||
deleting: 'Deleting...',
|
||||
deleteDealConfirm: 'Are you sure you want to delete',
|
||||
deleteDealDesc: 'This will mark the deal as lost'
|
||||
},
|
||||
import: {
|
||||
title: 'Import Contacts',
|
||||
downloadTemplate: 'Download Excel Template',
|
||||
dragDrop: 'Drag & drop an Excel or CSV file here',
|
||||
orClick: 'or click to select a file',
|
||||
fileRequirements: 'File Requirements:',
|
||||
step: 'Step',
|
||||
uploading: 'Uploading...',
|
||||
importing: 'Importing...',
|
||||
rowsPreview: 'rows to preview',
|
||||
warning: 'Warning',
|
||||
duplicateHandling: 'Duplicate contacts will be skipped and logged in the error report.',
|
||||
results: 'Results',
|
||||
successful: 'Successful',
|
||||
duplicates: 'Duplicates',
|
||||
failed: 'Failed',
|
||||
errors: 'Errors',
|
||||
downloadErrorReport: 'Download Error Report',
|
||||
importComplete: 'Import completed'
|
||||
},
|
||||
messages: {
|
||||
loginSuccess: 'Login successful',
|
||||
loginError: 'Invalid credentials',
|
||||
networkError: 'Network error. Please check your connection.',
|
||||
permissionDenied: 'Permission denied',
|
||||
sessionExpired: 'Session expired. Please login again.'
|
||||
}
|
||||
},
|
||||
ar: {
|
||||
common: {
|
||||
save: 'حفظ',
|
||||
cancel: 'إلغاء',
|
||||
delete: 'حذف',
|
||||
edit: 'تعديل',
|
||||
add: 'إضافة',
|
||||
search: 'بحث',
|
||||
filter: 'تصفية',
|
||||
export: 'تصدير',
|
||||
import: 'استيراد',
|
||||
loading: 'جاري التحميل...',
|
||||
noData: 'لا توجد بيانات',
|
||||
error: 'حدث خطأ',
|
||||
success: 'نجح',
|
||||
confirm: 'تأكيد',
|
||||
back: 'رجوع',
|
||||
next: 'التالي',
|
||||
finish: 'إنهاء',
|
||||
close: 'إغلاق',
|
||||
yes: 'نعم',
|
||||
no: 'لا',
|
||||
required: 'مطلوب',
|
||||
optional: 'اختياري',
|
||||
actions: 'إجراءات',
|
||||
status: 'الحالة',
|
||||
active: 'نشط',
|
||||
inactive: 'غير نشط',
|
||||
archived: 'مؤرشف',
|
||||
deleted: 'محذوف'
|
||||
},
|
||||
nav: {
|
||||
dashboard: 'لوحة التحكم',
|
||||
contacts: 'جهات الاتصال',
|
||||
crm: 'إدارة العملاء',
|
||||
projects: 'المشاريع',
|
||||
inventory: 'المخزون',
|
||||
hr: 'الموارد البشرية',
|
||||
marketing: 'التسويق',
|
||||
settings: 'الإعدادات',
|
||||
logout: 'تسجيل الخروج'
|
||||
},
|
||||
contacts: {
|
||||
title: 'جهات الاتصال',
|
||||
addContact: 'إضافة جهة اتصال',
|
||||
editContact: 'تعديل جهة الاتصال',
|
||||
deleteContact: 'حذف جهة الاتصال',
|
||||
viewContact: 'عرض جهة الاتصال',
|
||||
mergeContacts: 'دمج جهات الاتصال',
|
||||
importContacts: 'استيراد جهات الاتصال',
|
||||
exportContacts: 'تصدير جهات الاتصال',
|
||||
totalContacts: 'إجمالي جهات الاتصال',
|
||||
searchPlaceholder: 'البحث بالاسم أو البريد الإلكتروني أو الهاتف...',
|
||||
noContactsFound: 'لم يتم العثور على جهات اتصال',
|
||||
contactDetails: 'تفاصيل جهة الاتصال',
|
||||
contactInfo: 'معلومات الاتصال',
|
||||
companyInfo: 'معلومات الشركة',
|
||||
address: 'العنوان',
|
||||
categories: 'الفئات والعلامات',
|
||||
relationships: 'العلاقات',
|
||||
hierarchy: 'الهيكل التنظيمي',
|
||||
activities: 'الأنشطة',
|
||||
history: 'السجل',
|
||||
type: 'النوع',
|
||||
name: 'الاسم',
|
||||
nameAr: 'الاسم (بالعربية)',
|
||||
email: 'البريد الإلكتروني',
|
||||
phone: 'الهاتف',
|
||||
mobile: 'الجوال',
|
||||
website: 'الموقع الإلكتروني',
|
||||
companyName: 'اسم الشركة',
|
||||
companyNameAr: 'اسم الشركة (بالعربية)',
|
||||
taxNumber: 'الرقم الضريبي',
|
||||
commercialRegister: 'السجل التجاري',
|
||||
city: 'المدينة',
|
||||
country: 'الدولة',
|
||||
postalCode: 'الرمز البريدي',
|
||||
source: 'المصدر',
|
||||
rating: 'التقييم',
|
||||
tags: 'العلامات',
|
||||
individual: 'فرد',
|
||||
company: 'شركة',
|
||||
holding: 'مجموعة',
|
||||
government: 'حكومي',
|
||||
addRelationship: 'إضافة علاقة',
|
||||
relationshipType: 'نوع العلاقة',
|
||||
startDate: 'تاريخ البداية',
|
||||
endDate: 'تاريخ النهاية',
|
||||
notes: 'ملاحظات',
|
||||
representative: 'ممثل',
|
||||
partner: 'شريك',
|
||||
supplier: 'مورد',
|
||||
employee: 'موظف',
|
||||
subsidiary: 'فرع تابع',
|
||||
branch: 'فرع',
|
||||
parentCompany: 'الشركة الأم',
|
||||
customer: 'عميل',
|
||||
vendor: 'بائع',
|
||||
companyEmployee: 'موظف الشركة',
|
||||
other: 'أخرى',
|
||||
duplicateFound: 'تم العثور على جهات اتصال مشابهة',
|
||||
duplicateWarning: 'تم العثور على جهات اتصال مشابهة. يرجى المراجعة قبل المتابعة.',
|
||||
mergeInstead: 'دمج بدلاً من ذلك',
|
||||
continueAnyway: 'متابعة على أي حال',
|
||||
sourceContact: 'جهة الاتصال المصدر',
|
||||
targetContact: 'جهة الاتصال الهدف',
|
||||
compareFields: 'مقارنة الحقول',
|
||||
preview: 'معاينة',
|
||||
mergeWarning: 'لا يمكن التراجع عن هذا الإجراء!',
|
||||
mergeReason: 'سبب الدمج',
|
||||
mergeSuccess: 'تم دمج جهات الاتصال بنجاح!',
|
||||
importSuccess: 'تم استيراد جهات الاتصال بنجاح',
|
||||
exportSuccess: 'تم تصدير جهات الاتصال بنجاح',
|
||||
deleteConfirm: 'هل أنت متأكد من حذف جهة الاتصال هذه؟',
|
||||
deleteSuccess: 'تم حذف جهة الاتصال بنجاح',
|
||||
createSuccess: 'تم إنشاء جهة الاتصال بنجاح',
|
||||
updateSuccess: 'تم تحديث جهة الاتصال بنجاح'
|
||||
},
|
||||
crm: {
|
||||
title: 'إدارة العملاء',
|
||||
subtitle: 'إدارة العلاقات والمبيعات',
|
||||
addDeal: 'إضافة صفقة',
|
||||
editDeal: 'تعديل الصفقة',
|
||||
dealName: 'اسم الصفقة',
|
||||
contact: 'جهة الاتصال',
|
||||
structure: 'هيكل الصفقة',
|
||||
pipeline: 'مسار المبيعات',
|
||||
stage: 'المرحلة',
|
||||
probability: 'احتمالية الفوز',
|
||||
estimatedValue: 'القيمة المقدرة (ر.س)',
|
||||
expectedCloseDate: 'تاريخ الإغلاق المتوقع',
|
||||
searchPlaceholder: 'البحث في الصفقات...',
|
||||
filterStructure: 'الهيكل',
|
||||
filterStage: 'المرحلة',
|
||||
filterStatus: 'الحالة',
|
||||
all: 'الكل',
|
||||
view: 'عرض',
|
||||
win: 'فوز',
|
||||
lose: 'خسارة',
|
||||
archive: 'أرشفة',
|
||||
deleteDeal: 'حذف الصفقة',
|
||||
markWon: 'تحديد كفائز',
|
||||
markLost: 'تحديد كخاسر',
|
||||
actualValue: 'القيمة الفعلية (ر.س)',
|
||||
wonReason: 'سبب الفوز',
|
||||
lostReason: 'سبب الخسارة',
|
||||
noDealsFound: 'لم يتم العثور على صفقات',
|
||||
createSuccess: 'تم إنشاء الصفقة بنجاح',
|
||||
updateSuccess: 'تم تحديث الصفقة بنجاح',
|
||||
winSuccess: 'تم الفوز بالصفقة بنجاح',
|
||||
loseSuccess: 'تم تحديد الصفقة كخاسرة',
|
||||
deleteSuccess: 'تم أرشفة الصفقة بنجاح',
|
||||
fixFormErrors: 'يرجى إصلاح أخطاء النموذج',
|
||||
pipelineRequired: 'مسار المبيعات مطلوب',
|
||||
dealNameMin: 'اسم الصفقة يجب أن يكون 3 أحرف على الأقل',
|
||||
contactRequired: 'جهة الاتصال مطلوبة',
|
||||
structureRequired: 'هيكل الصفقة مطلوب',
|
||||
stageRequired: 'المرحلة مطلوبة',
|
||||
valueRequired: 'القيمة المقدرة يجب أن تكون أكبر من 0',
|
||||
selectPipeline: 'اختر المسار',
|
||||
selectContact: 'اختر جهة الاتصال',
|
||||
enterDealName: 'أدخل اسم الصفقة',
|
||||
structureB2B: 'B2B - شركة لشركة',
|
||||
structureB2C: 'B2C - شركة لفرد',
|
||||
structureB2G: 'B2G - شركة لحكومة',
|
||||
structurePartnership: 'شراكة - Partnership',
|
||||
dealDetail: 'تفاصيل الصفقة',
|
||||
quotes: 'عروض الأسعار',
|
||||
history: 'السجل',
|
||||
dealInfo: 'معلومات الصفقة',
|
||||
quickActions: 'إجراءات سريعة',
|
||||
totalValue: 'إجمالي القيمة',
|
||||
expectedValue: 'القيمة المتوقعة',
|
||||
activeDeals: 'الصفقات النشطة',
|
||||
wonDeals: 'الصفقات الرابحة',
|
||||
inPipeline: 'في المسار',
|
||||
winRate: 'معدل الفوز',
|
||||
conversion: 'التحويل',
|
||||
retry: 'إعادة المحاولة',
|
||||
createFirstDeal: 'إنشاء أول صفقة',
|
||||
loadingDeals: 'جاري تحميل الصفقات...',
|
||||
creating: 'جاري الإنشاء...',
|
||||
updating: 'جاري التحديث...',
|
||||
updateDeal: 'تحديث الصفقة',
|
||||
createDeal: 'إنشاء الصفقة',
|
||||
newDeal: 'صفقة جديدة',
|
||||
allStructures: 'جميع الهياكل',
|
||||
allStages: 'جميع المراحل',
|
||||
allStatus: 'جميع الحالات',
|
||||
deal: 'الصفقة',
|
||||
value: 'القيمة',
|
||||
owner: 'المالك',
|
||||
markDealWon: 'تحديد الصفقة كرابحة',
|
||||
markDealLost: 'تحديد الصفقة كخاسرة',
|
||||
reasonForWinning: 'سبب الفوز',
|
||||
reasonForLosing: 'سبب الخسارة',
|
||||
winPlaceholder: 'لماذا ربحنا هذه الصفقة؟',
|
||||
losePlaceholder: 'لماذا خسرنا هذه الصفقة؟',
|
||||
createNewDeal: 'إنشاء صفقة جديدة',
|
||||
paginationPrevious: 'السابق',
|
||||
paginationNext: 'التالي',
|
||||
processing: 'جاري المعالجة...',
|
||||
deleting: 'جاري الحذف...',
|
||||
deleteDealConfirm: 'هل أنت متأكد من حذف',
|
||||
deleteDealDesc: 'سيتم تحديد الصفقة كخاسرة'
|
||||
},
|
||||
import: {
|
||||
title: 'استيراد جهات الاتصال',
|
||||
downloadTemplate: 'تحميل قالب Excel',
|
||||
dragDrop: 'اسحب وأفلت ملف Excel أو CSV هنا',
|
||||
orClick: 'أو انقر لتحديد ملف',
|
||||
fileRequirements: 'متطلبات الملف:',
|
||||
step: 'خطوة',
|
||||
uploading: 'جاري الرفع...',
|
||||
importing: 'جاري الاستيراد...',
|
||||
rowsPreview: 'صفوف للمعاينة',
|
||||
warning: 'تنبيه',
|
||||
duplicateHandling: 'سيتم تخطي جهات الاتصال المكررة وتسجيلها في تقرير الأخطاء.',
|
||||
results: 'النتائج',
|
||||
successful: 'ناجح',
|
||||
duplicates: 'مكرر',
|
||||
failed: 'فشل',
|
||||
errors: 'أخطاء',
|
||||
downloadErrorReport: 'تحميل تقرير الأخطاء',
|
||||
importComplete: 'اكتمل الاستيراد'
|
||||
},
|
||||
messages: {
|
||||
loginSuccess: 'تم تسجيل الدخول بنجاح',
|
||||
loginError: 'بيانات الدخول غير صحيحة',
|
||||
networkError: 'خطأ في الشبكة. يرجى التحقق من الاتصال.',
|
||||
permissionDenied: 'غير مصرح',
|
||||
sessionExpired: 'انتهت الجلسة. يرجى تسجيل الدخول مرة أخرى.'
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user