fixed my propries page and fixed the sidebar again mouaz is the best in the west
All checks were successful
Build frontend / build (push) Successful in 42s
All checks were successful
Build frontend / build (push) Successful in 42s
This commit is contained in:
@ -43,7 +43,9 @@ import {
|
||||
Pencil,
|
||||
Save,
|
||||
X,
|
||||
Star
|
||||
Star,
|
||||
Ban,
|
||||
Check
|
||||
} from 'lucide-react';
|
||||
import toast, { Toaster } from 'react-hot-toast';
|
||||
import AuthService from '../../services/AuthService';
|
||||
@ -97,23 +99,29 @@ const DeleteConfirmationModal = ({ isOpen, onClose, onConfirm, propertyTitle })
|
||||
);
|
||||
};
|
||||
|
||||
const serviceLabels = {
|
||||
Electricity: 'كهرباء', Internet: 'إنترنت', Heating: 'تدفئة', Water: 'ماء',
|
||||
Pool: 'مسبح', PrivateGarden: 'حديقة خاصة', Parking: 'موقف سيارات',
|
||||
Security247: 'حراسة 24 س', CentralHeating: 'تدفئة مركزية',
|
||||
CentralAirConditioning: 'تكييف مركزي', EquippedKitchen: 'مطبخ مجهز',
|
||||
MaidsRoom: 'غرفة خادمة', Elevator: 'مصعد', Gym: 'نادي رياضي',
|
||||
Sauna: 'ساونا', Jacuzzi: 'جاكوزي', Balcony: 'بلكونة',
|
||||
Rooftop: 'سطح', Furnished: 'مفروش', AirConditioning: 'تكييف',
|
||||
SatelliteTV: 'تلفاز', Fireplace: 'مدفأة', StudyRoom: 'غرفة دراسة',
|
||||
Storage: 'مستودع', Laundry: 'غرفة غسيل', SmartHome: 'منزل ذكي',
|
||||
};
|
||||
|
||||
const termLabels = {
|
||||
NoSmoking: 'ممنوع التدخين', NoAnimals: 'ممنوع الحيوانات الأليفة',
|
||||
NoParties: 'ممنوع الحفلات', NoAlcohol: 'ممنوع الكحول',
|
||||
SuitableForChildren: 'مناسب للأطفال', SuitableForFamilies: 'مناسب للعائلات',
|
||||
SuitableForStudents: 'مناسب للطلاب', SuitableForElderly: 'مناسب لكبار السن',
|
||||
OnlyFemales: 'إناث فقط', OnlyMales: 'ذكور فقط',
|
||||
};
|
||||
|
||||
const PropertyViewModal = ({ isOpen, onClose, property }) => {
|
||||
if (!isOpen || !property) return null;
|
||||
|
||||
const getServiceIcon = (serviceId) => {
|
||||
const icons = {
|
||||
electricity: Zap,
|
||||
internet: Wifi,
|
||||
heating: Flame,
|
||||
water: Droplets,
|
||||
airConditioning: Wind,
|
||||
parking: Warehouse,
|
||||
elevator: Layers
|
||||
};
|
||||
const Icon = icons[serviceId];
|
||||
return Icon ? <Icon className="w-4 h-4" /> : null;
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
@ -166,23 +174,19 @@ const PropertyViewModal = ({ isOpen, onClose, property }) => {
|
||||
<div className="space-y-2">
|
||||
<p className="text-sm">
|
||||
<span className="text-gray-500">نوع العقار:</span>
|
||||
<span className="font-medium text-gray-900 mr-2">
|
||||
{property.propertyType === 'apartment' ? 'شقة' :
|
||||
property.propertyType === 'villa' ? 'فيلا' :
|
||||
property.propertyType === 'suite' ? 'سويت' : 'غرفة ضمن شقة'}
|
||||
</span>
|
||||
</p>
|
||||
<p className="text-sm">
|
||||
<span className="text-gray-500">الحالة:</span>
|
||||
<span className={`font-medium mr-2 ${property.furnished ? 'text-green-600' : 'text-gray-600'}`}>
|
||||
{property.furnished ? 'مفروش' : 'غير مفروش'}
|
||||
</span>
|
||||
<span className="font-medium text-gray-900 mr-2">{property.propertyTypeLabel || 'عقار'}</span>
|
||||
</p>
|
||||
{property.purpose === 'rent' && (
|
||||
<p className="text-sm">
|
||||
<span className="text-gray-500">حالة التأثيث:</span>
|
||||
<span className={`font-medium mr-2 ${property.furnished ? 'text-green-600' : 'text-gray-600'}`}>
|
||||
{property.furnished ? 'مفروش' : 'غير مفروش'}
|
||||
</span>
|
||||
</p>
|
||||
)}
|
||||
<p className="text-sm">
|
||||
<span className="text-gray-500">حالة العقار:</span>
|
||||
<span className={`font-medium mr-2 ${
|
||||
property.status === 'available' ? 'text-green-600' : 'text-yellow-600'
|
||||
}`}>
|
||||
<span className={`font-medium mr-2 ${property.status === 'available' ? 'text-green-600' : 'text-yellow-600'}`}>
|
||||
{property.status === 'available' ? 'متاح' : 'مؤجر'}
|
||||
</span>
|
||||
</p>
|
||||
@ -213,13 +217,27 @@ const PropertyViewModal = ({ isOpen, onClose, property }) => {
|
||||
<span className="text-sm font-bold">{property.area}</span>
|
||||
<span className="text-xs text-gray-500 block">م²</span>
|
||||
</div>
|
||||
{property.livingRooms && (
|
||||
{property.floor > 0 && (
|
||||
<div className="text-center">
|
||||
<Layers className="w-5 h-5 text-amber-500 mx-auto mb-1" />
|
||||
<span className="text-sm font-bold">{property.floor}</span>
|
||||
<span className="text-xs text-gray-500 block">طابق</span>
|
||||
</div>
|
||||
)}
|
||||
{property.salons > 0 && (
|
||||
<div className="text-center">
|
||||
<Sofa className="w-5 h-5 text-amber-500 mx-auto mb-1" />
|
||||
<span className="text-sm font-bold">{property.livingRooms}</span>
|
||||
<span className="text-sm font-bold">{property.salons}</span>
|
||||
<span className="text-xs text-gray-500 block">صالونات</span>
|
||||
</div>
|
||||
)}
|
||||
{property.balconies > 0 && (
|
||||
<div className="text-center">
|
||||
<DoorOpen className="w-5 h-5 text-amber-500 mx-auto mb-1" />
|
||||
<span className="text-sm font-bold">{property.balconies}</span>
|
||||
<span className="text-xs text-gray-500 block">بلكونات</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -236,23 +254,17 @@ const PropertyViewModal = ({ isOpen, onClose, property }) => {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{property.services && Object.values(property.services).some(v => v) && (
|
||||
{property.services && Object.keys(property.services).length > 0 && (
|
||||
<div className="bg-gray-50 p-4 rounded-xl mb-6">
|
||||
<h4 className="font-bold text-gray-700 mb-3">الخدمات المتوفرة</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{Object.entries(property.services).map(([key, value]) => {
|
||||
if (!value) return null;
|
||||
const Icon = getServiceIcon(key);
|
||||
const detail = typeof value === 'object' && value.detail ? value.detail : null;
|
||||
return (
|
||||
<span key={key} className="inline-flex items-center gap-1 px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm">
|
||||
{Icon}
|
||||
{key === 'electricity' && 'كهرباء'}
|
||||
{key === 'internet' && 'انترنت'}
|
||||
{key === 'heating' && 'تدفئة'}
|
||||
{key === 'water' && 'ماء'}
|
||||
{key === 'airConditioning' && 'تكييف'}
|
||||
{key === 'parking' && 'موقف سيارات'}
|
||||
{key === 'elevator' && 'مصعد'}
|
||||
{serviceLabels[key] || key}
|
||||
{detail && <span className="text-green-400">· {detail}</span>}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
@ -260,21 +272,21 @@ const PropertyViewModal = ({ isOpen, onClose, property }) => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{property.terms && Object.values(property.terms).some(v => v) && (
|
||||
{property.terms && Object.keys(property.terms).length > 0 && (
|
||||
<div className="bg-gray-50 p-4 rounded-xl mb-6">
|
||||
<h4 className="font-bold text-gray-700 mb-3">شروط الاستخدام</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
|
||||
{Object.entries(property.terms).map(([key, value]) => {
|
||||
if (!value) return null;
|
||||
return (
|
||||
<span key={key} className="inline-flex items-center gap-1 px-3 py-1 bg-amber-100 text-amber-800 rounded-full text-sm">
|
||||
{key === 'noSmoking' && ' ممنوع التدخين'}
|
||||
{key === 'noPets' && ' ممنوع الحيوانات'}
|
||||
{key === 'noParties' && ' ممنوع الحفلات'}
|
||||
{key === 'noAlcohol' && ' ممنوع الكحول'}
|
||||
{key === 'suitableForChildren' && ' مناسب للأطفال'}
|
||||
{key === 'suitableForElderly' && ' مناسب لكبار السن'}
|
||||
</span>
|
||||
<div key={key} className="flex items-center gap-2 p-2 bg-white rounded-lg">
|
||||
{key.startsWith('No') || key.startsWith('Only') ? (
|
||||
<Ban className="w-4 h-4 text-red-500 flex-shrink-0" />
|
||||
) : (
|
||||
<Check className="w-4 h-4 text-green-500 flex-shrink-0" />
|
||||
)}
|
||||
<span className="text-sm text-gray-700">{termLabels[key] || key}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
@ -285,24 +297,36 @@ const PropertyViewModal = ({ isOpen, onClose, property }) => {
|
||||
<h4 className="font-bold text-amber-700 mb-3">معلومات السعر</h4>
|
||||
{property.purpose === 'rent' ? (
|
||||
<div className="space-y-2">
|
||||
{property.dailyPrice && (
|
||||
{property.dailyPrice > 0 && (
|
||||
<p className="flex justify-between">
|
||||
<span className="text-gray-600">السعر اليومي:</span>
|
||||
<span className="font-bold text-amber-600">{Number(property.dailyPrice).toLocaleString()} ل.س</span>
|
||||
</p>
|
||||
)}
|
||||
{property.monthlyPrice && (
|
||||
{property.monthlyPrice > 0 && (
|
||||
<p className="flex justify-between">
|
||||
<span className="text-gray-600">السعر الشهري:</span>
|
||||
<span className="font-bold text-amber-600">{Number(property.monthlyPrice).toLocaleString()} ل.س</span>
|
||||
</p>
|
||||
)}
|
||||
{property.deposit > 0 && (
|
||||
<p className="flex justify-between">
|
||||
<span className="text-gray-600">التأمين:</span>
|
||||
<span className="font-bold text-gray-700">{Number(property.deposit).toLocaleString()} ل.س</span>
|
||||
</p>
|
||||
)}
|
||||
<p className="text-sm text-gray-500 mt-1">
|
||||
نوع الإيجار: {
|
||||
property.rentType === 'daily' ? 'يومي' :
|
||||
property.rentType === 'monthly' ? 'شهري' : 'يومي وشهري'
|
||||
}
|
||||
</p>
|
||||
{property.rating > 0 && (
|
||||
<p className="flex justify-between mt-2 pt-2 border-t border-amber-200">
|
||||
<span className="text-gray-600">التقييم:</span>
|
||||
<span className="font-bold text-amber-600 flex items-center gap-1">{Number(property.rating).toFixed(1)} <Star className="w-4 h-4 fill-amber-500" /></span>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<p className="flex justify-between">
|
||||
|
||||
Reference in New Issue
Block a user