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 ? (
-

+

) : (
-
-
+
)}
+
+ {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.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 && (
-
+
)}
) : (