'use client'; import { useState, useRef, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { ShieldCheck, Lock, Zap, Star, Rocket, Search, MapPin, Home, DollarSign, ChevronDown, Shield, Award, Sparkles, UserCircle, LogOut, Calendar, Building, PlusCircle, Heart, MessageCircle } from 'lucide-react'; import HeroSearch from './components/home/HeroSearch'; import PropertyMap from './components/home/PropertyMap'; import Link from 'next/link'; import Image from 'next/image'; import { getRentProperties, getSaleProperties } from './utils/api'; // Map API property data to the format the UI expects function mapApiProperty(item, index) { const info = item.propertyInformation || item; const isRent = item.monthlyRent !== undefined || item.dailyRent !== undefined; // Determine price display const dailyPrice = item.dailyRent ?? item.monthlyRent ?? item.price ?? 0; const monthlyPrice = item.monthlyRent ?? 0; // Map building type integer to string const buildingTypeMap = { 0: 'apartment', 1: 'villa', 2: 'house' }; const propType = buildingTypeMap[info.buildingType] || 'apartment'; // Map property status integer to string const statusMap = { 0: 'available', 1: 'booked', 2: 'maintenance' }; const status = statusMap[info.status] || 'available'; // Extract features as string array const features = []; if (item.isSmokeAllow) features.push('يسمح بالتدخين'); if (item.isVisitorAllow) features.push('يسمح بالزوار'); if (item.specializedFor) features.push('متخصص'); if (info.numberOfRooms) features.push(`${info.numberOfRooms} غرف`); if (info.numberOfBathRooms) features.push(`${info.numberOfBathRooms} حمامات`); return { id: item.id ?? index + 1, title: info.address || info.description?.substring(0, 40) || 'عقار', description: info.description || '', type: propType, price: dailyPrice, priceUSD: dailyPrice, priceUnit: 'daily', location: { city: extractCity(info.address), district: info.address || '', address: info.address || '', lat: parseFloat(info.cordsX) || 0, lng: parseFloat(info.cordsY) || 0, }, bedrooms: info.numberOfBedRooms || info.numberOfRooms || 0, bathrooms: info.numberOfBathRooms || 0, area: info.space || 0, features, images: ['/property-placeholder.jpg'], status, rating: item.rating || 4.5, isNew: false, allowedIdentities: ['syrian', 'passport'], priceDisplay: { daily: dailyPrice, monthly: monthlyPrice, }, bookings: [], _raw: item, }; } function extractCity(address) { if (!address) return ''; const cities = ['دمشق', 'حلب', 'حمص', 'اللاذقية', 'درعا', 'طرطوس', 'السويداء', 'دير الزور', 'الرقة', 'إدلب', 'الحسكة', 'القامشلي', 'ريف دمشق']; for (const city of cities) { if (address.includes(city)) return city; } return address.split(' ').pop() || ''; } // Fallback dummy data const FALLBACK_PROPERTIES = [ { id: 1, title: 'فيلا فاخرة في المزة', description: 'فيلا فاخرة مع حديقة خاصة ومسبح في أفضل أحياء دمشق.', type: 'villa', price: 500000, priceUSD: 50, priceUnit: 'daily', location: { city: 'دمشق', district: 'المزة', address: 'شارع المزة - فيلات غربية', lat: 33.5138, lng: 36.2765 }, bedrooms: 5, bathrooms: 4, area: 450, features: ['مسبح', 'حديقة خاصة', 'موقف سيارات', 'أمن 24/7', 'تدفئة مركزية', 'تكييف مركزي'], images: ['/villa1.jpg', '/villa2.jpg', '/villa3.jpg'], status: 'available', rating: 4.8, isNew: true, allowedIdentities: ['syrian', 'passport'], priceDisplay: { daily: 500000, monthly: 15000000 }, bookings: [{ startDate: '2024-03-10', endDate: '2024-03-15' }, { startDate: '2024-03-20', endDate: '2024-03-25' }] }, { id: 2, title: 'شقة حديثة في الشهباء', description: 'شقة عصرية في حي الشهباء الراقي بحلب.', type: 'apartment', price: 250000, priceUSD: 25, priceUnit: 'daily', location: { city: 'حلب', district: 'الشهباء', address: 'شارع النيل - بناء الرحاب', lat: 36.2021, lng: 37.1347 }, bedrooms: 3, bathrooms: 2, area: 180, features: ['مطبخ مجهز', 'بلكونة', 'موقف سيارات', 'مصعد'], images: ['/apartment1.jpg', '/apartment2.jpg'], status: 'available', rating: 4.5, isNew: false, allowedIdentities: ['syrian'], priceDisplay: { daily: 250000, monthly: 7500000 }, bookings: [{ startDate: '2024-03-05', endDate: '2024-03-08' }] }, { id: 3, title: 'بيت عائلي في بابا عمرو', description: 'بيت واسع مناسب للعائلات في حمص.', type: 'house', price: 350000, priceUSD: 35, priceUnit: 'daily', location: { city: 'حمص', district: 'بابا عمرو', address: 'حي الزهور', lat: 34.7265, lng: 36.7186 }, bedrooms: 4, bathrooms: 3, area: 300, features: ['حديقة كبيرة', 'موقف سيارات', 'مدفأة', 'كراج'], images: ['/house1.jpg'], status: 'booked', rating: 4.3, isNew: false, allowedIdentities: ['syrian', 'passport'], priceDisplay: { daily: 350000, monthly: 10500000 }, bookings: [] }, { id: 4, title: 'شقة بجانب البحر', description: 'شقة رائعة مع إطلالة بحرية في اللاذقية.', type: 'apartment', price: 300000, priceUSD: 30, priceUnit: 'daily', location: { city: 'اللاذقية', district: 'الشاطئ الأزرق', address: 'الكورنيش الغربي', lat: 35.5306, lng: 35.7801 }, bedrooms: 3, bathrooms: 2, area: 200, features: ['إطلالة بحرية', 'شرفة', 'تكييف', 'أمن'], images: ['/seaside1.jpg', '/seaside2.jpg', '/seaside3.jpg'], status: 'available', rating: 4.9, isNew: true, allowedIdentities: ['passport'], priceDisplay: { daily: 300000, monthly: 9000000 }, bookings: [] }, { id: 5, title: 'فيلا في درعا', description: 'فيلا فاخرة في حي الأطباء بدرعا.', type: 'villa', price: 400000, priceUSD: 40, priceUnit: 'daily', location: { city: 'درعا', district: 'حي الأطباء', address: 'شارع الشفاء', lat: 32.6237, lng: 36.1016 }, bedrooms: 4, bathrooms: 3, area: 350, features: ['حديقة مثمرة', 'أنظمة أمن', 'مسبح', 'كراج'], images: ['/villa4.jpg', '/villa5.jpg'], status: 'available', rating: 4.6, isNew: false, allowedIdentities: ['syrian', 'passport'], priceDisplay: { daily: 400000, monthly: 12000000 }, bookings: [] } ]; export default function HomePage() { const mapSectionRef = useRef(null); const [searchFilters, setSearchFilters] = useState(null); const [showMap, setShowMap] = useState(false); const [filteredProperties, setFilteredProperties] = useState([]); const [isScrolling, setIsScrolling] = useState(false); const [user, setUser] = useState(null); const [showUserMenu, setShowUserMenu] = useState(false); const menuRef = useRef(null); const [allProperties, setAllProperties] = useState(FALLBACK_PROPERTIES); const [loading, setLoading] = useState(true); // Fetch properties from API on mount useEffect(() => { const storedUser = localStorage.getItem('user'); if (storedUser) { setUser(JSON.parse(storedUser)); } async function fetchProperties() { try { const [rentData, saleData] = await Promise.all([ getRentProperties().catch(() => []), getSaleProperties().catch(() => []), ]); const rentList = Array.isArray(rentData) ? rentData : []; const saleList = Array.isArray(saleData) ? saleData : []; const mapped = [ ...rentList.map((p, i) => mapApiProperty(p, i)), ...saleList.map((p, i) => mapApiProperty(p, rentList.length + i)), ]; if (mapped.length > 0) { setAllProperties(mapped); } // If API returns empty, keep fallback } catch (err) { console.warn('Failed to fetch properties, using fallback data:', err); // keep fallback data } finally { setLoading(false); } } fetchProperties(); }, []); useEffect(() => { const handleClickOutside = (event) => { if (menuRef.current && !menuRef.current.contains(event.target)) { setShowUserMenu(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); const logout = () => { localStorage.removeItem('user'); setUser(null); setShowUserMenu(false); }; const applyFilters = (filters) => { setSearchFilters(filters); const filtered = allProperties.filter(property => { if (filters.city && filters.city !== 'all' && property.location.city !== filters.city) { return false; } if (filters.propertyType && filters.propertyType !== 'all' && property.type !== filters.propertyType) { return false; } if (filters.priceRange && filters.priceRange !== 'all') { const priceUSD = property.priceUSD; switch (filters.priceRange) { case '0-500': if (priceUSD > 50) return false; break; case '500-1000': if (priceUSD < 51 || priceUSD > 100) return false; break; case '1000-2000': if (priceUSD < 101 || priceUSD > 200) return false; break; case '2000-3000': if (priceUSD < 201 || priceUSD > 300) return false; break; case '3000+': if (priceUSD < 301) return false; break; } } if (filters.identityType && property.allowedIdentities) { if (!property.allowedIdentities.includes(filters.identityType)) { return false; } } return true; }); setFilteredProperties(filtered); if (!showMap) { setShowMap(true); setTimeout(() => { if (mapSectionRef.current) { setIsScrolling(true); mapSectionRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' }); setTimeout(() => setIsScrolling(false), 1000); } }, 300); } else { if (mapSectionRef.current) { setIsScrolling(true); mapSectionRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' }); setTimeout(() => setIsScrolling(false), 1000); } } }; const resetSearch = () => { setShowMap(false); setSearchFilters(null); setFilteredProperties([]); window.scrollTo({ top: 0, behavior: 'smooth' }); }; const getUserInitial = () => { if (user?.name) { return user.name.charAt(0).toUpperCase(); } return null; }; const isOwner = user?.role === 'owner'; return (
يمكنك إدارة عقاراتك من خلال لوحة التحكم الخاصة بك
تم العثور على {filteredProperties.length} عقار يطابق معايير البحث
) : (لا توجد عقارات تطابق معايير البحث. جرب تغيير الفلاتر.
)}حاول تغيير معايير البحث
نجعل عملية إيجاد منزلك المثالي سهلة وسريعة
كل عقار يتم التحقق منه بدقة لضمان الدقة والجودة.
سلامتك هي أولويتنا. نوفر معاملات آمنة ونحمي معلوماتك الشخصية.
اعثر على منزلك المثالي في دقائق باستخدام خوارزميات البحث والمطابقة المتقدمة لدينا.