'use client';
import { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import {
PlusCircle,
Building,
Home,
DollarSign,
MapPin,
Bed,
Bath,
Square,
Edit,
Trash2,
Eye,
Calendar,
TrendingUp,
Users,
FileText,
Image as ImageIcon,
CheckCircle,
XCircle,
AlertCircle,
ChevronRight,
ChevronLeft,
Loader2,
Clock,
Wifi,
Zap,
Flame,
Droplets,
Cigarette,
Dog,
Music,
Warehouse,
Layers,
Sofa,
DoorOpen,
Wind,
Pencil,
Save,
X,
Star,
Ban,
Check
} from 'lucide-react';
import toast, { Toaster } from 'react-hot-toast';
import AuthService from '../../services/AuthService';
import { getMyRentListings, getMySaleListings, editRentProperty } from '../../utils/api';
const DeleteConfirmationModal = ({ isOpen, onClose, onConfirm, propertyTitle }) => {
if (!isOpen) return null;
return (
e.stopPropagation()}
>
تأكيد الحذف
هل أنت متأكد من حذف العقار: "{propertyTitle}"؟
هذا الإجراء لا يمكن التراجع عنه
);
};
const serviceLabels = {
Electricity: 'كهرباء', Internet: 'إنترنت', Heating: 'تدفئة', Water: 'ماء',
Pool: 'مسبح', PrivateGarden: 'حديقة خاصة', Parking: 'موقف سيارات',
Security247: 'حراسة 24 س', CentralHeating: 'تدفئة مركزية',
CentralAirConditioning: 'تكييف مركزي', EquippedKitchen: 'مطبخ مجهز',
MaidsRoom: 'غرفة خادمة', Elevator: 'مصعد', Gym: 'نادي رياضي',
Sauna: 'ساونا', Jacuzzi: 'جاكوزي', Balcony: 'بلكونة',
Rooftop: 'سطح', Furnished: 'مفروش', AirConditioning: 'تكييف',
SatelliteTV: 'تلفاز', Fireplace: 'مدفأة', StudyRoom: 'غرفة دراسة',
Storage: 'مستودع', Laundry: 'غرفة غسيل', SmartHome: 'منزل ذكي',
};
const termLabels = {
NoSmoking: 'ممنوع التدخين', NoAnimals: 'ممنوع الحيوانات الأليفة',
NoParties: 'ممنوع الحفلات', NoAlcohol: 'ممنوع الكحول',
SuitableForChildren: 'مناسب للأطفال', SuitableForFamilies: 'مناسب للعائلات',
SuitableForStudents: 'مناسب للطلاب', SuitableForElderly: 'مناسب لكبار السن',
OnlyFemales: 'إناث فقط', OnlyMales: 'ذكور فقط',
};
const PropertyViewModal = ({ isOpen, onClose, property }) => {
if (!isOpen || !property) return null;
return (
e.stopPropagation()}
>
{property.title}
تم الإضافة: {new Date(property.createdAt).toLocaleDateString('ar-SA')}
{property.images && property.images.length > 0 && (
صور العقار
{property.images.map((image, index) => (
))}
)}
معلومات أساسية
نوع العقار:
{property.propertyTypeLabel || 'عقار'}
{property.purpose === 'rent' && (
حالة التأثيث:
{property.furnished ? 'مفروش' : 'غير مفروش'}
)}
حالة العقار:
{property.status === 'available' ? 'متاح' : 'مؤجر'}
{property.description && (
الوصف:
{property.description}
)}
التفاصيل
{property.bedrooms}
غرف
{property.bathrooms}
حمامات
{property.area}
م²
{property.floor > 0 && (
{property.floor}
طابق
)}
{property.salons > 0 && (
{property.salons}
صالونات
)}
{property.balconies > 0 && (
{property.balconies}
بلكونات
)}
الموقع
{property.address || 'لم يتم تحديد العنوان'}
{property.city && `، ${property.city}`}
{property.district && `، ${property.district}`}
{property.services && Object.keys(property.services).length > 0 && (
الخدمات المتوفرة
{Object.entries(property.services).map(([key, value]) => {
if (!value) return null;
const detail = typeof value === 'object' && value.detail ? value.detail : null;
return (
{serviceLabels[key] || key}
{detail && · {detail}}
);
})}
)}
{property.terms && Object.keys(property.terms).length > 0 && (
شروط الاستخدام
{Object.entries(property.terms).map(([key, value]) => {
if (!value) return null;
return (
{key.startsWith('No') || key.startsWith('Only') ? (
) : (
)}
{termLabels[key] || key}
);
})}
)}
معلومات السعر
{property.purpose === 'rent' ? (
{property.dailyPrice > 0 && (
السعر اليومي:
{Number(property.dailyPrice).toLocaleString()} ل.س
)}
{property.monthlyPrice > 0 && (
السعر الشهري:
{Number(property.monthlyPrice).toLocaleString()} ل.س
)}
{property.deposit > 0 && (
التأمين:
{Number(property.deposit).toLocaleString()} ل.س
)}
نوع الإيجار: {
property.rentType === 'daily' ? 'يومي' :
property.rentType === 'monthly' ? 'شهري' : 'يومي وشهري'
}
{property.rating > 0 && (
التقييم:
{Number(property.rating).toFixed(1)}
)}
) : (
سعر البيع:
{Number(property.salePrice).toLocaleString()} ل.س
)}
);
};
const PropertyEditModal = ({ isOpen, onClose, property, onSave }) => {
const [formData, setFormData] = useState({ ...property });
const [isSaving, setIsSaving] = useState(false);
const [editingField, setEditingField] = useState(null);
const [tempValues, setTempValues] = useState({});
const sections = [
{
title: 'معلومات أساسية',
fields: [
{ id: 'title', label: 'عنوان العقار', type: 'text' },
{ id: 'description', label: 'الوصف', type: 'textarea' },
{
id: 'propertyType',
label: 'نوع العقار',
type: 'select',
options: [
{ value: 'apartment', label: 'شقة' },
{ value: 'villa', label: 'فيلا' },
{ value: 'suite', label: 'سويت' },
{ value: 'room', label: 'غرفة ضمن شقة' }
],
},
{
id: 'furnished',
label: 'حالة العقار',
type: 'radio',
options: [
{ value: true, label: 'مفروش' },
{ value: false, label: 'غير مفروش' }
],
}
]
},
{
title: 'التفاصيل',
fields: [
{ id: 'bedrooms', label: 'عدد الغرف', type: 'number' },
{ id: 'bathrooms', label: 'عدد الحمامات', type: 'number' },
{ id: 'livingRooms', label: 'عدد الصالونات', type: 'number' },
{ id: 'area', label: 'المساحة (م²)', type: 'number' }
]
},
{
title: 'الموقع',
fields: [
{ id: 'address', label: 'العنوان الكامل', type: 'text' },
{ id: 'city', label: 'المدينة', type: 'text' },
{ id: 'district', label: 'الحي', type: 'text' }
]
},
{
title: 'السعر',
fields: formData?.purpose === 'rent' ? [
{ id: 'dailyPrice', label: 'السعر اليومي', type: 'number' },
{ id: 'monthlyPrice', label: 'السعر الشهري', type: 'number' },
{
id: 'rentType',
label: 'نوع الإيجار',
type: 'select',
options: [
{ value: 'daily', label: 'يومي' },
{ value: 'monthly', label: 'شهري' },
{ value: 'both', label: 'يومي وشهري' }
],
}
] : [
{ id: 'salePrice', label: 'سعر البيع', type: 'number' }
]
}
];
const startEditing = (fieldId) => {
setEditingField(fieldId);
setTempValues({ ...tempValues, [fieldId]: formData[fieldId] });
};
const cancelEditing = () => {
setEditingField(null);
setTempValues({});
};
const saveField = (fieldId) => {
setFormData({
...formData,
[fieldId]: tempValues[fieldId]
});
setEditingField(null);
setTempValues({});
const fieldLabel = sections.flatMap(s => s.fields).find(f => f.id === fieldId)?.label;
toast.success(`تم تحديث ${fieldLabel}`);
};
const handleTempChange = (fieldId, value) => {
setTempValues({ ...tempValues, [fieldId]: value });
};
const handleSave = () => {
setIsSaving(true);
setTimeout(() => {
onSave(formData);
setIsSaving(false);
onClose();
toast.success('تم تحديث العقار بنجاح');
}, 1000);
};
if (!isOpen || !property) return null;
return (
e.stopPropagation()}
>
تعديل العقار
قم بتحديث معلومات العقار
{formData.images && formData.images.length > 0 && (
صور العقار
{formData.images.map((image, index) => (
))}
)}
{sections.map((section, sectionIndex) => (
{section.title}
{section.fields.map((field) => (
{editingField !== field.id && (
)}
{editingField === field.id ? (
{field.type === 'textarea' ? (
) : (
{field.type === 'select' ? (
field.options.find(opt => opt.value === formData[field.id])?.label || formData[field.id]
) : field.type === 'radio' ? (
formData[field.id] ? 'مفروش' : 'غير مفروش'
) : field.id.includes('Price') ? (
formData[field.id] ? `${Number(formData[field.id]).toLocaleString()} ل.س` : '—'
) : (
formData[field.id] || '—'
)}
)}
))}
))}
);
};
export default function OwnerPropertiesPage() {
const router = useRouter();
const [user, setUser] = useState(null);
const [properties, setProperties] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [showAddMenu, setShowAddMenu] = useState(false);
const [activeTab, setActiveTab] = useState('rent');
const [deleteModal, setDeleteModal] = useState({ isOpen: false, property: null });
const [viewModal, setViewModal] = useState({ isOpen: false, property: null });
const [editModal, setEditModal] = useState({ isOpen: false, property: null });
const filteredProperties = properties.filter(p => p.purpose === activeTab);
const rentCount = properties.filter(p => p.purpose === 'rent').length;
const saleCount = properties.filter(p => p.purpose === 'sale').length;
useEffect(() => {
const authUser = AuthService.getUser();
if (authUser && AuthService.isOwner()) {
setUser({
name: authUser.name || authUser.email,
email: authUser.email,
role: 'owner',
});
loadProperties();
} else {
router.push('/auth/choose-role');
}
}, [router]);
const loadProperties = async () => {
const authUser = AuthService.getUser();
const userId = authUser?.id;
if (!userId) {
console.warn('[OwnerProperties] No user ID found');
setIsLoading(false);
return;
}
try {
console.log('[OwnerProperties] Fetching listings for user:', userId);
const [rentData, saleData] = await Promise.allSettled([
getMyRentListings(),
getMySaleListings(),
]);
const rentList = rentData.status === 'fulfilled' ? (Array.isArray(rentData.value) ? rentData.value.filter(Boolean) : (rentData.value ? [rentData.value] : [])) : [];
const saleList = saleData.status === 'fulfilled' ? (Array.isArray(saleData.value) ? saleData.value.filter(Boolean) : (saleData.value ? [saleData.value] : [])) : [];
console.log('[OwnerProperties] Rent:', rentList.length, 'Sale:', saleList.length);
const mappedRent = rentList.map((item) => {
const info = item.propertyInformation || {};
const details = (() => { try { return JSON.parse(info.detailsJSON || '{}'); } catch { return {}; } })();
const apiBase = typeof window !== 'undefined' ? (process.env.NEXT_PUBLIC_API_URL || 'https://45.93.137.91.nip.io/api') : '';
const raw = Array.isArray(info.images) ? info.images : [];
return {
id: item.id,
title: info.address || `عقار #${item.id}`,
propertyType: { 0: 'apartment', 1: 'villa', 2: 'sweet', 3: 'room', 4: 'studio', 5: 'office', 6: 'farms', 7: 'shop', 8: 'warehouse' }[info.buildingType] || 'apartment',
propertyTypeLabel: { 0: 'شقة', 1: 'فيلا', 2: 'سويت', 3: 'غرفة', 4: 'استوديو', 5: 'مكتب', 6: 'مزرعة', 7: 'متجر', 8: 'مستودع' }[info.buildingType] || 'عقار',
purpose: 'rent',
rentType: item.rentType === 0 ? 'monthly' : item.rentType === 1 ? 'daily' : 'daily',
dailyPrice: item.dailyRent || 0,
monthlyPrice: item.monthlyRent || 0,
salePrice: item.price || 0,
deposit: item.deposit || 0,
location: info.address || '',
bedrooms: info.numberOfBedRooms || 0,
bathrooms: info.numberOfBathRooms || 0,
area: info.space || 0,
livingRooms: details.livingRooms || 0,
floor: details.floorNumber ?? details.floor ?? 0,
salons: details.numberOfSalons ?? details.salonsCount ?? details.salons ?? 0,
balconies: details.numberOfBalconies ?? details.balconiesCount ?? details.balconies ?? 0,
status: { 0: 'available', 1: 'booked', 2: 'maintenance' }[info.status] || 'available',
images: raw.length > 0 ? raw.map(img => img.startsWith('http') ? img : `${apiBase}${img.startsWith('/') ? '' : '/Pictures/'}${img}`) : ['/property-placeholder.jpg'],
createdAt: item.createdAt || new Date().toISOString(),
furnished: details.furnished || false,
description: info.description || '',
address: info.address || '',
city: '',
district: '',
services: details.services || {},
terms: details.terms || {},
rating: item.rating || 0,
currencyId: item.currencyId,
_raw: item,
};
});
const mappedSale = saleList.map((item) => {
const info = item.propertyInformation || {};
const details = (() => { try { return JSON.parse(info.detailsJSON || '{}'); } catch { return {}; } })();
const apiBase = typeof window !== 'undefined' ? (process.env.NEXT_PUBLIC_API_URL || 'https://45.93.137.91.nip.io/api') : '';
const raw = Array.isArray(info.images) ? info.images : [];
return {
id: item.id,
title: info.address || `عقار للبيع #${item.id}`,
propertyType: { 0: 'apartment', 1: 'villa', 2: 'sweet', 3: 'room', 4: 'studio', 5: 'office', 6: 'farms', 7: 'shop', 8: 'warehouse' }[info.buildingType] || 'apartment',
propertyTypeLabel: { 0: 'شقة', 1: 'فيلا', 2: 'سويت', 3: 'غرفة', 4: 'استوديو', 5: 'مكتب', 6: 'مزرعة', 7: 'متجر', 8: 'مستودع' }[info.buildingType] || 'عقار',
purpose: 'sale',
dailyPrice: 0,
monthlyPrice: 0,
salePrice: item.price || 0,
deposit: 0,
location: info.address || '',
bedrooms: info.numberOfBedRooms || 0,
bathrooms: info.numberOfBathRooms || 0,
area: info.space || 0,
livingRooms: details.livingRooms || 0,
floor: details.floorNumber ?? details.floor ?? 0,
salons: details.numberOfSalons ?? details.salonsCount ?? details.salons ?? 0,
balconies: details.numberOfBalconies ?? details.balconiesCount ?? details.balconies ?? 0,
status: 'available',
images: raw.length > 0 ? raw.map(img => img.startsWith('http') ? img : `${apiBase}${img.startsWith('/') ? '' : '/Pictures/'}${img}`) : ['/property-placeholder.jpg'],
createdAt: item.createdAt || new Date().toISOString(),
furnished: details.furnished || false,
description: info.description || '',
address: info.address || '',
city: '',
district: '',
services: details.services || {},
terms: details.terms || {},
rating: item.rating || 0,
currencyId: item.currencyId,
_raw: item,
};
});
setProperties([...mappedRent, ...mappedSale]);
} catch (err) {
console.error('[OwnerProperties] Failed to load properties:', err);
toast.error('فشل في تحميل العقارات');
} finally {
setIsLoading(false);
}
};
const updatePropertiesInStorage = (newProperties) => {
setProperties(newProperties);
localStorage.setItem('ownerProperties', JSON.stringify(newProperties));
};
const handleDelete = () => {
if (deleteModal.property) {
const newProperties = properties.filter(p => p.id !== deleteModal.property.id);
updatePropertiesInStorage(newProperties);
setDeleteModal({ isOpen: false, property: null });
toast.success('تم حذف العقار بنجاح');
}
};
const handleSaveEdit = async (updatedProperty) => {
try {
if (updatedProperty.purpose === 'rent' && updatedProperty._raw) {
const buildingTypeMap = { apartment: 0, villa: 1, sweet: 2, room: 3, studio: 4, office: 5, farms: 6, shop: 7, warehouse: 8 };
const raw = updatedProperty._raw;
const rentTypeMap = { daily: 1, monthly: 0, both: 0 };
const detailsJSON = JSON.stringify({
services: updatedProperty.services || {},
terms: updatedProperty.terms || {},
furnished: updatedProperty.furnished,
});
const payload = {
propertyInformation: {
cordsX: raw.propertyInformation?.cordsX || '',
cordsY: raw.propertyInformation?.cordsY || '',
address: updatedProperty.address || raw.propertyInformation?.address || '',
description: updatedProperty.description || raw.propertyInformation?.description || '',
numberOfBathRooms: updatedProperty.bathrooms || raw.propertyInformation?.numberOfBathRooms || 0,
numberOfRooms: (updatedProperty.bedrooms || 0) + (updatedProperty.livingRooms || 0),
numberOfBedRooms: updatedProperty.bedrooms || raw.propertyInformation?.numberOfBedRooms || 0,
space: parseFloat(updatedProperty.area) || raw.propertyInformation?.space || 0,
detailsJSON,
buildingType: buildingTypeMap[updatedProperty.propertyType] ?? 0,
status: updatedProperty.status === 'available' ? 0 : 1,
propertyType: updatedProperty.furnished ? 0 : 1,
images: raw.propertyInformation?.images || [],
},
deposit: parseFloat(updatedProperty.deposit) || raw.deposit || 0,
monthlyRent: parseFloat(updatedProperty.monthlyPrice) || raw.monthlyRent || 0,
dailyRent: parseFloat(updatedProperty.dailyPrice) || raw.dailyRent || 0,
rating: updatedProperty.rating || 0,
currencyId: updatedProperty.currencyId || raw.currencyId || 1,
rentType: rentTypeMap[updatedProperty.rentType] ?? 0,
isSmokeAllow: !updatedProperty.terms?.NoSmoking,
isVisitorAllow: !updatedProperty.terms?.NoParties,
type: updatedProperty.furnished ? 0 : 1,
};
await editRentProperty(updatedProperty.id, payload);
}
const newProperties = properties.map(p =>
p.id === updatedProperty.id ? updatedProperty : p
);
updatePropertiesInStorage(newProperties);
setEditModal({ isOpen: false, property: null });
toast.success('تم تحديث العقار بنجاح');
} catch (err) {
console.error('[OwnerProperties] Edit failed:', err);
toast.error('فشل تحديث العقار');
}
};
const fadeInUp = {
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
transition: { duration: 0.5 }
};
if (isLoading) {
return (
);
}
return (
setDeleteModal({ isOpen: false, property: null })}
onConfirm={handleDelete}
propertyTitle={deleteModal.property?.title}
/>
setViewModal({ isOpen: false, property: null })}
property={viewModal.property}
/>
setEditModal({ isOpen: false, property: null })}
property={editModal.property}
onSave={handleSaveEdit}
/>
عقاراتي
مرحباً {user?.name}، لديك {properties.length} عقار
setShowAddMenu(!showAddMenu)}
className="bg-gradient-to-r from-amber-500 to-amber-600 text-white px-6 py-3 rounded-xl font-medium flex items-center gap-2 shadow-lg hover:shadow-xl transition-all"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
إضافة عقار جديد
{showAddMenu && (
setShowAddMenu(false)}
>
عقار للإيجار
أضف عقار متاح للإيجار
setShowAddMenu(false)}
>
عقار للبيع
أضف عقار متاح للبيع
)}
{/* Tab Switcher */}
{filteredProperties.length === 0 ? (
{activeTab === 'rent' ? 'لا توجد عقارات للإيجار' : 'لا توجد عقارات للبيع'}
ابدأ بإضافة أول عقار {activeTab === 'rent' ? 'للإيجار' : 'للبيع'} الآن
إضافة عقار جديد
) : (
{filteredProperties.map((property, index) => (
{property.images && property.images.length > 0 ? (

) : (
)}
{property.status === 'available' ? 'متاح' : 'مؤجر'}
{property.purpose === 'rent' && property.furnished !== undefined && (
{property.furnished ? 'مفروش' : 'غير مفروش'}
)}
{property.propertyTypeLabel || (property.propertyType === 'apartment' ? 'شقة' : property.propertyType === 'villa' ? 'فيلا' : property.propertyType === 'sweet' ? 'سويت' : property.propertyType === 'room' ? 'غرفة' : property.propertyType === 'studio' ? 'استوديو' : property.propertyType === 'office' ? 'مكتب' : property.propertyType === 'farms' ? 'مزرعة' : property.propertyType === 'shop' ? 'متجر' : property.propertyType === 'warehouse' ? 'مستودع' : 'عقار')}
{property.title}
{property.rating > 0 && (
{Number(property.rating).toFixed(1)}
)}
{property.address || property.location || 'موقع غير محدد'}
{property.bedrooms > 0 && (
{property.bedrooms}
)}
{property.bathrooms > 0 && (
{property.bathrooms}
)}
{property.area > 0 && (
{property.area}م²
)}
{property.floor > 0 && (
ط {property.floor}
)}
{property.salons > 0 && (
{property.salons}
)}
{property.balconies > 0 && (
{property.balconies}
)}
{property.purpose === 'rent' ? (
{property.monthlyPrice > 0 && (
{Number(property.monthlyPrice).toLocaleString()}
ل.س /شهر
)}
{property.dailyPrice > 0 && !property.monthlyPrice && (
{Number(property.dailyPrice).toLocaleString()}
ل.س /يوم
)}
{property.deposit > 0 && (
تأمين: {Number(property.deposit).toLocaleString()} ل.س
)}
) : (
{Number(property.salePrice).toLocaleString()} ل.س
)}
))}
)}
);
}