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

This commit is contained in:
mouazkh
2026-05-25 22:37:05 +03:00
parent 291e82a1b4
commit 7b333f9b53

View File

@ -43,7 +43,9 @@ import {
Pencil, Pencil,
Save, Save,
X, X,
Star Star,
Ban,
Check
} from 'lucide-react'; } from 'lucide-react';
import toast, { Toaster } from 'react-hot-toast'; import toast, { Toaster } from 'react-hot-toast';
import AuthService from '../../services/AuthService'; 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 }) => { const PropertyViewModal = ({ isOpen, onClose, property }) => {
if (!isOpen || !property) return null; 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 ( return (
<motion.div <motion.div
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
@ -166,23 +174,19 @@ const PropertyViewModal = ({ isOpen, onClose, property }) => {
<div className="space-y-2"> <div className="space-y-2">
<p className="text-sm"> <p className="text-sm">
<span className="text-gray-500">نوع العقار:</span> <span className="text-gray-500">نوع العقار:</span>
<span className="font-medium text-gray-900 mr-2"> <span className="font-medium text-gray-900 mr-2">{property.propertyTypeLabel || 'عقار'}</span>
{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>
</p> </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"> <p className="text-sm">
<span className="text-gray-500">حالة العقار:</span> <span className="text-gray-500">حالة العقار:</span>
<span className={`font-medium mr-2 ${ <span className={`font-medium mr-2 ${property.status === 'available' ? 'text-green-600' : 'text-yellow-600'}`}>
property.status === 'available' ? 'text-green-600' : 'text-yellow-600'
}`}>
{property.status === 'available' ? 'متاح' : 'مؤجر'} {property.status === 'available' ? 'متاح' : 'مؤجر'}
</span> </span>
</p> </p>
@ -213,13 +217,27 @@ const PropertyViewModal = ({ isOpen, onClose, property }) => {
<span className="text-sm font-bold">{property.area}</span> <span className="text-sm font-bold">{property.area}</span>
<span className="text-xs text-gray-500 block">م²</span> <span className="text-xs text-gray-500 block">م²</span>
</div> </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"> <div className="text-center">
<Sofa className="w-5 h-5 text-amber-500 mx-auto mb-1" /> <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> <span className="text-xs text-gray-500 block">صالونات</span>
</div> </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> </div>
</div> </div>
@ -236,23 +254,17 @@ const PropertyViewModal = ({ isOpen, onClose, property }) => {
</p> </p>
</div> </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"> <div className="bg-gray-50 p-4 rounded-xl mb-6">
<h4 className="font-bold text-gray-700 mb-3">الخدمات المتوفرة</h4> <h4 className="font-bold text-gray-700 mb-3">الخدمات المتوفرة</h4>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{Object.entries(property.services).map(([key, value]) => { {Object.entries(property.services).map(([key, value]) => {
if (!value) return null; if (!value) return null;
const Icon = getServiceIcon(key); const detail = typeof value === 'object' && value.detail ? value.detail : null;
return ( 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"> <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} {serviceLabels[key] || key}
{key === 'electricity' && 'كهرباء'} {detail && <span className="text-green-400">· {detail}</span>}
{key === 'internet' && 'انترنت'}
{key === 'heating' && 'تدفئة'}
{key === 'water' && 'ماء'}
{key === 'airConditioning' && 'تكييف'}
{key === 'parking' && 'موقف سيارات'}
{key === 'elevator' && 'مصعد'}
</span> </span>
); );
})} })}
@ -260,21 +272,21 @@ const PropertyViewModal = ({ isOpen, onClose, property }) => {
</div> </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"> <div className="bg-gray-50 p-4 rounded-xl mb-6">
<h4 className="font-bold text-gray-700 mb-3">شروط الاستخدام</h4> <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]) => { {Object.entries(property.terms).map(([key, value]) => {
if (!value) return null; if (!value) return null;
return ( 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"> <div key={key} className="flex items-center gap-2 p-2 bg-white rounded-lg">
{key === 'noSmoking' && ' ممنوع التدخين'} {key.startsWith('No') || key.startsWith('Only') ? (
{key === 'noPets' && ' ممنوع الحيوانات'} <Ban className="w-4 h-4 text-red-500 flex-shrink-0" />
{key === 'noParties' && ' ممنوع الحفلات'} ) : (
{key === 'noAlcohol' && ' ممنوع الكحول'} <Check className="w-4 h-4 text-green-500 flex-shrink-0" />
{key === 'suitableForChildren' && ' مناسب للأطفال'} )}
{key === 'suitableForElderly' && ' مناسب لكبار السن'} <span className="text-sm text-gray-700">{termLabels[key] || key}</span>
</span> </div>
); );
})} })}
</div> </div>
@ -285,24 +297,36 @@ const PropertyViewModal = ({ isOpen, onClose, property }) => {
<h4 className="font-bold text-amber-700 mb-3">معلومات السعر</h4> <h4 className="font-bold text-amber-700 mb-3">معلومات السعر</h4>
{property.purpose === 'rent' ? ( {property.purpose === 'rent' ? (
<div className="space-y-2"> <div className="space-y-2">
{property.dailyPrice && ( {property.dailyPrice > 0 && (
<p className="flex justify-between"> <p className="flex justify-between">
<span className="text-gray-600">السعر اليومي:</span> <span className="text-gray-600">السعر اليومي:</span>
<span className="font-bold text-amber-600">{Number(property.dailyPrice).toLocaleString()} ل.س</span> <span className="font-bold text-amber-600">{Number(property.dailyPrice).toLocaleString()} ل.س</span>
</p> </p>
)} )}
{property.monthlyPrice && ( {property.monthlyPrice > 0 && (
<p className="flex justify-between"> <p className="flex justify-between">
<span className="text-gray-600">السعر الشهري:</span> <span className="text-gray-600">السعر الشهري:</span>
<span className="font-bold text-amber-600">{Number(property.monthlyPrice).toLocaleString()} ل.س</span> <span className="font-bold text-amber-600">{Number(property.monthlyPrice).toLocaleString()} ل.س</span>
</p> </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"> <p className="text-sm text-gray-500 mt-1">
نوع الإيجار: { نوع الإيجار: {
property.rentType === 'daily' ? 'يومي' : property.rentType === 'daily' ? 'يومي' :
property.rentType === 'monthly' ? 'شهري' : 'يومي وشهري' property.rentType === 'monthly' ? 'شهري' : 'يومي وشهري'
} }
</p> </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> </div>
) : ( ) : (
<p className="flex justify-between"> <p className="flex justify-between">