626 lines
23 KiB
TypeScript
626 lines
23 KiB
TypeScript
'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',
|
|
costSheets: 'Cost Sheets',
|
|
contracts: 'Contracts',
|
|
invoices: 'Invoices',
|
|
addCostSheet: 'Add Cost Sheet',
|
|
addContract: 'Add Contract',
|
|
addInvoice: 'Add Invoice',
|
|
approve: 'Approve',
|
|
reject: 'Reject',
|
|
markSigned: 'Mark Signed',
|
|
recordPayment: 'Record Payment',
|
|
costSheetApproved: 'Cost sheet approved',
|
|
costSheetRejected: 'Cost sheet rejected',
|
|
contractSigned: 'Contract signed',
|
|
paymentRecorded: 'Payment recorded',
|
|
costSheetCreated: 'Cost sheet created',
|
|
contractCreated: 'Contract created',
|
|
invoiceCreated: 'Invoice created',
|
|
costSheetItems: 'Cost items (description, source, cost, quantity)',
|
|
invoiceItems: 'Line items (description, quantity, unit price)',
|
|
description: 'Description',
|
|
source: 'Source',
|
|
addRow: 'Add row',
|
|
totalCost: 'Total Cost',
|
|
suggestedPrice: 'Suggested Price',
|
|
profitMargin: 'Profit Margin',
|
|
contractTitle: 'Contract Title',
|
|
contractType: 'Contract Type',
|
|
contractTypeSales: 'Sales',
|
|
contractTypeService: 'Service',
|
|
contractTypeMaintenance: 'Maintenance',
|
|
contractValue: 'Contract Value',
|
|
startDate: 'Start Date',
|
|
endDate: 'End Date',
|
|
paymentTerms: 'Payment Terms',
|
|
deliveryTerms: 'Delivery Terms',
|
|
terms: 'Terms & Conditions',
|
|
subtotal: 'Subtotal',
|
|
taxAmount: 'Tax Amount',
|
|
total: 'Total',
|
|
dueDate: 'Due Date',
|
|
paidAmount: 'Paid Amount',
|
|
paidDate: 'Paid Date'
|
|
},
|
|
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: 'سيتم تحديد الصفقة كخاسرة',
|
|
costSheets: 'كشوفات التكلفة',
|
|
contracts: 'العقود',
|
|
invoices: 'الفواتير',
|
|
addCostSheet: 'إضافة كشف تكلفة',
|
|
addContract: 'إضافة عقد',
|
|
addInvoice: 'إضافة فاتورة',
|
|
approve: 'موافقة',
|
|
reject: 'رفض',
|
|
markSigned: 'توقيع',
|
|
recordPayment: 'تسجيل الدفع',
|
|
costSheetApproved: 'تمت الموافقة على كشف التكلفة',
|
|
costSheetRejected: 'تم رفض كشف التكلفة',
|
|
contractSigned: 'تم توقيع العقد',
|
|
paymentRecorded: 'تم تسجيل الدفع',
|
|
costSheetCreated: 'تم إنشاء كشف التكلفة',
|
|
contractCreated: 'تم إنشاء العقد',
|
|
invoiceCreated: 'تم إنشاء الفاتورة',
|
|
costSheetItems: 'بنود التكلفة (الوصف، المصدر، التكلفة، الكمية)',
|
|
invoiceItems: 'بنود الفاتورة (الوصف، الكمية، سعر الوحدة)',
|
|
description: 'الوصف',
|
|
source: 'المصدر',
|
|
addRow: 'إضافة صف',
|
|
totalCost: 'إجمالي التكلفة',
|
|
suggestedPrice: 'السعر المقترح',
|
|
profitMargin: 'هامش الربح',
|
|
contractTitle: 'عنوان العقد',
|
|
contractType: 'نوع العقد',
|
|
contractTypeSales: 'مبيعات',
|
|
contractTypeService: 'خدمة',
|
|
contractTypeMaintenance: 'صيانة',
|
|
contractValue: 'قيمة العقد',
|
|
startDate: 'تاريخ البداية',
|
|
endDate: 'تاريخ النهاية',
|
|
paymentTerms: 'شروط الدفع',
|
|
deliveryTerms: 'شروط التسليم',
|
|
terms: 'الشروط والأحكام',
|
|
subtotal: 'المجموع الفرعي',
|
|
taxAmount: 'ضريبة',
|
|
total: 'الإجمالي',
|
|
dueDate: 'تاريخ الاستحقاق',
|
|
paidAmount: 'المبلغ المدفوع',
|
|
paidDate: 'تاريخ الدفع'
|
|
},
|
|
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: 'انتهت الجلسة. يرجى تسجيل الدخول مرة أخرى.'
|
|
}
|
|
}
|
|
}
|