From aff9912ac2c829c9f52ccc5e3c226ec4c26990b8 Mon Sep 17 00:00:00 2001 From: mouazkh Date: Mon, 25 May 2026 21:53:57 +0300 Subject: [PATCH] fixed my propries page and fixed the sidebar again mouaz is the best in the west --- app/property/[id]/PropertyDetail.js | 336 +++++++++++++++++++++++----- 1 file changed, 277 insertions(+), 59 deletions(-) diff --git a/app/property/[id]/PropertyDetail.js b/app/property/[id]/PropertyDetail.js index 0c3f9fa..acc6c02 100644 --- a/app/property/[id]/PropertyDetail.js +++ b/app/property/[id]/PropertyDetail.js @@ -1,7 +1,7 @@ 'use client'; -import { useState, useEffect } from 'react'; -import { motion } from 'framer-motion'; +import { useState, useEffect, useMemo } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; import toast, { Toaster } from 'react-hot-toast'; import Link from 'next/link'; import { useParams, useRouter } from 'next/navigation'; @@ -10,7 +10,10 @@ import { Phone, Mail, MessageCircle, Calendar, Shield, Star, ChevronLeft, ChevronRight, Check, X, Wifi, Car, Wind, Camera, Home, Building2, Users, Clock, FileText, - LogIn, Loader2, ArrowLeft, ImageIcon, ChevronDown + LogIn, Loader2, ArrowLeft, ImageIcon, ChevronDown, + Layers, Sofa, DoorOpen, School, Hospital, Store, + TreePine, Building, GraduationCap, ExternalLink, + Smile, Ban, Wine, Dog, CassetteTape, Info } from 'lucide-react'; import { getRentProperty, getSaleProperty, getSalePropertyById, bookReservation, getAvailableDateRanges, getOwnerContactInformation } from '../../utils/api'; import AuthService from '../../services/AuthService'; @@ -42,6 +45,33 @@ function buildImageUrl(img) { return `${apiBase}${img.startsWith('/') ? '' : '/Pictures/'}${img}`; } +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 proximityLabels = { + School: 'مدرسة', Hospital: 'مستشفى', Restaurant: 'مطعم', + University: 'جامعة', Park: 'حديقة', Mall: 'مركز تسوق', + Supermarket: 'سوبر ماركت', Pharmacy: 'صيدلية', Mosque: 'مسجد', + Bank: 'بنك', Airport: 'مطار', BusStation: 'موقف باص', +}; + function mapApiDetail(item) { if (!item) return null; const info = item.propertyInformation || {}; @@ -55,20 +85,24 @@ function mapApiDetail(item) { const priceUnit = isRent ? (monthlyPrice ? 'monthly' : 'daily') : 'sale'; const propType = BuildingTypeKeys[info.buildingType] ?? BuildingTypeKeys[item.type] ?? 'apartment'; - const typeLabel = { apartment: 'شقة', villa: 'فيلا', house: 'بيت', sweet: 'سويت', studio: 'استوديو', office: 'مكتب', shop: 'متجر', warehouse: 'مستودع', farms: 'مزرعة', room: 'غرفة' }[propType] || 'عقار'; + const typeLabel = { apartment: 'شقة', villa: 'فيلا', house: 'بيت', sweet: 'سويت', studio: 'استوديو', office: 'مكتب', shop: 'متجر', warehouse: 'مستودع', farms: 'مزرعة', room: 'غرفة ضمن شقة' }[propType] || 'عقار'; const status = PropertyStatusKeys[info.status] ?? PropertyStatusKeys[item.status] ?? 'available'; - const statusLabel = { available: 'متاح', booked: 'محجوز', maintenance: 'صيانة', not_available: 'غير متاح' }[status] || 'متاح'; + const statusLabel = { available: 'متاح', booked: 'محجوز', notAvailable: 'غير متاح', maintenance: 'صيانة' }[status] || 'متاح'; const rawImages = Array.isArray(info.images) ? info.images : []; - const images = rawImages.length > 0 ? rawImages.map(buildImageUrl) : []; + const photosFallback = Array.isArray(details.photos) ? details.photos : []; + const allRaw = rawImages.length > 0 ? rawImages : photosFallback; + const images = allRaw.length > 0 ? allRaw.map(buildImageUrl) : []; const services = details.services || {}; const terms = details.terms || {}; + const proximity = details.proximity || {}; + const roomDetails = details.roomDetails || {}; return { id: item.id, - title: info.address || `عقار #${item.id}`, - description: info.description || '', + title: details.description || info.address || `عقار #${item.id}`, + description: details.description || info.description || '', type: propType, typeLabel, price, @@ -84,11 +118,16 @@ function mapApiDetail(item) { bedrooms: info.numberOfBedRooms || 0, bathrooms: info.numberOfBathRooms || 0, area: info.space || 0, + floor: details.floor || 0, + salons: details.salons || 0, + balconies: details.balconies || 0, images, status, statusLabel, services, terms, + proximity, + roomDetails, details, deposit: item.deposit || 0, currencyId: item.currencyId, @@ -236,6 +275,8 @@ export default function PropertyDetailsPage() { } const isFav = isFavorite(property.id); + const isRoomType = property.type === 'room'; + const isMostRequested = avgRating !== null && avgRating >= 4.5; return (
@@ -253,35 +294,55 @@ export default function PropertyDetailsPage() {
{/* Image Gallery */} -
+
{property.images.length > 0 ? ( - {property.title} + {property.title} ) : ( -
- +
+
+ +

لا توجد صور

+
)} + + {isMostRequested && ( +
+ + الأكثر طلباً + +
+ )} + {property.images.length > 1 && ( <> )} -
- {property.statusLabel} + +
+ {property.statusLabel} + {property.typeLabel} +
+
+ {currentImage + 1} / {property.images.length || 1}
+ {property.images.length > 1 && ( -
+
{property.images.map((img, idx) => ( ))} @@ -314,7 +375,7 @@ export default function PropertyDetailsPage() { {/* Price */}
{property.isRent ? ( -
+
{property.priceDisplay.monthly > 0 && (
{formatCurrency(property.priceDisplay.monthly)} @@ -328,7 +389,9 @@ export default function PropertyDetailsPage() {
)} {property.deposit > 0 && ( -
تأمين: {formatCurrency(property.deposit)} ل.س
+
+ تأمين: {formatCurrency(property.deposit)} ل.س +
)}
) : ( @@ -340,33 +403,54 @@ export default function PropertyDetailsPage() { )}
- {/* Stats */} -
+ {/* Specs Tiles */} +
{property.bedrooms > 0 && ( -
- -
{property.bedrooms}
+
+ +
{property.bedrooms}
غرف نوم
)} {property.bathrooms > 0 && ( -
- -
{property.bathrooms}
+
+ +
{property.bathrooms}
حمامات
)} {property.area > 0 && ( -
- -
{property.area}
+
+ +
{property.area}
م²
)} + {property.floor > 0 && ( +
+ +
{property.floor}
+
طابق
+
+ )} + {property.salons > 0 && ( +
+ +
{property.salons}
+
صالونات
+
+ )} + {property.balconies > 0 && ( +
+ +
{property.balconies}
+
بلكونات
+
+ )} {avgRating !== null && avgRating > 0 && ( -
- -
{avgRating.toFixed(1)}
+
+ +
{avgRating.toFixed(1)}
التقييم
)} @@ -382,34 +466,148 @@ export default function PropertyDetailsPage() { {/* Features */}
- {property.isSmokeAllow && يسمح بالتدخين} - {property.isVisitorAllow && يسمح بالزوار} - {property.specializedFor && متخصص} + {property.isSmokeAllow && يسمح بالتدخين} + {!property.isSmokeAllow && ممنوع التدخين} + {property.isVisitorAllow && يسمح بالزوار} + {property.specializedFor && {property.specializedFor}}
- {/* Services */} + {/* Services with detail text */} {Object.keys(property.services).length > 0 && (

الخدمات

{Object.entries(property.services).map(([key, val]) => { if (!val) return null; - const labels = { Electricity: 'كهرباء', Internet: 'إنترنت', Heating: 'تدفئة', Water: 'ماء', Pool: 'مسبح', PrivateGarden: 'حديقة خاصة', Parking: 'موقف سيارات', Security247: 'حراسة 24 س', CentralHeating: 'تدفئة مركزية', CentralAirConditioning: 'تكييف مركزي', EquippedKitchen: 'مطبخ مجهز', MaidsRoom: 'غرفة خادمة', Elevator: 'مصعد' }; - return {labels[key] || key}; + const detail = typeof val === 'object' && val.detail ? val.detail : null; + return ( + + {serviceLabels[key] || key} + {detail && · {detail}} + + ); })}
)} - {/* Terms */} + {/* Room Details (only for room type) */} + {isRoomType && Object.keys(property.roomDetails).length > 0 && ( +
+

+ + تفاصيل الغرفة +

+
+ {property.roomDetails.areaType && ( +
+
نوع المساحة
+
{property.roomDetails.areaType}
+
+ )} + {property.roomDetails.peopleAllowed && ( +
+
عدد الأشخاص
+
{property.roomDetails.peopleAllowed}
+
+ )} + {property.roomDetails.furniture && ( +
+
الأثاث
+
{property.roomDetails.furniture}
+
+ )} + {property.roomDetails.entranceType && ( +
+
نوع المدخل
+
{property.roomDetails.entranceType}
+
+ )} + {property.roomDetails.bathroomType && ( +
+
الحمام
+
{property.roomDetails.bathroomType}
+
+ )} + {property.roomDetails.kitchenType && ( +
+
المطبخ
+
{property.roomDetails.kitchenType}
+
+ )} + {property.roomDetails.residents && ( +
+
عدد السكان
+
{property.roomDetails.residents}
+
+ )} + {property.roomDetails.dedicatedTo && ( +
+
مخصص لـ
+
{property.roomDetails.dedicatedTo}
+
+ )} + {property.roomDetails.visitors && ( +
+
الزوار
+
{property.roomDetails.visitors ? 'مسموح' : 'ممنوع'}
+
+ )} + {property.roomDetails.quietTimes && ( +
+
أوقات الهدوء
+
{property.roomDetails.quietTimes}
+
+ )} +
+
+ )} + + {/* Proximity */} + {Object.keys(property.proximity).length > 0 && ( +
+

القرب من الخدمات

+
+ {Object.entries(property.proximity).map(([key, val]) => { + if (!val) return null; + const dist = typeof val === 'object' ? val.distance : val; + return ( +
+ {key === 'School' && } + {key === 'Hospital' && } + {key === 'Restaurant' && } + {key === 'University' && } + {key === 'Park' && } + {key === 'Mall' && } + {!['School','Hospital','Restaurant','University','Park','Mall'].includes(key) && } +
+
{proximityLabels[key] || key}
+
{dist} {typeof dist === 'number' ? 'كم' : ''}
+
+
+ ); + })} +
+
+ )} + + {/* Terms as checklist */} {Object.keys(property.terms).length > 0 && (

الشروط

-
+
{Object.entries(property.terms).map(([key, val]) => { if (!val) return null; - const labels = { NoSmoking: 'ممنوع التدخين', NoAnimals: 'ممنوع الحيوانات', NoParties: 'ممنوع الحفلات' }; - return {labels[key] || key}; + return ( +
+ {key.startsWith('No') || key.startsWith('Only') ? ( + + ) : ( + + )} + {termLabels[key] || key} +
+ ); })}
@@ -418,13 +616,26 @@ export default function PropertyDetailsPage() { {/* Map */} {property.location.lat && property.location.lng && ( - - - - - {property.title} - - + +
+ + + + {property.title} + + +
+
+ + موقع تقريبي — يظهر الموقع الدقيق بعد تأكيد الحجز +
+
)} @@ -457,7 +668,10 @@ export default function PropertyDetailsPage() { {/* Booking Card */} {property.isRent && ( -

حجز العقار

+
+ +

حجز العقار

+
{bookingSuccess ? (
@@ -471,12 +685,12 @@ export default function PropertyDetailsPage() { <>
- + setBookingDates(prev => ({ ...prev, start: e.target.value }))} className="w-full px-3 py-2 border border-gray-300 rounded-xl focus:ring-2 focus:ring-amber-500" />
- + setBookingDates(prev => ({ ...prev, end: e.target.value }))} className="w-full px-3 py-2 border border-gray-300 rounded-xl focus:ring-2 focus:ring-amber-500" />
@@ -498,19 +712,23 @@ export default function PropertyDetailsPage() { {/* Contact Card */} -

معلومات المالك

+
+ +

معلومات المالك

+
{showContact && contactInfo ? (
- + {contactInfo.phone || contactInfo.phoneNumber || '—'}
{contactInfo.whatsAppNumber && ( - + )}
) : (