'use client'; import { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Search, MapPin, Bed, Bath, Square, Filter, Grid3x3, List, Heart, ChevronDown, Star, Home, Building2, Phone, FileText } from 'lucide-react'; import Image from 'next/image'; import Link from 'next/link'; import { getRentProperties, getSaleProperties } from '../utils/api'; import { useFavorites } from '@/app/contexts/FavoritesContext'; import AuthService from '@/app/services/AuthService'; import toast, { Toaster } from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; function mapApiProperty(t, item, index) { const info = item.propertyInformation || {}; const dailyPrice = item.dailyRent ?? item.monthlyRent ?? item.price ?? 0; const buildingTypeMap = { 0: 'apartment', 1: 'villa', 2: 'sweet', 3: 'room', 4: 'studio', 5: 'office', 6: 'farms', 7: 'shop', 8: 'warehouse' }; const propType = buildingTypeMap[info.buildingType] ?? buildingTypeMap[item.type] ?? 'apartment'; const statusMap = { 0: 'available', 1: 'notAvailable', 2: 'booked' }; const status = statusMap[info.status] ?? statusMap[item.status] ?? 'available'; const cityMap = { 0: 'damascus', 1: 'aleppo', 2: 'homs', 3: 'latakia', 4: 'daraa', 5: 'tartous', 6: 'suweida', 7: 'deirEzzor', 8: 'raqqa', 9: 'idlib', 10: 'hasakah', 11: 'qamishli', 12: 'ruralDamascus' }; const features = []; if (item.isSmokeAllow) features.push(t('smoke-allowed', 'مسموح التدخين')); if (item.isVisitorAllow) features.push(t('visitors-allowed', 'مسموح الزوار')); if (item.specializedFor) features.push(t('specialized', 'مخصص')); if (info.numberOfBedRooms) features.push(`${info.numberOfBedRooms} ${t('bedrooms', 'غرف نوم')}`); if (info.numberOfBathRooms) features.push(`${info.numberOfBathRooms} ${t('bathrooms', 'حمامات')}`); const apiBase = typeof window !== 'undefined' ? (process.env.NEXT_PUBLIC_API_URL || 'http://45.93.137.91/api') : ''; const rawImages = Array.isArray(info.images) ? info.images : []; const images = rawImages.length > 0 ? rawImages.map(img => img.startsWith('http') ? img : `${apiBase}${img.startsWith('/') ? '' : '/Pictures/'}${img}`) : ['/property-placeholder.jpg']; return { id: item.id ?? index + 1, title: info.address || `${t('property', 'عقار')} #${item.id || index + 1}`, description: info.description || '', type: propType, price: dailyPrice, priceUnit: 'daily', location: { city: cityMap[info.city] || extractCity(info.address) || 'damascus', district: info.address || '', }, bedrooms: info.numberOfBedRooms || 0, bathrooms: info.numberOfBathRooms || 0, area: info.space || 0, features, images, status, rating: item.rating || 0, isNew: false, _raw: item, }; } function extractCity(address) { if (!address) return ''; const cityMap = { 'دمشق': 'damascus', 'حلب': 'aleppo', 'حمص': 'homs', 'اللاذقية': 'latakia', 'درعا': 'daraa', 'طرطوس': 'tartous', 'السويداء': 'suweida', 'دير الزور': 'deirEzzor', 'الرقة': 'raqqa', 'إدلب': 'idlib', 'الحسكة': 'hasakah', 'القامشلي': 'qamishli', 'ريف دمشق': 'ruralDamascus' }; for (const [arabic, key] of Object.entries(cityMap)) { if (address.includes(arabic)) return key; } return ''; } const PropertyCard = ({ property, viewMode = 'grid', onLoginRequired }) => { const { t, i18n } = useTranslation(); const { isFavorite: checkFavorite, addFavorite, removeFavorite } = useFavorites(); const [favLoading, setFavLoading] = useState(false); const [currentImage, setCurrentImage] = useState(0); const isFav = checkFavorite(property.id); const toggleFavorite = async (e) => { e.preventDefault(); e.stopPropagation(); if (!AuthService.isAuthenticated()) { onLoginRequired?.(); return; } setFavLoading(true); if (isFav) { await removeFavorite(property.id); } else { await addFavorite(property.id); } setFavLoading(false); }; const formatCurrency = (amount) => { return amount?.toLocaleString() + ' ' + t('syp-symbol', 'ل.س'); }; const getPropertyTypeIcon = (type) => { switch (type) { case 'villa': return ; case 'apartment': return ; case 'house': return ; case 'studio': return ; default: return ; } }; const getPropertyTypeLabel = (type) => { switch (type) { case 'villa': return t('buildingType.villa', 'فيلا'); case 'apartment': return t('buildingType.apartment', 'شقة'); case 'house': return t('house', 'منزل'); case 'studio': return t('buildingType.studio', 'ستوديو'); case 'sweet': return t('buildingType.sweet', 'جناح'); case 'room': return t('buildingType.room', 'غرفة'); case 'office': return t('buildingType.office', 'مكتب'); case 'farms': return t('buildingType.farms', 'مزرعة'); case 'shop': return t('buildingType.shop', 'محل تجاري'); case 'warehouse': return t('buildingType.warehouse', 'مستودع'); default: return type; } }; if (viewMode === 'list') { return (
{property.title} {property.images.length > 1 && (
{property.images.map((_, idx) => (
)}
{getPropertyTypeIcon(property.type)} {getPropertyTypeLabel(property.type)} {property.status === 'available' ? t('available', 'متاح') : t('booked', 'محجوز')}

{property.title}

{t('city.' + property.location.city, property.location.city)}، {property.location.district}
{formatCurrency(property.price)}
/{property.priceUnit === 'daily' ? t('day', 'يوم') : t('month', 'شهر')}
{property.bedrooms} {t('rooms', 'غرف')}
{property.bathrooms} {t('bathrooms', 'حمامات')}
{property.area} {t('sqm', 'م²')}

{property.description}

{t('viewDetails', 'عرض التفاصيل')}
); } return (
{property.title}
{getPropertyTypeIcon(property.type)} {getPropertyTypeLabel(property.type)} {property.status === 'available' && ( {t('available', 'متاح')} )}

{property.title}

{t('city.' + property.location.city, property.location.city)}، {property.location.district}
{formatCurrency(property.price)}
/{property.priceUnit === 'daily' ? t('day', 'يوم') : t('month', 'شهر')}
{property.bedrooms}
{property.bathrooms}
{property.area}{t('sqm', 'م²')}
{property.rating > 0 && (
{property.rating.toFixed(1)}
)}
{t('viewDetails', 'عرض التفاصيل')}
); }; const FilterBar = ({ filters, onFilterChange }) => { const { t } = useTranslation(); const [showFilters, setShowFilters] = useState(false); const propertyTypes = [ { id: 'all', label: t('all', 'الكل') }, { id: 'residential', label: t('propertyType.residential', 'سكني') }, { id: 'commercial', label: t('propertyType.commercial', 'تجاري') }, { id: 'agricultural', label: t('propertyType.agricultural', 'زراعي') }, ]; const buildingTypes = [ { id: 'all', label: t('all', 'الكل') }, { id: 'apartment', label: t('buildingType.apartment', 'شقة'), icon: Building2 }, { id: 'villa', label: t('buildingType.villa', 'فيلا'), icon: Home }, { id: 'sweet', label: t('buildingType.sweet', 'جناح'), icon: Home }, { id: 'room', label: t('buildingType.room', 'غرفة'), icon: Home }, { id: 'studio', label: t('buildingType.studio', 'ستوديو'), icon: Building2 }, { id: 'office', label: t('buildingType.office', 'مكتب'), icon: Building2 }, { id: 'farms', label: t('buildingType.farms', 'مزرعة'), icon: Home }, { id: 'shop', label: t('buildingType.shop', 'محل تجاري'), icon: Building2 }, { id: 'warehouse', label: t('buildingType.warehouse', 'مستودع'), icon: Building2 } ]; const priceRanges = [ { id: 'all', label: t('allPrices', 'جميع الأسعار') }, { id: '0-500000', label: t('price-range-less-than-500k', 'أقل من 500 ألف') }, { id: '500000-1000000', label: t('price-range-500k-to-1m', '500 ألف - 1 مليون') }, { id: '1000000-2000000', label: t('price-range-1m-to-2m', '1 مليون - 2 مليون') }, { id: '2000000-5000000', label: t('price-range-2m-to-5m', '2 مليون - 5 مليون') }, { id: '5000000+', label: t('price-range-more-than-5m', 'أكثر من 5 مليون') } ]; const cities = [ { id: 'all', label: t('allCities', 'جميع المدن') }, { id: 'damascus', label: t('city.damascus', 'دمشق') }, { id: 'aleppo', label: t('city.aleppo', 'حلب') }, { id: 'homs', label: t('city.homs', 'حمص') }, { id: 'latakia', label: t('city.latakia', 'اللاذقية') }, { id: 'daraa', label: t('city.daraa', 'درعا') }, { id: 'tartous', label: t('city.tartous', 'طرطوس') }, { id: 'suweida', label: t('city.suweida', 'السويداء') }, { id: 'deirEzzor', label: t('city.deirEzzor', 'دير الزور') }, { id: 'raqqa', label: t('city.raqqa', 'الرقة') }, { id: 'idlib', label: t('city.idlib', 'إدلب') }, { id: 'hasakah', label: t('city.hasakah', 'الحسكة') }, { id: 'qamishli', label: t('city.qamishli', 'القامشلي') }, { id: 'ruralDamascus', label: t('city.ruralDamascus', 'ريف دمشق') } ]; const certificates = [ { id: 'all', label: t('allCertificates', 'جميع السندات') }, { id: 'realEstateTitle', label: t('certificate.realEstateTitle', 'طابو أخضر') }, { id: 'courtRuling', label: t('certificate.courtRuling', 'حكم محكمة') }, { id: 'notary', label: t('certificate.notary', 'كاتب عدل') }, { id: 'shares', label: t('certificate.shares', 'أسهم عقارية') } ]; return (
onFilterChange({ ...filters, search: e.target.value })} />
{showFilters && (
onFilterChange({ ...filters, minArea: e.target.value })} /> onFilterChange({ ...filters, maxArea: e.target.value })} />
)}
); }; export default function PropertiesPage() { const { t, i18n } = useTranslation(); const [purposeTab, setPurposeTab] = useState('rent'); const [viewMode, setViewMode] = useState('grid'); const [sortBy, setSortBy] = useState('newest'); const [properties, setProperties] = useState([]); const [loading, setLoading] = useState(true); const [showLoginDialog, setShowLoginDialog] = useState(false); const [filters, setFilters] = useState({ search: '', propertyType: 'all', buildingType: 'all', city: 'all', priceRange: 'all', bedrooms: 'all', bathrooms: 'all', certificate: 'all', minArea: '', maxArea: '', features: [] }); useEffect(() => { async function fetchProperties() { setLoading(true); try { const queryParams = new URLSearchParams(); if (filters.bedrooms !== 'all') { queryParams.append('numberOfBedRooms', filters.bedrooms); } if (filters.bathrooms !== 'all') { queryParams.append('numberOfBathRooms', filters.bathrooms); } if (filters.minArea) { queryParams.append('space', filters.minArea); } const buildingTypeReverseMap = { 'apartment': 'Apartment', 'villa': 'Villa', 'sweet': 'Sweet', 'room': 'Room', 'studio': 'Studio', 'office': 'Office', 'farms': 'Farms', 'shop': 'Shop', 'warehouse': 'Warehouse' }; if (filters.buildingType !== 'all' && buildingTypeReverseMap[filters.buildingType] !== undefined) { queryParams.append('buildingType', buildingTypeReverseMap[filters.buildingType]); } const propertyTypeReverseMap = { 'residential': 'Residential', 'commercial': 'Commercial', 'agricultural': 'Agricultural' }; if (filters.propertyType !== 'all' && propertyTypeReverseMap[filters.propertyType] !== undefined) { queryParams.append('propertyType', propertyTypeReverseMap[filters.propertyType]); } const certificateReverseMap = { 'realEstateTitle': 'RealEstateTitle', 'courtRuling': 'CourtRuling', 'notary': 'Notary', 'shares': 'Shares' }; if (filters.certificate !== 'all' && certificateReverseMap[filters.certificate] !== undefined) { queryParams.append('certificate', certificateReverseMap[filters.certificate]); } if (filters.city !== 'all') { const cityFormatted = filters.city.charAt(0).toUpperCase() + filters.city.slice(1); queryParams.append('city', cityFormatted); } const baseUrl = process.env.NEXT_PUBLIC_API_URL || 'http://45.93.137.91/api'; const rentEndpoint = `${baseUrl}/RentProperties/FilterRentProperties?${queryParams.toString()}`; const [rentRes, saleData] = await Promise.all([ fetch(rentEndpoint, { headers: { 'Accept': 'application/json', } }).then(res => res.json()).catch(() => ({ data: [], isSuccess: false })), getSaleProperties().catch(() => []), ]); const rentList = rentRes.isSuccess && Array.isArray(rentRes.data) ? rentRes.data : []; const saleList = Array.isArray(saleData) ? saleData : []; const mapped = [ ...rentList.map((p, i) => ({ ...mapApiProperty(t, p, i), purpose: 'rent' })), ...saleList.map((p, i) => ({ ...mapApiProperty(t, p, rentList.length + i), purpose: 'sale' })), ]; setProperties(mapped); } catch (err) { console.error('[Properties] Failed to fetch properties:', err); } finally { setLoading(false); } } fetchProperties(); }, [filters, t]); const filteredProperties = properties .filter(p => p.purpose === purposeTab) .filter(property => { if (filters.search && !property.title.includes(filters.search) && !property.description.includes(filters.search)) { return false; } if (filters.priceRange !== 'all') { const [min, max] = filters.priceRange.split('-'); if (max) { if (property.price < parseInt(min) || property.price > parseInt(max)) return false; } else if (filters.priceRange.endsWith('+')) { const minVal = parseInt(filters.priceRange.replace('+', '')); if (property.price < minVal) return false; } } return true; }) .sort((a, b) => { switch (sortBy) { case 'price_asc': return a.price - b.price; case 'price_desc': return b.price - a.price; case 'rating': return b.rating - a.rating; default: return 0; } }); return (

{purposeTab === 'rent' ? t('properties-for-rent', 'عقارات للإيجار') : t('properties-for-sale', 'عقارات للبيع')}

{t('best-properties-in-syria', 'أفضل العقارات المتاحة في سوريا مباشرة وبسهولة')}

{loading && (
)}
{filteredProperties.length} {t('property-available', 'عقار متاح')}
{filteredProperties.map((property) => ( setShowLoginDialog(true)} /> ))}
{!loading && filteredProperties.length === 0 && (

{t('no-properties', 'لا يوجد نتائج تطابق بحثك')}

{t('try-changing-search-criteria', 'يرجى تجربة تعديل خيارات الفلترة والبحث')}

)}
{showLoginDialog && (
setShowLoginDialog(false)}> e.stopPropagation()} className="bg-white rounded-2xl p-6 max-w-sm w-full mx-4 shadow-xl text-center" >

{t('login-required-title', 'تسجيل الدخول مطلوب')}

{t('login-required-favorites-desc', 'يجب تسجيل الدخول لتتمكن من إضافة العقار للمفضلة')}

{t('login', 'دخول')}
)}
); }