Added translation to all site with edit style
All checks were successful
Build frontend / build (push) Successful in 1m40s
All checks were successful
Build frontend / build (push) Successful in 1m40s
This commit is contained in:
@ -35,9 +35,10 @@ 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';
|
||||
|
||||
// Map API data to UI format
|
||||
function mapApiProperty(item, index) {
|
||||
function mapApiProperty(t, item, index) {
|
||||
const info = item.propertyInformation || {};
|
||||
|
||||
const dailyPrice = item.dailyRent ?? item.monthlyRent ?? item.price ?? 0;
|
||||
@ -50,11 +51,11 @@ function mapApiProperty(item, index) {
|
||||
const status = statusMap[info.status] ?? statusMap[item.status] ?? 'available';
|
||||
|
||||
const features = [];
|
||||
if (item.isSmokeAllow) features.push('يسمح بالتدخين');
|
||||
if (item.isVisitorAllow) features.push('يسمح بالزوار');
|
||||
if (item.specializedFor) features.push('متخصص');
|
||||
if (info.numberOfBedRooms) features.push(`${info.numberOfBedRooms} غرف نوم`);
|
||||
if (info.numberOfBathRooms) features.push(`${info.numberOfBathRooms} حمامات`);
|
||||
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')}`);
|
||||
|
||||
// Extract images from API and build full URLs
|
||||
const apiBase = typeof window !== 'undefined' ? (process.env.NEXT_PUBLIC_API_URL || 'https://45.93.137.91.nip.io/api') : '';
|
||||
@ -65,13 +66,13 @@ function mapApiProperty(item, index) {
|
||||
|
||||
return {
|
||||
id: item.id ?? index + 1,
|
||||
title: info.address || `عقار #${item.id || index + 1}`,
|
||||
title: info.address || `${t('property')} #${item.id || index + 1}`,
|
||||
description: info.description || '',
|
||||
type: propType,
|
||||
price: dailyPrice,
|
||||
priceUnit: 'daily',
|
||||
location: {
|
||||
city: extractCity(info.address) || 'دمشق',
|
||||
city: extractCity(info.address) || 'damascus',
|
||||
district: info.address || '',
|
||||
},
|
||||
bedrooms: info.numberOfBedRooms || 0,
|
||||
@ -88,9 +89,23 @@ function mapApiProperty(item, index) {
|
||||
|
||||
function extractCity(address) {
|
||||
if (!address) return '';
|
||||
const cities = ['دمشق', 'حلب', 'حمص', 'اللاذقية', 'درعا', 'طرطوس', 'السويداء', 'دير الزور', 'الرقة', 'إدلب', 'الحسكة', 'القامشلي', 'ريف دمشق'];
|
||||
for (const city of cities) {
|
||||
if (address.includes(city)) return city;
|
||||
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 '';
|
||||
}
|
||||
@ -98,6 +113,7 @@ function extractCity(address) {
|
||||
// API-only — no fallback data
|
||||
|
||||
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);
|
||||
@ -118,7 +134,7 @@ const PropertyCard = ({ property, viewMode = 'grid', onLoginRequired }) => {
|
||||
};
|
||||
|
||||
const formatCurrency = (amount) => {
|
||||
return amount?.toLocaleString() + ' ل.س';
|
||||
return amount?.toLocaleString() + ' ' + t('syp-symbol');
|
||||
};
|
||||
|
||||
const getPropertyTypeIcon = (type) => {
|
||||
@ -133,10 +149,10 @@ const PropertyCard = ({ property, viewMode = 'grid', onLoginRequired }) => {
|
||||
|
||||
const getPropertyTypeLabel = (type) => {
|
||||
switch (type) {
|
||||
case 'villa': return 'فيلا';
|
||||
case 'apartment': return 'شقة';
|
||||
case 'house': return 'بيت';
|
||||
case 'studio': return 'استوديو';
|
||||
case 'villa': return t('buildingType.villa');
|
||||
case 'apartment': return t('buildingType.apartment');
|
||||
case 'house': return t('house');
|
||||
case 'studio': return t('buildingType.studio');
|
||||
default: return type;
|
||||
}
|
||||
};
|
||||
@ -187,33 +203,33 @@ const PropertyCard = ({ property, viewMode = 'grid', onLoginRequired }) => {
|
||||
{getPropertyTypeLabel(property.type)}
|
||||
</span>
|
||||
<span className={`px-2 py-1 rounded-lg text-xs font-medium ${property.status === 'available' ? 'bg-gray-800 text-white' : 'bg-gray-200 text-gray-600'}`}>
|
||||
{property.status === 'available' ? 'متاح' : 'محجوز'}
|
||||
{property.status === 'available' ? t('available') : t('booked')}
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-1">{property.title}</h3>
|
||||
<div className="flex items-center gap-1 text-gray-500 text-sm mb-3">
|
||||
<MapPin className="w-4 h-4" />
|
||||
{property.location.city}، {property.location.district}
|
||||
{t('city.' + property.location.city)}، {property.location.district}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<div className="text-2xl font-bold text-gray-900">{formatCurrency(property.price)}</div>
|
||||
<div className="text-xs text-gray-500">/{property.priceUnit === 'daily' ? 'يوم' : 'شهر'}</div>
|
||||
<div className="text-xs text-gray-500">/{property.priceUnit === 'daily' ? t('day') : t('month')}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-4 mb-4">
|
||||
<div className="flex items-center gap-1 text-gray-600">
|
||||
<Bed className="w-4 h-4" />
|
||||
<span>{property.bedrooms} غرف</span>
|
||||
<span>{property.bedrooms} {t('rooms')}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1 text-gray-600">
|
||||
<Bath className="w-4 h-4" />
|
||||
<span>{property.bathrooms} حمامات</span>
|
||||
<span>{property.bathrooms} {t('bathrooms')}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1 text-gray-600">
|
||||
<Square className="w-4 h-4" />
|
||||
<span>{property.area} م²</span>
|
||||
<span>{property.area} {t('sqm')}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -224,7 +240,7 @@ const PropertyCard = ({ property, viewMode = 'grid', onLoginRequired }) => {
|
||||
href={`/property/${property.id}`}
|
||||
className="flex-1 bg-gray-800 text-white py-3 rounded-xl font-medium hover:bg-gray-900 transition-colors text-center"
|
||||
>
|
||||
عرض التفاصيل
|
||||
{t('viewDetails')}
|
||||
</Link>
|
||||
<button className="px-4 bg-gray-100 text-gray-700 py-3 rounded-xl font-medium hover:bg-gray-200 transition-colors flex items-center gap-2">
|
||||
<Phone className="w-4 h-4" />
|
||||
@ -269,18 +285,18 @@ const PropertyCard = ({ property, viewMode = 'grid', onLoginRequired }) => {
|
||||
{getPropertyTypeLabel(property.type)}
|
||||
</span>
|
||||
{property.status === 'available' && (
|
||||
<span className="px-2 py-1 bg-gray-800 text-white rounded-lg text-xs font-medium">متاح</span>
|
||||
<span className="px-2 py-1 bg-gray-800 text-white rounded-lg text-xs font-medium">{t('available')}</span>
|
||||
)}
|
||||
</div>
|
||||
<h3 className="font-bold text-gray-900 mb-1 line-clamp-1">{property.title}</h3>
|
||||
<div className="flex items-center gap-1 text-gray-500 text-xs mb-2">
|
||||
<MapPin className="w-3 h-3" />
|
||||
<span className="line-clamp-1">{property.location.city}، {property.location.district}</span>
|
||||
<span className="line-clamp-1">{t('city.' + property.location.city)}، {property.location.district}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<div className="text-xl font-bold text-gray-900">{formatCurrency(property.price)}</div>
|
||||
<div className="text-xs text-gray-500">/{property.priceUnit === 'daily' ? 'يوم' : 'شهر'}</div>
|
||||
<div className="text-xs text-gray-500">/{property.priceUnit === 'daily' ? t('day') : t('month')}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -296,7 +312,7 @@ const PropertyCard = ({ property, viewMode = 'grid', onLoginRequired }) => {
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<Square className="w-4 h-4" />
|
||||
<span>{property.area}م²</span>
|
||||
<span>{property.area}{t('sqm')}</span>
|
||||
</div>
|
||||
</div>
|
||||
{property.rating > 0 && (
|
||||
@ -311,7 +327,7 @@ const PropertyCard = ({ property, viewMode = 'grid', onLoginRequired }) => {
|
||||
href={`/property/${property.id}`}
|
||||
className="block w-full bg-gray-800 text-white py-3 rounded-xl font-medium hover:bg-gray-900 transition-colors text-center"
|
||||
>
|
||||
عرض التفاصيل
|
||||
{t('viewDetails')}
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
@ -319,31 +335,40 @@ const PropertyCard = ({ property, viewMode = 'grid', onLoginRequired }) => {
|
||||
};
|
||||
|
||||
const FilterBar = ({ filters, onFilterChange }) => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const [showFilters, setShowFilters] = useState(false);
|
||||
|
||||
const propertyTypes = [
|
||||
{ id: 'all', label: 'الكل' },
|
||||
{ id: 'apartment', label: 'شقة', icon: Building2 },
|
||||
{ id: 'villa', label: 'فيلا', icon: Home },
|
||||
{ id: 'house', label: 'بيت', icon: Home },
|
||||
{ id: 'all', label: t('all') },
|
||||
{ id: 'apartment', label: t('buildingType.apartment'), icon: Building2 },
|
||||
{ id: 'villa', label: t('buildingType.villa'), icon: Home },
|
||||
{ id: 'house', label: t('house'), icon: Home },
|
||||
];
|
||||
|
||||
const priceRanges = [
|
||||
{ id: 'all', label: 'جميع الأسعار' },
|
||||
{ id: '0-500000', label: 'أقل من 500,000' },
|
||||
{ id: '500000-1000000', label: '500,000 - 1,000,000' },
|
||||
{ id: '1000000-2000000', label: '1,000,000 - 2,000,000' },
|
||||
{ id: '2000000-5000000', label: '2,000,000 - 5,000,000' },
|
||||
{ id: '5000000+', label: 'أكثر من 5,000,000' }
|
||||
{ id: 'all', label: t('allPrices') },
|
||||
{ id: '0-500000', label: t('price-range-less-than-500k') },
|
||||
{ id: '500000-1000000', label: t('price-range-500k-to-1m') },
|
||||
{ id: '1000000-2000000', label: t('price-range-1m-to-2m') },
|
||||
{ id: '2000000-5000000', label: t('price-range-2m-to-5m') },
|
||||
{ id: '5000000+', label: t('price-range-more-than-5m') }
|
||||
];
|
||||
|
||||
const cities = [
|
||||
{ id: 'all', label: 'جميع المدن' },
|
||||
{ id: 'دمشق', label: 'دمشق' },
|
||||
{ id: 'حلب', label: 'حلب' },
|
||||
{ id: 'حمص', label: 'حمص' },
|
||||
{ id: 'اللاذقية', label: 'اللاذقية' },
|
||||
{ id: 'درعا', label: 'درعا' }
|
||||
{ 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') }
|
||||
];
|
||||
|
||||
return (
|
||||
@ -353,7 +378,7 @@ const FilterBar = ({ filters, onFilterChange }) => {
|
||||
<Search className="absolute right-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="ابحث عن عقار..."
|
||||
placeholder={t('search-property-placeholder')}
|
||||
className="w-full pr-12 px-4 py-3 border border-gray-200 rounded-xl focus:ring-2 focus:ring-gray-300 focus:border-gray-300 transition-all"
|
||||
value={filters.search}
|
||||
onChange={(e) => onFilterChange({ ...filters, search: e.target.value })}
|
||||
@ -364,7 +389,7 @@ const FilterBar = ({ filters, onFilterChange }) => {
|
||||
className="px-6 py-3 bg-gray-100 rounded-xl font-medium hover:bg-gray-200 transition-colors flex items-center gap-2 text-gray-700"
|
||||
>
|
||||
<Filter className="w-5 h-5" />
|
||||
فلاتر متقدمة
|
||||
{t('advanced-filters')}
|
||||
<ChevronDown className={`w-4 h-4 transition-transform ${showFilters ? 'rotate-180' : ''}`} />
|
||||
</button>
|
||||
</div>
|
||||
@ -379,7 +404,7 @@ const FilterBar = ({ filters, onFilterChange }) => {
|
||||
>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 pt-4 border-t border-gray-100">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">نوع العقار</label>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">{t('property-type')}</label>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{propertyTypes.map((type) => {
|
||||
const Icon = type.icon;
|
||||
@ -398,7 +423,7 @@ const FilterBar = ({ filters, onFilterChange }) => {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">المدينة</label>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">{t('city')}</label>
|
||||
<select
|
||||
value={filters.city}
|
||||
onChange={(e) => onFilterChange({ ...filters, city: e.target.value })}
|
||||
@ -411,7 +436,7 @@ const FilterBar = ({ filters, onFilterChange }) => {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">نطاق السعر</label>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">{t('price-range')}</label>
|
||||
<select
|
||||
value={filters.priceRange}
|
||||
onChange={(e) => onFilterChange({ ...filters, priceRange: e.target.value })}
|
||||
@ -424,13 +449,13 @@ const FilterBar = ({ filters, onFilterChange }) => {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">غرف النوم</label>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">{t('bedrooms')}</label>
|
||||
<select
|
||||
value={filters.bedrooms}
|
||||
onChange={(e) => onFilterChange({ ...filters, bedrooms: e.target.value })}
|
||||
className="w-full px-4 py-2 border border-gray-200 rounded-xl focus:ring-2 focus:ring-gray-300 focus:border-gray-300"
|
||||
>
|
||||
<option value="all">جميع الأعداد</option>
|
||||
<option value="all">{t('all-numbers')}</option>
|
||||
<option value="1">1+</option>
|
||||
<option value="2">2+</option>
|
||||
<option value="3">3+</option>
|
||||
@ -440,18 +465,18 @@ const FilterBar = ({ filters, onFilterChange }) => {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">المساحة (م²)</label>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">{t('area-sqm')}</label>
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
type="number"
|
||||
placeholder="من"
|
||||
placeholder={t('from')}
|
||||
className="w-full px-4 py-2 border border-gray-200 rounded-xl focus:ring-2 focus:ring-gray-300 focus:border-gray-300"
|
||||
value={filters.minArea}
|
||||
onChange={(e) => onFilterChange({ ...filters, minArea: e.target.value })}
|
||||
/>
|
||||
<input
|
||||
type="number"
|
||||
placeholder="إلى"
|
||||
placeholder={t('to')}
|
||||
className="w-full px-4 py-2 border border-gray-200 rounded-xl focus:ring-2 focus:ring-gray-300 focus:border-gray-300"
|
||||
value={filters.maxArea}
|
||||
onChange={(e) => onFilterChange({ ...filters, maxArea: e.target.value })}
|
||||
@ -474,13 +499,13 @@ const FilterBar = ({ filters, onFilterChange }) => {
|
||||
})}
|
||||
className="px-6 py-2 bg-gray-100 rounded-xl font-medium hover:bg-gray-200 transition-colors text-gray-700"
|
||||
>
|
||||
إعادة تعيين
|
||||
{t('reset')}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setShowFilters(false)}
|
||||
className="px-6 py-2 bg-gray-800 text-white rounded-xl font-medium hover:bg-gray-900 transition-colors"
|
||||
>
|
||||
تطبيق الفلاتر
|
||||
{t('apply-filters')}
|
||||
</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
@ -491,6 +516,7 @@ const FilterBar = ({ filters, onFilterChange }) => {
|
||||
};
|
||||
|
||||
export default function PropertiesPage() {
|
||||
const { t, i18n } = useTranslation();
|
||||
const [purposeTab, setPurposeTab] = useState('rent');
|
||||
const [viewMode, setViewMode] = useState('grid');
|
||||
const [sortBy, setSortBy] = useState('newest');
|
||||
@ -520,8 +546,8 @@ export default function PropertiesPage() {
|
||||
const saleList = Array.isArray(saleData) ? saleData : [];
|
||||
|
||||
const mapped = [
|
||||
...rentList.map((p, i) => ({ ...mapApiProperty(p, i), purpose: 'rent' })),
|
||||
...saleList.map((p, i) => ({ ...mapApiProperty(p, rentList.length + i), purpose: 'sale' })),
|
||||
...rentList.map((p, i) => ({ ...mapApiProperty(t, p, i), purpose: 'rent' })),
|
||||
...saleList.map((p, i) => ({ ...mapApiProperty(t, p, rentList.length + i), purpose: 'sale' })),
|
||||
];
|
||||
|
||||
if (mapped.length > 0) {
|
||||
@ -575,26 +601,26 @@ export default function PropertiesPage() {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 py-8">
|
||||
<div dir={i18n.language === 'ar' ? 'rtl' : 'ltr'} className="min-h-screen bg-gray-50 py-8">
|
||||
<div className="container mx-auto px-4">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className="text-center mb-8"
|
||||
>
|
||||
<h1 className="text-4xl font-bold text-gray-900 mb-2">{purposeTab === 'rent' ? 'عقارات للإيجار' : 'عقارات للبيع'}</h1>
|
||||
<p className="text-gray-500">أفضل العقارات في سوريا</p>
|
||||
<h1 className="text-4xl font-bold text-gray-900 mb-2">{purposeTab === 'rent' ? t('properties-for-rent') : t('properties-for-sale')}</h1>
|
||||
<p className="text-gray-500">{t('best-properties-in-syria')}</p>
|
||||
|
||||
{/* Purpose Toggle */}
|
||||
<div className="flex justify-center mt-4">
|
||||
<div className="inline-flex bg-gray-100 rounded-xl p-1">
|
||||
<button onClick={() => setPurposeTab('rent')}
|
||||
className={`px-6 py-2 rounded-lg text-sm font-medium transition-all ${purposeTab === 'rent' ? 'bg-white text-amber-600 shadow-sm' : 'text-gray-500 hover:text-gray-700'}`}>
|
||||
للإيجار
|
||||
{t('for-rent')}
|
||||
</button>
|
||||
<button onClick={() => setPurposeTab('sale')}
|
||||
className={`px-6 py-2 rounded-lg text-sm font-medium transition-all ${purposeTab === 'sale' ? 'bg-white text-blue-600 shadow-sm' : 'text-gray-500 hover:text-gray-700'}`}>
|
||||
للبيع
|
||||
{t('for-sale')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -609,7 +635,7 @@ export default function PropertiesPage() {
|
||||
|
||||
<div className="flex justify-between items-center my-6">
|
||||
<div className="text-gray-600">
|
||||
<span className="font-bold text-gray-900">{filteredProperties.length}</span> عقار متاح
|
||||
<span className="font-bold text-gray-900">{filteredProperties.length}</span> {t('property-available')}
|
||||
</div>
|
||||
<div className="flex gap-3">
|
||||
<select
|
||||
@ -617,10 +643,10 @@ export default function PropertiesPage() {
|
||||
onChange={(e) => setSortBy(e.target.value)}
|
||||
className="px-4 py-2 border border-gray-200 rounded-xl focus:ring-2 focus:ring-gray-300 focus:border-gray-300 text-gray-700"
|
||||
>
|
||||
<option value="newest">الأحدث</option>
|
||||
<option value="price_asc">السعر: من الأقل</option>
|
||||
<option value="price_desc">السعر: من الأعلى</option>
|
||||
<option value="rating">التقييم</option>
|
||||
<option value="newest">{t('newest')}</option>
|
||||
<option value="price_asc">{t('price-low-to-high')}</option>
|
||||
<option value="price_desc">{t('price-high-to-low')}</option>
|
||||
<option value="rating">{t('rating')}</option>
|
||||
</select>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
@ -657,8 +683,8 @@ export default function PropertiesPage() {
|
||||
<div className="w-24 h-24 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<Home className="w-12 h-12 text-gray-400" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-gray-700 mb-2">لا توجد عقارات</h3>
|
||||
<p className="text-gray-500">جرب تغيير معايير البحث</p>
|
||||
<h3 className="text-xl font-bold text-gray-700 mb-2">{t('no-properties')}</h3>
|
||||
<p className="text-gray-500">{t('try-changing-search-criteria')}</p>
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
@ -674,20 +700,20 @@ export default function PropertiesPage() {
|
||||
<div className="w-14 h-14 bg-amber-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<Heart className="w-7 h-7 text-amber-600" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">تسجيل الدخول مطلوب</h3>
|
||||
<p className="text-gray-500 mb-6">يجب تسجيل الدخول لإضافة العقارات إلى المفضلة</p>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">{t('login-required-title')}</h3>
|
||||
<p className="text-gray-500 mb-6">{t('login-required-favorites-desc')}</p>
|
||||
<div className="flex gap-3">
|
||||
<button
|
||||
onClick={() => setShowLoginDialog(false)}
|
||||
className="flex-1 py-3 border border-gray-200 rounded-xl font-medium text-gray-600 hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
إلغاء
|
||||
{t('cancel')}
|
||||
</button>
|
||||
<Link
|
||||
href="/login"
|
||||
className="flex-1 py-3 bg-amber-500 text-white rounded-xl font-medium hover:bg-amber-600 transition-colors text-center"
|
||||
>
|
||||
تسجيل الدخول
|
||||
{t('login')}
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
Reference in New Issue
Block a user