'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.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 (
{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 (
{showFilters && (
)}
);
};
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', 'دخول')}
)}
);
}