2026-01-29 19:34:28 +03:00
|
|
|
'use client';
|
|
|
|
|
|
2026-03-07 07:34:31 +03:00
|
|
|
import { useState, useRef, useEffect } from 'react';
|
|
|
|
|
import { motion, AnimatePresence } from 'framer-motion';
|
2026-01-29 19:34:28 +03:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2026-03-07 07:34:31 +03:00
|
|
|
import {
|
|
|
|
|
ShieldCheck,
|
|
|
|
|
Lock,
|
|
|
|
|
Zap,
|
|
|
|
|
Star,
|
|
|
|
|
Rocket,
|
|
|
|
|
Search,
|
|
|
|
|
MapPin,
|
|
|
|
|
Home,
|
|
|
|
|
DollarSign,
|
|
|
|
|
ChevronDown,
|
|
|
|
|
Shield,
|
|
|
|
|
Award,
|
2026-03-17 20:36:59 +03:00
|
|
|
Sparkles,
|
|
|
|
|
UserCircle,
|
|
|
|
|
LogOut,
|
|
|
|
|
Calendar,
|
|
|
|
|
Building,
|
|
|
|
|
PlusCircle,
|
|
|
|
|
Heart,
|
|
|
|
|
MessageCircle
|
2026-03-07 07:34:31 +03:00
|
|
|
} from 'lucide-react';
|
2026-01-29 19:34:28 +03:00
|
|
|
import './i18n/config';
|
2026-03-07 07:34:31 +03:00
|
|
|
import HeroSearch from './components/home/HeroSearch';
|
|
|
|
|
import PropertyMap from './components/home/PropertyMap';
|
2026-03-17 20:36:59 +03:00
|
|
|
import Link from 'next/link';
|
|
|
|
|
import Image from 'next/image';
|
2026-01-29 19:34:28 +03:00
|
|
|
|
|
|
|
|
export default function HomePage() {
|
|
|
|
|
const { t } = useTranslation();
|
2026-03-07 07:34:31 +03:00
|
|
|
const mapSectionRef = useRef(null);
|
|
|
|
|
const [searchFilters, setSearchFilters] = useState(null);
|
|
|
|
|
const [showMap, setShowMap] = useState(false);
|
|
|
|
|
const [filteredProperties, setFilteredProperties] = useState([]);
|
|
|
|
|
const [isScrolling, setIsScrolling] = useState(false);
|
2026-03-17 20:36:59 +03:00
|
|
|
const [user, setUser] = useState(null);
|
|
|
|
|
const [showUserMenu, setShowUserMenu] = useState(false);
|
|
|
|
|
const menuRef = useRef(null);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const storedUser = localStorage.getItem('user');
|
|
|
|
|
if (storedUser) {
|
|
|
|
|
setUser(JSON.parse(storedUser));
|
|
|
|
|
}
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
};
|
2026-01-29 19:34:28 +03:00
|
|
|
|
2026-03-07 07:34:31 +03:00
|
|
|
const [allProperties] = useState([
|
|
|
|
|
{
|
|
|
|
|
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: []
|
2026-01-29 19:34:28 +03:00
|
|
|
}
|
2026-03-07 07:34:31 +03:00
|
|
|
]);
|
2026-01-29 19:34:28 +03:00
|
|
|
|
2026-03-07 07:34:31 +03:00
|
|
|
const applyFilters = (filters) => {
|
|
|
|
|
setSearchFilters(filters);
|
|
|
|
|
|
|
|
|
|
const filtered = allProperties.filter(property => {
|
|
|
|
|
if (filters.city && filters.city !== 'all' && property.location.city !== filters.city) {
|
|
|
|
|
return false;
|
2026-01-29 19:34:28 +03:00
|
|
|
}
|
2026-03-07 07:34:31 +03:00
|
|
|
|
|
|
|
|
if (filters.propertyType && filters.propertyType !== 'all' && property.type !== filters.propertyType) {
|
|
|
|
|
return false;
|
2026-01-29 19:34:28 +03:00
|
|
|
}
|
2026-03-07 07:34:31 +03:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-29 19:34:28 +03:00
|
|
|
};
|
|
|
|
|
|
2026-03-07 07:34:31 +03:00
|
|
|
const resetSearch = () => {
|
|
|
|
|
setShowMap(false);
|
|
|
|
|
setSearchFilters(null);
|
|
|
|
|
setFilteredProperties([]);
|
|
|
|
|
window.scrollTo({
|
|
|
|
|
top: 0,
|
|
|
|
|
behavior: 'smooth'
|
|
|
|
|
});
|
2026-01-29 19:34:28 +03:00
|
|
|
};
|
2026-01-28 17:32:36 +03:00
|
|
|
|
2026-03-17 20:36:59 +03:00
|
|
|
const getUserInitial = () => {
|
|
|
|
|
if (user?.name) {
|
|
|
|
|
return user.name.charAt(0).toUpperCase();
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const isOwner = user?.role === 'owner';
|
|
|
|
|
|
2026-01-28 17:32:36 +03:00
|
|
|
return (
|
2026-03-07 07:34:31 +03:00
|
|
|
<div className="min-h-screen">
|
2026-01-29 19:34:28 +03:00
|
|
|
<section className="relative min-h-screen flex items-center justify-center overflow-hidden">
|
|
|
|
|
<div className="absolute inset-0 z-0">
|
|
|
|
|
<motion.div
|
|
|
|
|
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
|
|
|
|
|
style={{
|
2026-03-07 07:34:31 +03:00
|
|
|
backgroundImage: 'url(/hero.jpg)',
|
2026-01-29 19:34:28 +03:00
|
|
|
}}
|
|
|
|
|
initial={{ scale: 1.1 }}
|
|
|
|
|
animate={{ scale: 1 }}
|
|
|
|
|
transition={{ duration: 1.5, ease: "easeOut" }}
|
|
|
|
|
/>
|
|
|
|
|
<div className="absolute inset-0 bg-gradient-to-r from-black/70 via-black/60 to-black/50" />
|
|
|
|
|
</div>
|
|
|
|
|
<div className="relative z-10 container mx-auto px-4 sm:px-6 lg:px-8">
|
|
|
|
|
<div className="max-w-6xl mx-auto">
|
|
|
|
|
<motion.div
|
|
|
|
|
className="text-center mb-12"
|
|
|
|
|
initial="hidden"
|
|
|
|
|
animate="visible"
|
2026-03-07 07:34:31 +03:00
|
|
|
variants={{
|
|
|
|
|
hidden: { opacity: 0 },
|
|
|
|
|
visible: {
|
|
|
|
|
opacity: 1,
|
|
|
|
|
transition: { staggerChildren: 0.2 }
|
|
|
|
|
}
|
|
|
|
|
}}
|
2026-01-28 17:32:36 +03:00
|
|
|
>
|
2026-01-29 19:34:28 +03:00
|
|
|
<motion.h1
|
|
|
|
|
className="text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-bold text-white mb-6 leading-tight tracking-tight"
|
2026-03-07 07:34:31 +03:00
|
|
|
variants={{
|
|
|
|
|
hidden: { opacity: 0, y: 20 },
|
|
|
|
|
visible: { opacity: 1, y: 0 }
|
|
|
|
|
}}
|
2026-01-29 19:34:28 +03:00
|
|
|
>
|
|
|
|
|
{t("heroTitleLine1")}<br />
|
|
|
|
|
<motion.span
|
|
|
|
|
className="text-amber-400"
|
2026-03-07 07:34:31 +03:00
|
|
|
animate={{
|
|
|
|
|
y: [0, -10, 0],
|
|
|
|
|
}}
|
|
|
|
|
transition={{
|
|
|
|
|
duration: 2,
|
|
|
|
|
repeat: Infinity,
|
|
|
|
|
ease: "easeInOut"
|
|
|
|
|
}}
|
2026-01-29 19:34:28 +03:00
|
|
|
>
|
|
|
|
|
{t("heroTitleLine2")}
|
|
|
|
|
</motion.span>
|
|
|
|
|
</motion.h1>
|
|
|
|
|
<motion.p
|
|
|
|
|
className="text-base sm:text-lg text-gray-200 max-w-2xl mx-auto leading-relaxed"
|
2026-03-07 07:34:31 +03:00
|
|
|
variants={{
|
|
|
|
|
hidden: { opacity: 0, y: 20 },
|
|
|
|
|
visible: { opacity: 1, y: 0 }
|
|
|
|
|
}}
|
2026-01-29 19:34:28 +03:00
|
|
|
>
|
|
|
|
|
{t("heroSubtitle")}
|
|
|
|
|
</motion.p>
|
|
|
|
|
</motion.div>
|
2026-03-17 20:36:59 +03:00
|
|
|
|
|
|
|
|
{!isOwner && <HeroSearch onSearch={applyFilters} />}
|
|
|
|
|
|
|
|
|
|
{isOwner && (
|
|
|
|
|
<motion.div
|
|
|
|
|
initial={{ opacity: 0, y: 20 }}
|
|
|
|
|
animate={{ opacity: 1, y: 0 }}
|
|
|
|
|
transition={{ delay: 0.5 }}
|
|
|
|
|
className="bg-white/10 backdrop-blur-lg rounded-2xl p-8 text-center border border-white/20"
|
|
|
|
|
>
|
|
|
|
|
<h2 className="text-2xl font-bold text-white mb-2">
|
|
|
|
|
مرحباً {user?.name}!
|
|
|
|
|
</h2>
|
|
|
|
|
<p className="text-gray-200 mb-4">
|
|
|
|
|
يمكنك إدارة عقاراتك من خلال لوحة التحكم الخاصة بك
|
|
|
|
|
</p>
|
|
|
|
|
{/* <Link
|
|
|
|
|
href="/owner/properties"
|
|
|
|
|
className="inline-flex items-center gap-2 bg-amber-500 text-white px-6 py-3 rounded-xl font-medium hover:bg-amber-600 transition-colors"
|
|
|
|
|
>
|
|
|
|
|
<Building className="w-5 h-5" />
|
|
|
|
|
إدارة عقاراتي
|
|
|
|
|
</Link> */}
|
|
|
|
|
</motion.div>
|
|
|
|
|
)}
|
2026-01-29 19:34:28 +03:00
|
|
|
</div>
|
2026-01-28 17:32:36 +03:00
|
|
|
</div>
|
2026-03-17 20:36:59 +03:00
|
|
|
|
|
|
|
|
{!showMap && !isOwner && (
|
2026-01-29 19:34:28 +03:00
|
|
|
<motion.div
|
2026-03-07 07:34:31 +03:00
|
|
|
className="absolute bottom-8 left-1/2 transform -translate-x-1/2 cursor-pointer"
|
|
|
|
|
animate={{
|
|
|
|
|
y: [0, 10, 0],
|
|
|
|
|
}}
|
|
|
|
|
transition={{
|
|
|
|
|
duration: 1.5,
|
|
|
|
|
repeat: Infinity,
|
|
|
|
|
ease: "easeInOut"
|
|
|
|
|
}}
|
|
|
|
|
onClick={() => window.scrollTo({
|
|
|
|
|
top: window.innerHeight,
|
|
|
|
|
behavior: 'smooth'
|
|
|
|
|
})}
|
2026-01-28 17:32:36 +03:00
|
|
|
>
|
2026-03-07 07:34:31 +03:00
|
|
|
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 14l-7 7m0 0l-7-7m7 7V3" />
|
|
|
|
|
</svg>
|
2026-01-29 19:34:28 +03:00
|
|
|
</motion.div>
|
2026-03-07 07:34:31 +03:00
|
|
|
)}
|
|
|
|
|
</section>
|
2026-01-29 19:34:28 +03:00
|
|
|
|
2026-03-17 20:36:59 +03:00
|
|
|
{!isOwner && (
|
|
|
|
|
<AnimatePresence mode="wait">
|
|
|
|
|
{showMap && (
|
|
|
|
|
<motion.section
|
|
|
|
|
ref={mapSectionRef}
|
|
|
|
|
initial={{ opacity: 0, y: 50 }}
|
|
|
|
|
animate={{ opacity: 1, y: 0 }}
|
|
|
|
|
exit={{ opacity: 0, y: -50 }}
|
|
|
|
|
transition={{
|
|
|
|
|
type: "spring",
|
|
|
|
|
damping: 20,
|
|
|
|
|
stiffness: 100,
|
|
|
|
|
duration: 0.6
|
|
|
|
|
}}
|
|
|
|
|
className="py-12 bg-gray-50 relative"
|
|
|
|
|
>
|
|
|
|
|
{isScrolling && (
|
|
|
|
|
<motion.div
|
|
|
|
|
className="absolute top-0 left-0 right-0 h-1 bg-amber-500 z-10"
|
|
|
|
|
initial={{ scaleX: 0 }}
|
|
|
|
|
animate={{ scaleX: 1 }}
|
|
|
|
|
transition={{ duration: 1, ease: "easeInOut" }}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2026-01-29 19:34:28 +03:00
|
|
|
|
2026-03-17 20:36:59 +03:00
|
|
|
<div className="container mx-auto px-4">
|
2026-03-07 07:34:31 +03:00
|
|
|
<motion.div
|
|
|
|
|
initial={{ opacity: 0, y: 20 }}
|
|
|
|
|
animate={{ opacity: 1, y: 0 }}
|
2026-03-17 20:36:59 +03:00
|
|
|
transition={{ delay: 0.2 }}
|
|
|
|
|
className="text-center mb-8"
|
2026-03-07 07:34:31 +03:00
|
|
|
>
|
2026-03-17 20:36:59 +03:00
|
|
|
<div className="flex items-center justify-center gap-4 mb-2">
|
|
|
|
|
<h2 className="text-3xl font-bold text-gray-900">
|
|
|
|
|
{filteredProperties.length > 0 ? 'نتائج البحث' : 'لا توجد نتائج'}
|
|
|
|
|
</h2>
|
|
|
|
|
<motion.button
|
|
|
|
|
onClick={resetSearch}
|
|
|
|
|
className="px-4 py-2 bg-white border border-gray-300 rounded-full text-sm font-medium text-gray-700 hover:bg-gray-50 shadow-sm flex items-center gap-2"
|
|
|
|
|
whileHover={{ scale: 1.05 }}
|
|
|
|
|
whileTap={{ scale: 0.95 }}
|
|
|
|
|
>
|
|
|
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
|
|
|
|
</svg>
|
|
|
|
|
بحث جديد
|
|
|
|
|
</motion.button>
|
2026-03-07 07:34:31 +03:00
|
|
|
</div>
|
2026-03-17 20:36:59 +03:00
|
|
|
|
|
|
|
|
{filteredProperties.length > 0 ? (
|
|
|
|
|
<p className="text-gray-600">
|
|
|
|
|
تم العثور على {filteredProperties.length} عقار يطابق معايير البحث
|
|
|
|
|
</p>
|
|
|
|
|
) : (
|
|
|
|
|
<p className="text-gray-600">
|
|
|
|
|
لا توجد عقارات تطابق معايير البحث. جرب تغيير الفلاتر.
|
|
|
|
|
</p>
|
|
|
|
|
)}
|
2026-03-07 07:34:31 +03:00
|
|
|
</motion.div>
|
2026-03-17 20:36:59 +03:00
|
|
|
|
|
|
|
|
<motion.div
|
|
|
|
|
className="bg-white rounded-2xl shadow-xl overflow-hidden border border-gray-200"
|
|
|
|
|
initial={{ scale: 0.95, opacity: 0 }}
|
|
|
|
|
animate={{ scale: 1, opacity: 1 }}
|
|
|
|
|
transition={{ delay: 0.3, type: "spring" }}
|
|
|
|
|
>
|
|
|
|
|
{filteredProperties.length > 0 ? (
|
|
|
|
|
<PropertyMap
|
|
|
|
|
properties={filteredProperties}
|
|
|
|
|
userIdentity={searchFilters?.identityType || 'syrian'}
|
|
|
|
|
/>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="h-[400px] flex flex-col items-center justify-center bg-gray-50">
|
|
|
|
|
<div className="w-24 h-24 bg-gray-200 rounded-full flex items-center justify-center mb-4">
|
|
|
|
|
<svg className="w-12 h-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
|
|
|
</svg>
|
|
|
|
|
</div>
|
|
|
|
|
<h3 className="text-xl font-bold text-gray-700 mb-2">لا توجد نتائج</h3>
|
|
|
|
|
<p className="text-gray-500">حاول تغيير معايير البحث</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</motion.div>
|
|
|
|
|
|
|
|
|
|
{filteredProperties.length > 0 && searchFilters && (
|
|
|
|
|
<motion.div
|
|
|
|
|
initial={{ opacity: 0, y: 20 }}
|
|
|
|
|
animate={{ opacity: 1, y: 0 }}
|
|
|
|
|
transition={{ delay: 0.5 }}
|
|
|
|
|
className="mt-6 flex flex-wrap gap-3 justify-center"
|
|
|
|
|
>
|
|
|
|
|
<div className="bg-white px-4 py-2 rounded-full shadow-sm border border-gray-200 text-sm">
|
|
|
|
|
<span className="text-gray-600">المدينة: </span>
|
|
|
|
|
<span className="font-bold text-gray-900">
|
|
|
|
|
{searchFilters.city === 'all' ? 'جميع المدن' : searchFilters.city}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="bg-white px-4 py-2 rounded-full shadow-sm border border-gray-200 text-sm">
|
|
|
|
|
<span className="text-gray-600">نوع العقار: </span>
|
|
|
|
|
<span className="font-bold text-gray-900">
|
|
|
|
|
{searchFilters.propertyType === 'all' ? 'الكل' :
|
|
|
|
|
searchFilters.propertyType === 'apartment' ? 'شقة' :
|
|
|
|
|
searchFilters.propertyType === 'villa' ? 'فيلا' : 'بيت'}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="bg-white px-4 py-2 rounded-full shadow-sm border border-gray-200 text-sm">
|
|
|
|
|
<span className="text-gray-600">نطاق السعر: </span>
|
|
|
|
|
<span className="font-bold text-gray-900">
|
|
|
|
|
{searchFilters.priceRange === 'all' ? 'جميع الأسعار' :
|
|
|
|
|
searchFilters.priceRange === '0-500' ? 'أقل من 50$' :
|
|
|
|
|
searchFilters.priceRange === '500-1000' ? '50$ - 100$' :
|
|
|
|
|
searchFilters.priceRange === '1000-2000' ? '100$ - 200$' :
|
|
|
|
|
searchFilters.priceRange === '2000-3000' ? '200$ - 300$' : 'أكثر من 300$'}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</motion.div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</motion.section>
|
|
|
|
|
)}
|
|
|
|
|
</AnimatePresence>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<section className="py-20 bg-gradient-to-b from-white to-gray-50">
|
|
|
|
|
<div className="container mx-auto px-4">
|
|
|
|
|
<motion.div
|
|
|
|
|
className="text-center mb-12"
|
|
|
|
|
initial={{ opacity: 0, y: 20 }}
|
|
|
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
|
|
|
viewport={{ once: true }}
|
|
|
|
|
transition={{ duration: 0.6 }}
|
|
|
|
|
>
|
|
|
|
|
<div className="inline-block px-4 py-1 bg-amber-100 text-amber-700 rounded-full text-sm font-medium mb-4">
|
|
|
|
|
لماذا نحن؟
|
2026-03-07 07:34:31 +03:00
|
|
|
</div>
|
2026-03-17 20:36:59 +03:00
|
|
|
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4 tracking-tight">
|
|
|
|
|
{t("whyChooseUsTitle")}
|
|
|
|
|
</h2>
|
|
|
|
|
<p className="text-gray-600 max-w-2xl mx-auto text-lg">
|
|
|
|
|
{t("whyChooseUsSubtitle")}
|
|
|
|
|
</p>
|
|
|
|
|
</motion.div>
|
2026-03-07 07:34:31 +03:00
|
|
|
|
2026-03-17 20:36:59 +03:00
|
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
|
|
|
<motion.div
|
|
|
|
|
className="group bg-white p-6 rounded-xl shadow-sm hover:shadow-md transition-all duration-300 border border-gray-100"
|
|
|
|
|
initial={{ opacity: 0, y: 20 }}
|
|
|
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
|
|
|
viewport={{ once: true }}
|
|
|
|
|
transition={{ duration: 0.5, delay: 0.1 }}
|
|
|
|
|
whileHover={{ y: -4 }}
|
|
|
|
|
>
|
|
|
|
|
<div className="flex items-center gap-4 mb-4">
|
|
|
|
|
<div className="w-12 h-12 bg-amber-100 rounded-xl flex items-center justify-center group-hover:bg-amber-200 transition-colors duration-300">
|
|
|
|
|
<ShieldCheck className="w-6 h-6 text-amber-600" />
|
|
|
|
|
</div>
|
|
|
|
|
<h3 className="text-lg font-bold text-gray-900">
|
|
|
|
|
{t("feature1Title")}
|
|
|
|
|
</h3>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<p className="text-gray-600 text-sm leading-relaxed">
|
|
|
|
|
{t("feature1Description")}
|
|
|
|
|
</p>
|
|
|
|
|
</motion.div>
|
|
|
|
|
|
|
|
|
|
<motion.div
|
|
|
|
|
className="group bg-white p-6 rounded-xl shadow-sm hover:shadow-md transition-all duration-300 border border-gray-100"
|
|
|
|
|
initial={{ opacity: 0, y: 20 }}
|
|
|
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
|
|
|
viewport={{ once: true }}
|
|
|
|
|
transition={{ duration: 0.5, delay: 0.2 }}
|
|
|
|
|
whileHover={{ y: -4 }}
|
|
|
|
|
>
|
|
|
|
|
<div className="flex items-center gap-4 mb-4">
|
|
|
|
|
<div className="w-12 h-12 bg-blue-100 rounded-xl flex items-center justify-center group-hover:bg-blue-200 transition-colors duration-300">
|
|
|
|
|
<Lock className="w-6 h-6 text-blue-600" />
|
|
|
|
|
</div>
|
|
|
|
|
<h3 className="text-lg font-bold text-gray-900">
|
|
|
|
|
{t("feature2Title")}
|
|
|
|
|
</h3>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<p className="text-gray-600 text-sm leading-relaxed">
|
|
|
|
|
{t("feature2Description")}
|
|
|
|
|
</p>
|
|
|
|
|
</motion.div>
|
|
|
|
|
|
|
|
|
|
<motion.div
|
|
|
|
|
className="group bg-white p-6 rounded-xl shadow-sm hover:shadow-md transition-all duration-300 border border-gray-100"
|
|
|
|
|
initial={{ opacity: 0, y: 20 }}
|
|
|
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
|
|
|
viewport={{ once: true }}
|
|
|
|
|
transition={{ duration: 0.5, delay: 0.3 }}
|
|
|
|
|
whileHover={{ y: -4 }}
|
|
|
|
|
>
|
|
|
|
|
<div className="flex items-center gap-4 mb-4">
|
|
|
|
|
<div className="w-12 h-12 bg-green-100 rounded-xl flex items-center justify-center group-hover:bg-green-200 transition-colors duration-300">
|
|
|
|
|
<Zap className="w-6 h-6 text-green-600" />
|
|
|
|
|
</div>
|
|
|
|
|
<h3 className="text-lg font-bold text-gray-900">
|
|
|
|
|
{t("feature3Title")}
|
|
|
|
|
</h3>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<p className="text-gray-600 text-sm leading-relaxed">
|
|
|
|
|
{t("feature3Description")}
|
|
|
|
|
</p>
|
|
|
|
|
</motion.div>
|
2026-03-07 07:34:31 +03:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-03-17 20:36:59 +03:00
|
|
|
</section>
|
2026-01-28 17:32:36 +03:00
|
|
|
</div>
|
|
|
|
|
);
|
2026-01-29 19:34:28 +03:00
|
|
|
}
|