This commit is contained in:
@ -37,12 +37,12 @@ const ReasonDialog = ({ isOpen, onClose, onConfirm, title, defaultReason = '' })
|
||||
const [otherReason, setOtherReason] = useState('');
|
||||
|
||||
const commonReasons = [
|
||||
'ط£ط¹ظ…ط§ظ„ طµظٹط§ظ†ط© ظپظٹ ط§ظ„ط¹ظ‚ط§ط±',
|
||||
'ط§ظ„ط¹ظ‚ط§ط± ط؛ظٹط± ظ…طھط§ط ظپظٹ ظ‡ط°ظ‡ ط§ظ„طھظˆط§ط±ظٹط®',
|
||||
'ظ…ط´ظƒظ„ط© ظپظٹ ظˆط«ط§ط¦ظ‚ ط§ظ„ظ…ط³طھط£ط¬ط±',
|
||||
'ط§ظ„ظ…ط§ظ„ظƒ ط؛ظٹط± ظ…طھط§ط ظ„ظ„طھط³ظ„ظٹظ…',
|
||||
'طھط£ط®ط± ظپظٹ ط¯ظپط¹ ط§ظ„ط¶ظ…ط§ظ†',
|
||||
'ط³ط¨ط¨ ط¢ط®ط±'
|
||||
'أعمال صيانة في العقار',
|
||||
'العقار غير متاح في هذه التواريخ',
|
||||
'مشكلة في وثائق المستأجر',
|
||||
'المالك غير متاح للتسليم',
|
||||
'تأخر في دفع الضمان',
|
||||
'سبب آخر'
|
||||
];
|
||||
|
||||
if (!isOpen) return null;
|
||||
@ -67,7 +67,7 @@ const ReasonDialog = ({ isOpen, onClose, onConfirm, title, defaultReason = '' })
|
||||
<AlertCircle className="w-8 h-8 text-red-600" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-gray-900">{title}</h3>
|
||||
<p className="text-sm text-gray-500 mt-1">ظٹط±ط¬ظ‰ طھطط¯ظٹط¯ ط³ط¨ط¨ ط§ظ„ط±ظپط¶</p>
|
||||
<p className="text-sm text-gray-500 mt-1">يرجى تحديد سبب الرفض</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
@ -75,7 +75,7 @@ const ReasonDialog = ({ isOpen, onClose, onConfirm, title, defaultReason = '' })
|
||||
<button
|
||||
key={r}
|
||||
onClick={() => {
|
||||
if (r === 'ط³ط¨ط¨ ط¢ط®ط±') {
|
||||
if (r === 'سبب آخر') {
|
||||
} else {
|
||||
onConfirm(r);
|
||||
}
|
||||
@ -87,7 +87,7 @@ const ReasonDialog = ({ isOpen, onClose, onConfirm, title, defaultReason = '' })
|
||||
))}
|
||||
|
||||
<textarea
|
||||
placeholder="ط§ظƒطھط¨ ط³ط¨ط¨ط§ظ‹ ط¢ط®ط±..."
|
||||
placeholder="اكتب سبباً آخر..."
|
||||
value={otherReason}
|
||||
onChange={(e) => setOtherReason(e.target.value)}
|
||||
className="w-full p-3 border rounded-xl resize-none focus:ring-2 focus:ring-red-500 focus:border-transparent"
|
||||
@ -100,13 +100,13 @@ const ReasonDialog = ({ isOpen, onClose, onConfirm, title, defaultReason = '' })
|
||||
className="flex-1 bg-red-600 text-white py-3 rounded-xl font-medium hover:bg-red-700 transition-colors"
|
||||
disabled={!otherReason.trim()}
|
||||
>
|
||||
طھط£ظƒظٹط¯ ط§ظ„ط±ظپط¶
|
||||
تأكيد الرفض
|
||||
</button>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="flex-1 bg-gray-100 text-gray-700 py-3 rounded-xl font-medium hover:bg-gray-200 transition-colors"
|
||||
>
|
||||
ط¥ظ„ط؛ط§ط،
|
||||
إلغاء
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -119,17 +119,17 @@ const PDFExportButton = ({ request, onExportComplete }) => {
|
||||
const [isExporting, setIsExporting] = useState(false);
|
||||
|
||||
const formatCurrency = (amount) => {
|
||||
return amount?.toLocaleString() + ' ظ„.ط³';
|
||||
return amount?.toLocaleString() + ' ل.س';
|
||||
};
|
||||
|
||||
const generatePDF = async () => {
|
||||
if (!request) {
|
||||
toast.error('ظ„ط§ طھظˆط¬ط¯ ط¨ظٹط§ظ†ط§طھ ظ„ظ„طھطµط¯ظٹط±');
|
||||
toast.error('لا توجد بيانات للتصدير');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsExporting(true);
|
||||
const loadingToast = toast.loading('ط¬ط§ط±ظٹ ط¥ظ†ط´ط§ط، ظ…ظ„ظپ PDF...', { id: 'pdf-export' });
|
||||
const loadingToast = toast.loading('جاري إنشاء ملف PDF...', { id: 'pdf-export' });
|
||||
|
||||
try {
|
||||
const printContent = document.createElement('div');
|
||||
@ -290,49 +290,49 @@ const PDFExportButton = ({ request, onExportComplete }) => {
|
||||
<path d="M16 12L20 14" stroke="white"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="pdf-title">طھظ‚ط±ظٹط± ط·ظ„ط¨ طط¬ط² #${request.id}</div>
|
||||
<div class="pdf-subtitle">طھط§ط±ظٹط® ط§ظ„طھظ‚ط±ظٹط±: ${new Date().toLocaleDateString('ar-SA')} | ${new Date().toLocaleTimeString('ar-SA')}</div>
|
||||
<div class="pdf-title">تقرير طلب حجز #${request.id}</div>
|
||||
<div class="pdf-subtitle">تاريخ التقرير: ${new Date().toLocaleDateString('ar-SA')} | ${new Date().toLocaleTimeString('ar-SA')}</div>
|
||||
</div>
|
||||
|
||||
<div class="pdf-section">
|
||||
<div class="pdf-section-title">
|
||||
<span></span> ظ…ط¹ظ„ظˆظ…ط§طھ ط§ظ„ظ…ط³طھط£ط¬ط±
|
||||
<span></span> معلومات المستأجر
|
||||
</div>
|
||||
<div class="pdf-grid">
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ط§ظ„ط§ط³ظ… ط§ظ„ظƒط§ظ…ظ„:</span>
|
||||
<span class="pdf-value">${request.user || 'ط؛ظٹط± ظ…طط¯ط¯'}</span>
|
||||
<span class="pdf-label">الاسم الكامل:</span>
|
||||
<span class="pdf-value">${request.user || 'غير محدد'}</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ظ†ظˆط¹ ط§ظ„ظ‡ظˆظٹط©:</span>
|
||||
<span class="pdf-value">${request.userType === 'syrian' ? 'ظ‡ظˆظٹط© ط³ظˆط±ظٹط©' : 'ط¬ظˆط§ط² ط³ظپط±'}</span>
|
||||
<span class="pdf-label">نوع الهوية:</span>
|
||||
<span class="pdf-value">${request.userType === 'syrian' ? 'هوية سورية' : 'جواز سفر'}</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ط±ظ‚ظ… ط§ظ„ظ‡ظˆظٹط©:</span>
|
||||
<span class="pdf-value">${request.identityNumber || 'ط؛ظٹط± ظ…طط¯ط¯'}</span>
|
||||
<span class="pdf-label">رقم الهوية:</span>
|
||||
<span class="pdf-value">${request.identityNumber || 'غير محدد'}</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ط§ظ„ط¨ط±ظٹط¯ ط§ظ„ط¥ظ„ظƒطھط±ظˆظ†ظٹ:</span>
|
||||
<span class="pdf-value">${request.userEmail || 'ط؛ظٹط± ظ…طط¯ط¯'}</span>
|
||||
<span class="pdf-label">البريد الإلكتروني:</span>
|
||||
<span class="pdf-value">${request.userEmail || 'غير محدد'}</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ط±ظ‚ظ… ط§ظ„ظ‡ط§طھظپ:</span>
|
||||
<span class="pdf-value">${request.userPhone || 'ط؛ظٹط± ظ…طط¯ط¯'}</span>
|
||||
<span class="pdf-label">رقم الهاتف:</span>
|
||||
<span class="pdf-value">${request.userPhone || 'غير محدد'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pdf-section">
|
||||
<div class="pdf-section-title">
|
||||
<span></span> ظ…ط¹ظ„ظˆظ…ط§طھ ط§ظ„ط¹ظ‚ط§ط±
|
||||
<span></span> معلومات العقار
|
||||
</div>
|
||||
<div class="pdf-grid">
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ط§ظ„ط¹ظ‚ط§ط±:</span>
|
||||
<span class="pdf-value">${request.property || 'ط؛ظٹط± ظ…طط¯ط¯'}</span>
|
||||
<span class="pdf-label">العقار:</span>
|
||||
<span class="pdf-value">${request.property || 'غير محدد'}</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ط§ظ„ط³ط¹ط± ط§ظ„ظٹظˆظ…ظٹ:</span>
|
||||
<span class="pdf-label">السعر اليومي:</span>
|
||||
<span class="pdf-value">${formatCurrency(request.dailyPrice)}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -340,30 +340,30 @@ const PDFExportButton = ({ request, onExportComplete }) => {
|
||||
|
||||
<div class="pdf-section">
|
||||
<div class="pdf-section-title">
|
||||
<span></span> طھظپط§طµظٹظ„ ط§ظ„طط¬ط²
|
||||
<span></span> تفاصيل الحجز
|
||||
</div>
|
||||
<div class="pdf-grid">
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">طھط§ط±ظٹط® ط§ظ„ط¨ط¯ط§ظٹط©:</span>
|
||||
<span class="pdf-value">${request.startDate || 'ط؛ظٹط± ظ…طط¯ط¯'}</span>
|
||||
<span class="pdf-label">تاريخ البداية:</span>
|
||||
<span class="pdf-value">${request.startDate || 'غير محدد'}</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">طھط§ط±ظٹط® ط§ظ„ظ†ظ‡ط§ظٹط©:</span>
|
||||
<span class="pdf-value">${request.endDate || 'ط؛ظٹط± ظ…طط¯ط¯'}</span>
|
||||
<span class="pdf-label">تاريخ النهاية:</span>
|
||||
<span class="pdf-value">${request.endDate || 'غير محدد'}</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ط¹ط¯ط¯ ط§ظ„ط£ظٹط§ظ…:</span>
|
||||
<span class="pdf-value">${request.days || 0} ظٹظˆظ…</span>
|
||||
<span class="pdf-label">عدد الأيام:</span>
|
||||
<span class="pdf-value">${request.days || 0} يوم</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ط§ظ„طط§ظ„ط©:</span>
|
||||
<span class="pdf-label">الحالة:</span>
|
||||
<span class="pdf-value">
|
||||
<span class="pdf-status pdf-status-${request.status}">
|
||||
${request.status === 'pending' ? 'ظ‚ظٹط¯ ط§ظ„ط§ظ†طھط¸ط§ط±' :
|
||||
request.status === 'owner_approved' ? 'ظ…ظˆط§ظپظ‚ط© ط§ظ„ظ…ط§ظ„ظƒ' :
|
||||
request.status === 'admin_approved' ? 'ظ…ظˆط§ظپظ‚ط© ط§ظ„ط¥ط¯ط§ط±ط©' :
|
||||
request.status === 'active' ? 'ط¥ظٹط¬ط§ط± ظ†ط´ط·' :
|
||||
request.status === 'completed' ? 'ظ…ظ†طھظ‡ظٹ' : 'ظ…ط±ظپظˆط¶'}
|
||||
${request.status === 'pending' ? 'قيد الانتظار' :
|
||||
request.status === 'owner_approved' ? 'موافقة المالك' :
|
||||
request.status === 'admin_approved' ? 'موافقة الإدارة' :
|
||||
request.status === 'active' ? 'إيجار نشط' :
|
||||
request.status === 'completed' ? 'منتهي' : 'مرفوض'}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
@ -372,27 +372,27 @@ const PDFExportButton = ({ request, onExportComplete }) => {
|
||||
|
||||
<div class="pdf-section">
|
||||
<div class="pdf-section-title">
|
||||
<span></span> ط§ظ„ظ…ط¹ظ„ظˆظ…ط§طھ ط§ظ„ظ…ط§ظ„ظٹط©
|
||||
<span></span> المعلومات المالية
|
||||
</div>
|
||||
<div class="pdf-grid">
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ط³ظ„ظپط© ط§ظ„ط¶ظ…ط§ظ†:</span>
|
||||
<span class="pdf-label">سلفة الضمان:</span>
|
||||
<span class="pdf-value">${formatCurrency(request.securityDeposit)}</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ط§ظ„ظ…ط¨ظ„ط؛ ط§ظ„ط¥ط¬ظ…ط§ظ„ظٹ:</span>
|
||||
<span class="pdf-label">المبلغ الإجمالي:</span>
|
||||
<span class="pdf-value pdf-amount">${formatCurrency(request.totalAmount)}</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ظ†ط³ط¨ط© ط§ظ„ط¹ظ…ظˆظ„ط©:</span>
|
||||
<span class="pdf-label">نسبة العمولة:</span>
|
||||
<span class="pdf-value">${request.commissionRate || 0}%</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ظ†ظˆط¹ ط§ظ„ط¹ظ…ظˆظ„ط©:</span>
|
||||
<span class="pdf-value">${request.commissionType || 'ط؛ظٹط± ظ…طط¯ط¯'}</span>
|
||||
<span class="pdf-label">نوع العمولة:</span>
|
||||
<span class="pdf-value">${request.commissionType || 'غير محدد'}</span>
|
||||
</div>
|
||||
<div class="pdf-info-item">
|
||||
<span class="pdf-label">ظ‚ظٹظ…ط© ط§ظ„ط¹ظ…ظˆظ„ط©:</span>
|
||||
<span class="pdf-label">قيمة العمولة:</span>
|
||||
<span class="pdf-value">${formatCurrency(request.commissionAmount)}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -401,7 +401,7 @@ const PDFExportButton = ({ request, onExportComplete }) => {
|
||||
${request.notes ? `
|
||||
<div class="pdf-section">
|
||||
<div class="pdf-section-title">
|
||||
<span></span> ظ…ظ„ط§طط¸ط§طھ
|
||||
<span></span> ملاحظات
|
||||
</div>
|
||||
<div class="pdf-info-item" style="display: block;">
|
||||
<span class="pdf-value">${request.notes}</span>
|
||||
@ -411,44 +411,44 @@ const PDFExportButton = ({ request, onExportComplete }) => {
|
||||
|
||||
<div class="pdf-section">
|
||||
<div class="pdf-section-title">
|
||||
<span></span> ط³ط¬ظ„ ط§ظ„ط¥ط¬ط±ط§ط،ط§طھ
|
||||
<span></span> سجل الإجراءات
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 8px;">
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<span class="pdf-badge"> ${request.requestDate}</span>
|
||||
<span class="pdf-value">طھظ… ط¥ظ†ط´ط§ط، ط§ظ„ط·ظ„ط¨</span>
|
||||
<span class="pdf-value">تم إنشاء الطلب</span>
|
||||
</div>
|
||||
${request.ownerApproved ? `
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<span class="pdf-badge">✓</span>
|
||||
<span class="pdf-value">طھظ…طھ ظ…ظˆط§ظپظ‚ط© ط§ظ„ظ…ط§ظ„ظƒ</span>
|
||||
<span class="pdf-value">تمت موافقة المالك</span>
|
||||
</div>
|
||||
` : ''}
|
||||
${request.adminApproved ? `
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<span class="pdf-badge">✓</span>
|
||||
<span class="pdf-value">طھظ…طھ ظ…ظˆط§ظپظ‚ط© ط§ظ„ط¥ط¯ط§ط±ط©</span>
|
||||
<span class="pdf-value">تمت موافقة الإدارة</span>
|
||||
</div>
|
||||
` : ''}
|
||||
${request.ownerDelivered ? `
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<span class="pdf-badge"></span>
|
||||
<span class="pdf-value">طھظ… طھط³ظ„ظٹظ… ط§ظ„ظ…ظپطھط§ط</span>
|
||||
<span class="pdf-value">تم تسليم المفتاح</span>
|
||||
</div>
|
||||
` : ''}
|
||||
${request.tenantReceived ? `
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<span class="pdf-badge"></span>
|
||||
<span class="pdf-value">طھظ… ط§ط³طھظ„ط§ظ… ط§ظ„ط¹ظ‚ط§ط±</span>
|
||||
<span class="pdf-value">تم استلام العقار</span>
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pdf-footer">
|
||||
<div>طھظ‚ط±ظٹط± طµط§ط¯ط± ط¹ظ† ظ†ط¸ط§ظ… SweetHome ظ„ط¥ط¯ط§ط±ط© ط§ظ„ط¹ظ‚ط§ط±ط§طھ</div>
|
||||
<div style="margin-top: 5px;">ط¬ظ…ظٹط¹ ط§ظ„طظ‚ظˆظ‚ ظ…طظپظˆط¸ط© آ© ${new Date().getFullYear()} SweetHome</div>
|
||||
<div style="margin-top: 5px; font-size: 9px;">ظ‡ط°ط§ ط§ظ„طھظ‚ط±ظٹط± طھظ… ط¥ظ†ط´ط§ط¤ظ‡ طھظ„ظ‚ط§ط¦ظٹط§ظ‹ ظˆظ„ط§ ظٹططھط§ط¬ ط¥ظ„ظ‰ طھظˆظ‚ظٹط¹</div>
|
||||
<div>تقرير صادر عن نظام SweetHome لإدارة العقارات</div>
|
||||
<div style="margin-top: 5px;">جميع الحقوق محفوظة © ${new Date().getFullYear()} SweetHome</div>
|
||||
<div style="margin-top: 5px; font-size: 9px;">هذا التقرير تم إنشاؤه تلقائياً ولا يحتاج إلى توقيع</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@ -496,12 +496,12 @@ const PDFExportButton = ({ request, onExportComplete }) => {
|
||||
pageCount++;
|
||||
}
|
||||
|
||||
const fileName = `طھظ‚ط±ظٹط±_ط·ظ„ط¨_${request.id}_${new Date().toISOString().split('T')[0]}.pdf`;
|
||||
const fileName = `تقرير_طلب_${request.id}_${new Date().toISOString().split('T')[0]}.pdf`;
|
||||
pdf.save(fileName);
|
||||
|
||||
document.body.removeChild(printContent);
|
||||
|
||||
toast.success(`طھظ… طھطµط¯ظٹط± ط§ظ„طھظ‚ط±ظٹط± ط¨ظ†ط¬ط§ط! (${pageCount} طµظپطط©)`, { id: 'pdf-export' });
|
||||
toast.success(`تم تصدير التقرير بنجاح! (${pageCount} صفحة)`, { id: 'pdf-export' });
|
||||
|
||||
if (onExportComplete) {
|
||||
onExportComplete();
|
||||
@ -509,7 +509,7 @@ const PDFExportButton = ({ request, onExportComplete }) => {
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error generating PDF:', error);
|
||||
toast.error('طط¯ط« ط®ط·ط£ ط£ط«ظ†ط§ط، ط¥ظ†ط´ط§ط، ظ…ظ„ظپ PDF', { id: 'pdf-export' });
|
||||
toast.error('حدث خطأ أثناء إنشاء ملف PDF', { id: 'pdf-export' });
|
||||
} finally {
|
||||
setIsExporting(false);
|
||||
}
|
||||
@ -524,12 +524,12 @@ const PDFExportButton = ({ request, onExportComplete }) => {
|
||||
{isExporting ? (
|
||||
<>
|
||||
<Loader2 className="w-5 h-5 animate-spin" />
|
||||
ط¬ط§ط±ظٹ ط§ظ„طھطµط¯ظٹط±...
|
||||
جاري التصدير...
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Download className="w-5 h-5" />
|
||||
طھطµط¯ظٹط± PDF
|
||||
تصدير PDF
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
@ -540,7 +540,7 @@ const RequestDetailsDialog = ({ request, isOpen, onClose }) => {
|
||||
if (!isOpen || !request) return null;
|
||||
|
||||
const formatCurrency = (amount) => {
|
||||
return amount?.toLocaleString() + ' ظ„.ط³';
|
||||
return amount?.toLocaleString() + ' ل.س';
|
||||
};
|
||||
|
||||
return (
|
||||
@ -562,9 +562,9 @@ const RequestDetailsDialog = ({ request, isOpen, onClose }) => {
|
||||
<div>
|
||||
<h2 className="text-xl font-bold flex items-center gap-2">
|
||||
<FileText className="w-5 h-5" />
|
||||
طھظپط§طµظٹظ„ ط§ظ„ط·ظ„ط¨ #{request.id}
|
||||
تفاصيل الطلب #{request.id}
|
||||
</h2>
|
||||
<p className="text-amber-100 text-sm mt-1">ط¬ظ…ظٹط¹ ظ…ط¹ظ„ظˆظ…ط§طھ ط§ظ„ط·ظ„ط¨ ظپظٹ ظ…ظƒط§ظ† ظˆط§طط¯</p>
|
||||
<p className="text-amber-100 text-sm mt-1">جميع معلومات الطلب في مكان واحد</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={onClose}
|
||||
@ -578,29 +578,29 @@ const RequestDetailsDialog = ({ request, isOpen, onClose }) => {
|
||||
<div className="bg-gradient-to-br from-blue-50 to-indigo-50 p-4 rounded-xl">
|
||||
<h3 className="font-bold mb-3 flex items-center gap-2 text-blue-800">
|
||||
<User className="w-4 h-4" />
|
||||
ظ…ط¹ظ„ظˆظ…ط§طھ ط§ظ„ظ…ط³طھط£ط¬ط±
|
||||
معلومات المستأجر
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ط§ظ„ط§ط³ظ… ط§ظ„ظƒط§ظ…ظ„</label>
|
||||
<label className="text-xs text-gray-500">الاسم الكامل</label>
|
||||
<div className="font-medium">{request.user}</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ظ†ظˆط¹ ط§ظ„ظ‡ظˆظٹط©</label>
|
||||
<label className="text-xs text-gray-500">نوع الهوية</label>
|
||||
<div className="font-medium">
|
||||
{request.userType === 'syrian' ? 'ًں‡¸ًں‡¾ ظ‡ظˆظٹط© ط³ظˆط±ظٹط©' : 'ط¬ظˆط§ط² ط³ظپط±'}
|
||||
{request.userType === 'syrian' ? '🇸🇾 هوية سورية' : 'جواز سفر'}
|
||||
<span className="text-xs text-gray-500 mr-2">{request.identityNumber}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ط§ظ„ط¨ط±ظٹط¯ ط§ظ„ط¥ظ„ظƒطھط±ظˆظ†ظٹ</label>
|
||||
<label className="text-xs text-gray-500">البريد الإلكتروني</label>
|
||||
<div className="font-medium flex items-center gap-1">
|
||||
<Mail className="w-3 h-3 text-gray-400" />
|
||||
{request.userEmail}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ط±ظ‚ظ… ط§ظ„ظ‡ط§طھظپ</label>
|
||||
<label className="text-xs text-gray-500">رقم الهاتف</label>
|
||||
<div className="font-medium flex items-center gap-1">
|
||||
<Phone className="w-3 h-3 text-gray-400" />
|
||||
{request.userPhone}
|
||||
@ -612,15 +612,15 @@ const RequestDetailsDialog = ({ request, isOpen, onClose }) => {
|
||||
<div className="bg-gradient-to-br from-green-50 to-emerald-50 p-4 rounded-xl">
|
||||
<h3 className="font-bold mb-3 flex items-center gap-2 text-green-800">
|
||||
<Home className="w-4 h-4" />
|
||||
ظ…ط¹ظ„ظˆظ…ط§طھ ط§ظ„ط¹ظ‚ط§ط±
|
||||
معلومات العقار
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ط§ظ„ط¹ظ‚ط§ط±</label>
|
||||
<label className="text-xs text-gray-500">العقار</label>
|
||||
<div className="font-medium">{request.property}</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ط§ظ„ط³ط¹ط± ط§ظ„ظٹظˆظ…ظٹ</label>
|
||||
<label className="text-xs text-gray-500">السعر اليومي</label>
|
||||
<div className="font-medium text-green-600">{formatCurrency(request.dailyPrice)}</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -629,23 +629,23 @@ const RequestDetailsDialog = ({ request, isOpen, onClose }) => {
|
||||
<div className="bg-gradient-to-br from-amber-50 to-orange-50 p-4 rounded-xl">
|
||||
<h3 className="font-bold mb-3 flex items-center gap-2 text-amber-800">
|
||||
<Calendar className="w-4 h-4" />
|
||||
طھظپط§طµظٹظ„ ط§ظ„طط¬ط²
|
||||
تفاصيل الحجز
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">طھط§ط±ظٹط® ط§ظ„ط¨ط¯ط§ظٹط©</label>
|
||||
<label className="text-xs text-gray-500">تاريخ البداية</label>
|
||||
<div className="font-medium">{request.startDate}</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">طھط§ط±ظٹط® ط§ظ„ظ†ظ‡ط§ظٹط©</label>
|
||||
<label className="text-xs text-gray-500">تاريخ النهاية</label>
|
||||
<div className="font-medium">{request.endDate}</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ط¹ط¯ط¯ ط§ظ„ط£ظٹط§ظ…</label>
|
||||
<div className="font-medium">{request.days} ظٹظˆظ…</div>
|
||||
<label className="text-xs text-gray-500">عدد الأيام</label>
|
||||
<div className="font-medium">{request.days} يوم</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ط§ظ„ظ…ط¨ظ„ط؛ ط§ظ„ط¥ط¬ظ…ط§ظ„ظٹ</label>
|
||||
<label className="text-xs text-gray-500">المبلغ الإجمالي</label>
|
||||
<div className="font-medium text-green-600">{formatCurrency(request.totalAmount)}</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -654,33 +654,33 @@ const RequestDetailsDialog = ({ request, isOpen, onClose }) => {
|
||||
<div className="bg-gradient-to-br from-purple-50 to-pink-50 p-4 rounded-xl">
|
||||
<h3 className="font-bold mb-3 flex items-center gap-2 text-purple-800">
|
||||
<DollarSign className="w-4 h-4" />
|
||||
ط§ظ„ظ…ط¹ظ„ظˆظ…ط§طھ ط§ظ„ظ…ط§ظ„ظٹط©
|
||||
المعلومات المالية
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ط³ظ„ظپط© ط§ظ„ط¶ظ…ط§ظ†</label>
|
||||
<label className="text-xs text-gray-500">سلفة الضمان</label>
|
||||
<div className="font-medium text-blue-600">{formatCurrency(request.securityDeposit)}</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">طط§ظ„ط© ط§ظ„ط±ط¹ط¨ظˆظ†</label>
|
||||
<label className="text-xs text-gray-500">حالة العربون</label>
|
||||
<div className={`font-medium px-3 py-1 rounded-full text-sm inline-block ${
|
||||
request.securityDepositPaid
|
||||
? 'bg-green-100 text-green-800'
|
||||
: 'bg-yellow-100 text-yellow-800'
|
||||
}`}>
|
||||
{request.securityDepositPaid ? '✓ طھظ… ط§ظ„ط¯ظپط¹' : 'âڈ³ ظپظٹ ط§ظ†طھط¸ط§ط± ط§ظ„ط¯ظپط¹'}
|
||||
{request.securityDepositPaid ? '✓ تم الدفع' : '⏳ في انتظار الدفع'}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ظ†ط³ط¨ط© ط§ظ„ط¹ظ…ظˆظ„ط©</label>
|
||||
<label className="text-xs text-gray-500">نسبة العمولة</label>
|
||||
<div className="font-medium">{request.commissionRate}%</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ظ†ظˆط¹ ط§ظ„ط¹ظ…ظˆظ„ط©</label>
|
||||
<label className="text-xs text-gray-500">نوع العمولة</label>
|
||||
<div className="font-medium text-amber-600">{request.commissionType}</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ظ‚ظٹظ…ط© ط§ظ„ط¹ظ…ظˆظ„ط©</label>
|
||||
<label className="text-xs text-gray-500">قيمة العمولة</label>
|
||||
<div className="font-medium text-amber-600">{formatCurrency(request.commissionAmount)}</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -689,29 +689,29 @@ const RequestDetailsDialog = ({ request, isOpen, onClose }) => {
|
||||
<div className="bg-gray-50 p-4 rounded-xl">
|
||||
<h3 className="font-bold mb-3 flex items-center gap-2">
|
||||
<History className="w-4 h-4" />
|
||||
ط³ط¬ظ„ ط§ظ„ط¥ط¬ط±ط§ط،ط§طھ
|
||||
سجل الإجراءات
|
||||
</h3>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
|
||||
<span className="text-gray-600">طھظ… ط¥ظ†ط´ط§ط، ط§ظ„ط·ظ„ط¨: {request.requestDate}</span>
|
||||
<span className="text-gray-600">تم إنشاء الطلب: {request.requestDate}</span>
|
||||
</div>
|
||||
{request.ownerApproved && (
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<div className="w-2 h-2 bg-blue-500 rounded-full"></div>
|
||||
<span className="text-gray-600">ظ…ظˆط§ظپظ‚ط© ط§ظ„ظ…ط§ظ„ظƒ</span>
|
||||
<span className="text-gray-600">موافقة المالك</span>
|
||||
</div>
|
||||
)}
|
||||
{request.adminApproved && (
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
|
||||
<span className="text-gray-600">ظ…ظˆط§ظپظ‚ط© ط§ظ„ط¥ط¯ط§ط±ط©</span>
|
||||
<span className="text-gray-600">موافقة الإدارة</span>
|
||||
</div>
|
||||
)}
|
||||
{request.ownerDelivered && (
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<div className="w-2 h-2 bg-purple-500 rounded-full"></div>
|
||||
<span className="text-gray-600">طھظ… طھط³ظ„ظٹظ… ط§ظ„ظ…ظپطھط§ط ظ…ظ† ط§ظ„ظ…ط§ظ„ظƒ</span>
|
||||
<span className="text-gray-600">تم تسليم المفتاح من المالك</span>
|
||||
</div>
|
||||
)}
|
||||
{request.notes && (
|
||||
@ -729,7 +729,7 @@ const RequestDetailsDialog = ({ request, isOpen, onClose }) => {
|
||||
className="flex-1 bg-blue-600 text-white py-3 rounded-xl font-medium hover:bg-blue-700 transition-colors flex items-center justify-center gap-2"
|
||||
>
|
||||
<Printer className="w-5 h-5" />
|
||||
ط·ط¨ط§ط¹ط© ط§ظ„طھظپط§طµظٹظ„
|
||||
طباعة التفاصيل
|
||||
</button>
|
||||
|
||||
<PDFExportButton request={request} />
|
||||
@ -740,11 +740,13 @@ const RequestDetailsDialog = ({ request, isOpen, onClose }) => {
|
||||
};
|
||||
|
||||
const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId }) => {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const [expanded, setExpanded] = useState(
|
||||
request.status === 'admin_approved' && !request.securityDepositPaid,
|
||||
);
|
||||
const isConfirmingDeposit = confirmingDepositId === request.id;
|
||||
|
||||
const formatCurrency = (amount) => {
|
||||
return amount?.toLocaleString() + ' ظ„.ط³';
|
||||
return amount?.toLocaleString() + ' ل.س';
|
||||
};
|
||||
|
||||
const getStatusColor = (status) => {
|
||||
@ -770,12 +772,12 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
};
|
||||
|
||||
const labels = {
|
||||
pending: 'ط¨ط§ظ†طھط¸ط§ط± ط§ظ„ظ…ظˆط§ظپظ‚ط©',
|
||||
owner_approved: 'ظ…ظˆط§ظپظ‚ط© ط§ظ„ظ…ط§ظ„ظƒ',
|
||||
admin_approved: 'ظ…ظˆط§ظپظ‚ط© ط§ظ„ط¥ط¯ط§ط±ط©',
|
||||
active: 'ط¥ظٹط¬ط§ط± ظ†ط´ط·',
|
||||
completed: 'ظ…ظ†طھظ‡ظٹ',
|
||||
rejected: 'ظ…ط±ظپظˆط¶'
|
||||
pending: 'بانتظار الموافقة',
|
||||
owner_approved: 'موافقة المالك',
|
||||
admin_approved: 'موافقة الإدارة',
|
||||
active: 'إيجار نشط',
|
||||
completed: 'منتهي',
|
||||
rejected: 'مرفوض'
|
||||
};
|
||||
|
||||
return (
|
||||
@ -794,7 +796,7 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
<div className="p-4 cursor-pointer" onClick={() => setExpanded(!expanded)}>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-lg font-bold text-gray-900">ط·ظ„ط¨ #{request.id}</span>
|
||||
<span className="text-lg font-bold text-gray-900">طلب #{request.id}</span>
|
||||
{getStatusBadge(request.status)}
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
@ -818,7 +820,7 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<Calendar className="w-4 h-4 text-gray-400" />
|
||||
<span>{request.days} ط£ظٹط§ظ…</span>
|
||||
<span>{request.days} أيام</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<DollarSign className="w-4 h-4 text-gray-400" />
|
||||
@ -837,22 +839,22 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 mb-4">
|
||||
<div className="bg-blue-50 p-2 rounded-lg">
|
||||
<div className="text-xs text-gray-500">ط³ظ„ظپط© ط¶ظ…ط§ظ†</div>
|
||||
<div className="text-xs text-gray-500">سلفة ضمان</div>
|
||||
<div className="font-bold text-blue-600">{formatCurrency(request.securityDeposit)}</div>
|
||||
</div>
|
||||
<div className={`p-2 rounded-lg ${request.securityDepositPaid ? 'bg-green-50' : 'bg-yellow-50'}`}>
|
||||
<div className="text-xs text-gray-500">طط§ظ„ط© ط§ظ„ط±ط¹ط¨ظˆظ†</div>
|
||||
<div className="text-xs text-gray-500">حالة العربون</div>
|
||||
<div className={`font-bold text-xs ${request.securityDepositPaid ? 'text-green-600' : 'text-yellow-600'}`}>
|
||||
{request.securityDepositPaid ? 'طھظ… ط§ظ„ط¯ظپط¹' : ' ط¨ط§ظ†طھط¸ط§ط±'}
|
||||
{request.securityDepositPaid ? 'تم الدفع' : ' بانتظار'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-amber-50 p-2 rounded-lg">
|
||||
<div className="text-xs text-gray-500">ط§ظ„ط¹ظ…ظˆظ„ط©</div>
|
||||
<div className="text-xs text-gray-500">العمولة</div>
|
||||
<div className="font-bold text-amber-600">{request.commissionRate}% ({request.commissionType})</div>
|
||||
</div>
|
||||
<div className="bg-purple-50 p-2 rounded-lg">
|
||||
<div className="text-xs text-gray-500">ظ…ط¯ط© ط§ظ„ط¥ظٹط¬ط§ط±</div>
|
||||
<div className="font-bold text-purple-600 text-xs">{request.startDate} ط¥ظ„ظ‰ {request.endDate}</div>
|
||||
<div className="text-xs text-gray-500">مدة الإيجار</div>
|
||||
<div className="font-bold text-purple-600 text-xs">{request.startDate} إلى {request.endDate}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -860,7 +862,7 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
<div className="bg-green-50 p-3 rounded-lg mb-4">
|
||||
<h4 className="font-bold text-sm mb-2 flex items-center gap-2 text-green-800">
|
||||
<Phone className="w-4 h-4" />
|
||||
ظ…ط¹ظ„ظˆظ…ط§طھ ط§ظ„ط§طھطµط§ظ„
|
||||
معلومات الاتصال
|
||||
</h4>
|
||||
<div className="grid grid-cols-2 gap-2 text-sm">
|
||||
<div className="flex items-center gap-1">
|
||||
@ -883,14 +885,14 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
className="flex-1 bg-green-600 text-white py-3 rounded-xl font-medium hover:bg-green-700 transition-all transform hover:scale-105 flex items-center justify-center gap-2"
|
||||
>
|
||||
<CheckCircle className="w-5 h-5" />
|
||||
ظ…ظˆط§ظپظ‚ط© ط§ظ„ظ…ط§ظ„ظƒ
|
||||
موافقة المالك
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onAction('owner_reject', request.id)}
|
||||
className="flex-1 bg-red-600 text-white py-3 rounded-xl font-medium hover:bg-red-700 transition-all transform hover:scale-105 flex items-center justify-center gap-2"
|
||||
>
|
||||
<XCircle className="w-5 h-5" />
|
||||
ط±ظپط¶
|
||||
رفض
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onAction('view_details', request)}
|
||||
@ -908,14 +910,14 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
className="flex-1 bg-blue-600 text-white py-3 rounded-xl font-medium hover:bg-blue-700 transition-all transform hover:scale-105 flex items-center justify-center gap-2"
|
||||
>
|
||||
<CheckCircle className="w-5 h-5" />
|
||||
ظ…ظˆط§ظپظ‚ط© ط§ظ„ط¥ط¯ط§ط±ط©
|
||||
موافقة الإدارة
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onAction('admin_reject', request.id)}
|
||||
className="flex-1 bg-red-600 text-white py-3 rounded-xl font-medium hover:bg-red-700 transition-all transform hover:scale-105 flex items-center justify-center gap-2"
|
||||
>
|
||||
<XCircle className="w-5 h-5" />
|
||||
ط±ظپط¶ ط¥ط¯ط§ط±ظٹ
|
||||
رفض إداري
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onAction('view_details', request)}
|
||||
@ -945,8 +947,8 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
) : (
|
||||
<CreditCard className="w-5 h-5" />
|
||||
)}
|
||||
<span className="hidden md:inline">{request.securityDepositPaid ? 'طھظ… ط¯ظپط¹ ط§ظ„ط±ط¹ط¨ظˆظ†' : 'طھط£ظƒظٹط¯ ط§ظ„ط±ط¹ط¨ظˆظ†'}</span>
|
||||
<span className="md:hidden">{request.securityDepositPaid ? '✓' : 'ط±ط¹ط¨ظˆظ†'}</span>
|
||||
<span className="hidden md:inline">{request.securityDepositPaid ? 'تم دفع العربون' : 'تأكيد العربون'}</span>
|
||||
<span className="md:hidden">{request.securityDepositPaid ? '✓' : 'عربون'}</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onAction('deliver_key', { id: request.id, type: 'owner' })}
|
||||
@ -958,8 +960,8 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
}`}
|
||||
>
|
||||
<Key className="w-5 h-5" />
|
||||
<span className="hidden md:inline">{request.ownerDelivered ? 'طھظ… طھط³ظ„ظٹظ… ط§ظ„ظ…ظپطھط§ط' : 'طھط³ظ„ظٹظ… ط§ظ„ظ…ظپطھط§ط'}</span>
|
||||
<span className="md:hidden">{request.ownerDelivered ? '✓' : 'ظ…ظپطھط§ط'}</span>
|
||||
<span className="hidden md:inline">{request.ownerDelivered ? 'تم تسليم المفتاح' : 'تسليم المفتاح'}</span>
|
||||
<span className="md:hidden">{request.ownerDelivered ? '✓' : 'مفتاح'}</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onAction('receive_property', { id: request.id, type: 'tenant' })}
|
||||
@ -971,8 +973,8 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
}`}
|
||||
>
|
||||
<DoorOpen className="w-5 h-5" />
|
||||
<span className="hidden md:inline">{request.tenantReceived ? 'طھظ… ط§ظ„ط§ط³طھظ„ط§ظ…' : 'ط§ط³طھظ„ط§ظ… ط§ظ„ط¹ظ‚ط§ط±'}</span>
|
||||
<span className="md:hidden">{request.tenantReceived ? '✓' : 'ط§ط³طھظ„ط§ظ…'}</span>
|
||||
<span className="hidden md:inline">{request.tenantReceived ? 'تم الاستلام' : 'استلام العقار'}</span>
|
||||
<span className="md:hidden">{request.tenantReceived ? '✓' : 'استلام'}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -991,7 +993,7 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
}`}
|
||||
>
|
||||
<DoorOpen className="w-5 h-5" />
|
||||
{request.tenantLeft ? 'طھظ… ط§ظ„ظ…ط؛ط§ط¯ط±ط©' : 'ظ…ط؛ط§ط¯ط±ط© ط§ظ„ط¹ظ‚ط§ط±'}
|
||||
{request.tenantLeft ? 'تم المغادرة' : 'مغادرة العقار'}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onAction('owner_receive', { id: request.id, type: 'owner' })}
|
||||
@ -1003,15 +1005,15 @@ const RequestCard = ({ request, onAction, onViewDetails, confirmingDepositId })
|
||||
}`}
|
||||
>
|
||||
<Key className="w-5 h-5" />
|
||||
{request.ownerReceived ? 'طھظ… ط§ظ„ط§ط³طھظ„ط§ظ…' : 'ط§ط³طھظ„ط§ظ… ط§ظ„ط¹ظ‚ط§ط±'}
|
||||
{request.ownerReceived ? 'تم الاستلام' : 'استلام العقار'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{request.actualStartDate && (
|
||||
<div className="bg-gray-100 p-3 rounded-lg">
|
||||
<div className="flex justify-between text-sm mb-1">
|
||||
<span>ط¨ط¯ط£ ط§ظ„ط¥ظٹط¬ط§ط±: {request.actualStartDate}</span>
|
||||
<span>ط§ظ„ظ…ط¯ط©: {request.days} ظٹظˆظ…</span>
|
||||
<span>بدأ الإيجار: {request.actualStartDate}</span>
|
||||
<span>المدة: {request.days} يوم</span>
|
||||
</div>
|
||||
<div className="w-full bg-gray-300 rounded-full h-2">
|
||||
<div
|
||||
@ -1035,12 +1037,12 @@ export default function BookingRequests() {
|
||||
const [requests, setRequests] = useState([
|
||||
{
|
||||
id: 'REQ001',
|
||||
user: 'ط£طظ…ط¯ ظ…طظ…ط¯',
|
||||
user: 'أحمد محمد',
|
||||
userEmail: 'ahmed@example.com',
|
||||
userPhone: '0938123456',
|
||||
userType: 'syrian',
|
||||
identityNumber: '123456789',
|
||||
property: 'ظپظٹظ„ط§ ظپط§ط®ط±ط© ظپظٹ ط¯ظ…ط´ظ‚',
|
||||
property: 'فيلا فاخرة في دمشق',
|
||||
propertyId: 1,
|
||||
startDate: '2024-03-01',
|
||||
endDate: '2024-03-10',
|
||||
@ -1048,7 +1050,7 @@ export default function BookingRequests() {
|
||||
totalAmount: 5000000,
|
||||
dailyPrice: 500000,
|
||||
commissionRate: 5,
|
||||
commissionType: 'ظ…ظ† ط§ظ„ظ…ط§ظ„ظƒ',
|
||||
commissionType: 'من المالك',
|
||||
commissionAmount: 250000,
|
||||
securityDeposit: 500000,
|
||||
status: 'pending',
|
||||
@ -1068,12 +1070,12 @@ export default function BookingRequests() {
|
||||
},
|
||||
{
|
||||
id: 'REQ002',
|
||||
user: 'ط³ط§ط±ط© ط£طظ…ط¯',
|
||||
user: 'سارة أحمد',
|
||||
userEmail: 'sara@example.com',
|
||||
userPhone: '0945123789',
|
||||
userType: 'passport',
|
||||
identityNumber: 'AB123456',
|
||||
property: 'ط´ظ‚ط© طط¯ظٹط«ط© ظپظٹ طظ„ط¨',
|
||||
property: 'شقة حديثة في حلب',
|
||||
propertyId: 2,
|
||||
startDate: '2024-03-05',
|
||||
endDate: '2024-03-15',
|
||||
@ -1081,13 +1083,13 @@ export default function BookingRequests() {
|
||||
totalAmount: 2500000,
|
||||
dailyPrice: 250000,
|
||||
commissionRate: 7,
|
||||
commissionType: 'ظ…ظ† ط§ظ„ظ…ط³طھط£ط¬ط±',
|
||||
commissionType: 'من المستأجر',
|
||||
commissionAmount: 175000,
|
||||
securityDeposit: 250000,
|
||||
status: 'owner_approved',
|
||||
status: 'admin_approved',
|
||||
requestDate: '2024-02-24',
|
||||
ownerApproved: true,
|
||||
adminApproved: false,
|
||||
adminApproved: true,
|
||||
ownerDelivered: false,
|
||||
tenantReceived: false,
|
||||
tenantLeft: false,
|
||||
@ -1101,12 +1103,12 @@ export default function BookingRequests() {
|
||||
},
|
||||
{
|
||||
id: 'REQ003',
|
||||
user: 'ظ…طظ…ط¯ ط§ظ„طظ„ط¨ظٹ',
|
||||
user: 'محمد الحلبي',
|
||||
userEmail: 'mohammed@example.com',
|
||||
userPhone: '0956123456',
|
||||
userType: 'syrian',
|
||||
identityNumber: '987654321',
|
||||
property: 'ط´ظ‚ط© ط¨ط¬ط§ظ†ط¨ ط§ظ„ط¨طط± ظپظٹ ط§ظ„ظ„ط§ط°ظ‚ظٹط©',
|
||||
property: 'شقة بجانب البحر في اللاذقية',
|
||||
propertyId: 3,
|
||||
startDate: '2024-02-20',
|
||||
endDate: '2024-03-20',
|
||||
@ -1114,7 +1116,7 @@ export default function BookingRequests() {
|
||||
totalAmount: 9000000,
|
||||
dailyPrice: 300000,
|
||||
commissionRate: 5,
|
||||
commissionType: 'ظ…ظ† ط§ظ„ط§ط«ظ†ظٹظ†',
|
||||
commissionType: 'من الاثنين',
|
||||
commissionAmount: 450000,
|
||||
securityDeposit: 500000,
|
||||
status: 'active',
|
||||
@ -1128,7 +1130,7 @@ export default function BookingRequests() {
|
||||
securityDepositPaid: true,
|
||||
securityDepositReturned: null,
|
||||
contractSigned: true,
|
||||
notes: 'ط¹ظ‚ط¯ ظ…ظˆظ‚ط¹ ط¥ظ„ظƒطھط±ظˆظ†ظٹط§ظ‹',
|
||||
notes: 'عقد موقع إلكترونياً',
|
||||
actualStartDate: '2024-02-20',
|
||||
actualEndDate: null
|
||||
}
|
||||
@ -1205,7 +1207,7 @@ export default function BookingRequests() {
|
||||
...req,
|
||||
ownerApproved: true,
|
||||
status: 'owner_approved',
|
||||
notes: 'طھظ…طھ ط§ظ„ظ…ظˆط§ظپظ‚ط© ظ…ظ† ظ‚ط¨ظ„ ط§ظ„ظ…ط§ظ„ظƒ'
|
||||
notes: 'تمت الموافقة من قبل المالك'
|
||||
}
|
||||
: req
|
||||
)
|
||||
@ -1220,7 +1222,7 @@ export default function BookingRequests() {
|
||||
...req,
|
||||
adminApproved: true,
|
||||
status: 'admin_approved',
|
||||
notes: 'طھظ…طھ ط§ظ„ظ…ظˆط§ظپظ‚ط© ظ…ظ† ظ‚ط¨ظ„ ط§ظ„ط¥ط¯ط§ط±ط©'
|
||||
notes: 'تمت الموافقة من قبل الإدارة'
|
||||
}
|
||||
: req
|
||||
)
|
||||
@ -1285,11 +1287,11 @@ export default function BookingRequests() {
|
||||
|
||||
if (userType === 'owner') {
|
||||
updates.ownerDelivered = true;
|
||||
updates.notes = 'طھظ… طھط³ظ„ظٹظ… ط§ظ„ظ…ظپطھط§ط ظ…ظ† ظ‚ط¨ظ„ ط§ظ„ظ…ط§ظ„ظƒ';
|
||||
updates.notes = 'تم تسليم المفتاح من قبل المالك';
|
||||
}
|
||||
if (userType === 'tenant') {
|
||||
updates.tenantReceived = true;
|
||||
updates.notes = 'طھظ… ط§ط³طھظ„ط§ظ… ط§ظ„ط¹ظ‚ط§ط± ظ…ظ† ظ‚ط¨ظ„ ط§ظ„ظ…ط³طھط£ط¬ط±';
|
||||
updates.notes = 'تم استلام العقار من قبل المستأجر';
|
||||
}
|
||||
|
||||
if ((userType === 'owner' && req.tenantReceived) ||
|
||||
@ -1297,7 +1299,7 @@ export default function BookingRequests() {
|
||||
updates.status = 'active';
|
||||
updates.contractSigned = true;
|
||||
updates.actualStartDate = new Date().toISOString().split('T')[0];
|
||||
updates.notes = 'ط¨ط¯ط£طھ ظپطھط±ط© ط§ظ„ط¥ظٹط¬ط§ط± ط§ظ„ظپط¹ظ„ظٹط©';
|
||||
updates.notes = 'بدأت فترة الإيجار الفعلية';
|
||||
}
|
||||
|
||||
return { ...req, ...updates };
|
||||
@ -1315,11 +1317,11 @@ export default function BookingRequests() {
|
||||
|
||||
if (userType === 'tenant') {
|
||||
updates.tenantLeft = true;
|
||||
updates.notes = 'ط؛ط§ط¯ط± ط§ظ„ظ…ط³طھط£ط¬ط± ط§ظ„ط¹ظ‚ط§ط±';
|
||||
updates.notes = 'غادر المستأجر العقار';
|
||||
}
|
||||
if (userType === 'owner') {
|
||||
updates.ownerReceived = true;
|
||||
updates.notes = 'ط§ط³طھظ„ظ… ط§ظ„ظ…ط§ظ„ظƒ ط§ظ„ط¹ظ‚ط§ط±';
|
||||
updates.notes = 'استلم المالك العقار';
|
||||
}
|
||||
|
||||
if ((userType === 'tenant' && req.ownerReceived) ||
|
||||
@ -1339,7 +1341,7 @@ export default function BookingRequests() {
|
||||
updates.actualAmount = actualAmount;
|
||||
updates.securityDepositReturned = refundAmount;
|
||||
updates.damageDeduction = damageDeduction;
|
||||
updates.notes = `ط§ظ†طھظ‡ظ‰ ط§ظ„ط¥ظٹط¬ط§ط± ط¨ط¹ط¯ ${actualDays} ظٹظˆظ… - ط§ظ„ظ…ط¨ظ„ط؛ ط§ظ„ظپط¹ظ„ظٹ: ${actualAmount.toLocaleString()} ظ„.ط³ - ظ…ط³طھط±ط¯ ط§ظ„ط¶ظ…ط§ظ†: ${refundAmount.toLocaleString()} ظ„.ط³`;
|
||||
updates.notes = `انتهى الإيجار بعد ${actualDays} يوم - المبلغ الفعلي: ${actualAmount.toLocaleString()} ل.س - مسترد الضمان: ${refundAmount.toLocaleString()} ل.س`;
|
||||
}
|
||||
|
||||
return { ...req, ...updates };
|
||||
@ -1371,7 +1373,7 @@ export default function BookingRequests() {
|
||||
className="bg-gradient-to-br from-blue-600 to-blue-700 text-white rounded-2xl p-4 shadow-lg"
|
||||
>
|
||||
<div className="text-3xl font-bold mb-1">{stats.total}</div>
|
||||
<div className="text-sm opacity-90">ط¥ط¬ظ…ط§ظ„ظٹ ط§ظ„ط·ظ„ط¨ط§طھ</div>
|
||||
<div className="text-sm opacity-90">إجمالي الطلبات</div>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
@ -1380,7 +1382,7 @@ export default function BookingRequests() {
|
||||
className="bg-gradient-to-br from-yellow-600 to-yellow-700 text-white rounded-2xl p-4 shadow-lg"
|
||||
>
|
||||
<div className="text-3xl font-bold mb-1">{stats.pending}</div>
|
||||
<div className="text-sm opacity-90">ظ‚ظٹط¯ ط§ظ„ط§ظ†طھط¸ط§ط±</div>
|
||||
<div className="text-sm opacity-90">قيد الانتظار</div>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
@ -1389,7 +1391,7 @@ export default function BookingRequests() {
|
||||
className="bg-gradient-to-br from-purple-600 to-purple-700 text-white rounded-2xl p-4 shadow-lg"
|
||||
>
|
||||
<div className="text-3xl font-bold mb-1">{stats.active}</div>
|
||||
<div className="text-sm opacity-90">ط¥ظٹط¬ط§ط±ط§طھ ظ†ط´ط·ط©</div>
|
||||
<div className="text-sm opacity-90">إيجارات نشطة</div>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
@ -1398,23 +1400,23 @@ export default function BookingRequests() {
|
||||
className="bg-gradient-to-br from-green-600 to-green-700 text-white rounded-2xl p-4 shadow-lg"
|
||||
>
|
||||
<div className="text-3xl font-bold mb-1">{stats.completed}</div>
|
||||
<div className="text-sm opacity-90">ظ…ظ†طھظ‡ظٹط©</div>
|
||||
<div className="text-sm opacity-90">منتهية</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white/80 backdrop-blur-sm rounded-2xl p-4 shadow-lg border border-white/20">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<h3 className="font-bold text-gray-700">طھطµظپظٹط© طط³ط¨ ط§ظ„طط§ظ„ط©</h3>
|
||||
<span className="text-sm text-gray-500">{filteredRequests.length} ط·ظ„ط¨</span>
|
||||
<h3 className="font-bold text-gray-700">تصفية حسب الحالة</h3>
|
||||
<span className="text-sm text-gray-500">{filteredRequests.length} طلب</span>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{[
|
||||
{ id: 'all', label: 'ط§ظ„ظƒظ„', color: 'gray' },
|
||||
{ id: 'pending', label: 'ظ‚ظٹط¯ ط§ظ„ط§ظ†طھط¸ط§ط±', color: 'yellow' },
|
||||
{ id: 'owner_approved', label: 'ظ…ظˆط§ظپظ‚ط© ط§ظ„ظ…ط§ظ„ظƒ', color: 'blue' },
|
||||
{ id: 'admin_approved', label: 'ظ…ظˆط§ظپظ‚ط© ط§ظ„ط¥ط¯ط§ط±ط©', color: 'green' },
|
||||
{ id: 'active', label: 'ط¥ظٹط¬ط§ط±ط§طھ ظ†ط´ط·ط©', color: 'purple' },
|
||||
{ id: 'completed', label: 'ظ…ظ†طھظ‡ظٹط©', color: 'gray' }
|
||||
{ id: 'all', label: 'الكل', color: 'gray' },
|
||||
{ id: 'pending', label: 'قيد الانتظار', color: 'yellow' },
|
||||
{ id: 'owner_approved', label: 'موافقة المالك', color: 'blue' },
|
||||
{ id: 'admin_approved', label: 'موافقة الإدارة', color: 'green' },
|
||||
{ id: 'active', label: 'إيجارات نشطة', color: 'purple' },
|
||||
{ id: 'completed', label: 'منتهية', color: 'gray' }
|
||||
].map((tab) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
@ -1452,8 +1454,8 @@ export default function BookingRequests() {
|
||||
<div className="w-24 h-24 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<Clock className="w-12 h-12 text-gray-400" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-gray-700 mb-2">ظ„ط§ طھظˆط¬ط¯ ط·ظ„ط¨ط§طھ طط¬ط²</h3>
|
||||
<p className="text-gray-500">ظ„ط§ طھظˆط¬ط¯ ط·ظ„ط¨ط§طھ طط¬ط² ظپظٹ ظ‡ط°ظ‡ ط§ظ„ظپط¦ط©</p>
|
||||
<h3 className="text-xl font-bold text-gray-700 mb-2">لا توجد طلبات حجز</h3>
|
||||
<p className="text-gray-500">لا توجد طلبات حجز في هذه الفئة</p>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
@ -1461,7 +1463,7 @@ export default function BookingRequests() {
|
||||
isOpen={reasonDialog.isOpen}
|
||||
onClose={() => setReasonDialog({ isOpen: false, requestId: null, type: null })}
|
||||
onConfirm={handleRejectWithReason}
|
||||
title={reasonDialog.type === 'owner' ? 'ط±ظپط¶ ظ…ظ† ط§ظ„ظ…ط§ظ„ظƒ' : 'ط±ظپط¶ ط¥ط¯ط§ط±ظٹ'}
|
||||
title={reasonDialog.type === 'owner' ? 'رفض من المالك' : 'رفض إداري'}
|
||||
/>
|
||||
|
||||
<RequestDetailsDialog
|
||||
|
||||
Reference in New Issue
Block a user