"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.bookedCount > 0 && (
{property.bookedCount}
حجوزات
)}
الموقع
{property.address || "لم يتم تحديد العنوان"}
{property.city && `، ${property.city}`}
{property.district && `، ${property.district}`}
{property.services &&
(Array.isArray(property.services)
? property.services.length > 0
: Object.keys(property.services).length > 0) && (
الخدمات المتوفرة
{Array.isArray(property.services)
? property.services.map((svc, i) => (
{serviceLabels[svc] || svc}
))
: Object.entries(property.services).map(([key, value]) => {
if (!value) return null;
const detail =
typeof value === "object" && value.detail
? value.detail
: typeof value === "string"
? value
: 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] || "—"}
)}
))}
))}
الخدمات
{Object.entries(formData.services || {}).map(([key, value]) => {
const serviceLabels = {
electricity: "كهرباء",
internet: "انترنت",
heating: "تدفئة",
water: "ماء",
airConditioning: "تكييف",
parking: "موقف سيارات",
elevator: "مصعد",
};
return (
);
})}
شروط الاستخدام
{Object.entries(formData.terms || {}).map(([key, value]) => {
const termLabels = {
noSmoking: " ممنوع التدخين",
noPets: " ممنوع الحيوانات",
noParties: " ممنوع الحفلات",
noAlcohol: " ممنوع الكحول",
suitableForChildren: " مناسب للأطفال",
suitableForElderly: " مناسب لكبار السن",
};
return (
);
})}
);
};
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 normalizeServices = (details) => {
const rawServices = details.services || {};
const serviceList = Array.isArray(rawServices)
? rawServices
: Object.keys(rawServices).filter((k) => rawServices[k]);
const serviceDetails = details.serviceDetails || {};
const services = {};
serviceList.forEach((s) => {
services[s] = serviceDetails[s] || true;
});
return services;
};
const normalizeTerms = (terms) => {
if (!terms) return {};
return Array.isArray(terms)
? terms.reduce((acc, t) => ({ ...acc, [t]: true }), {})
: terms;
};
const normalizeProximity = (prox) => {
if (!prox) return {};
const result = {};
Object.entries(prox).forEach(([k, v]) => {
if (!v) return;
result[k.charAt(0).toUpperCase() + k.slice(1)] = v;
});
return result;
};
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,
bookedCount: details.bookedCount || 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: normalizeServices(details),
terms: normalizeTerms(details.terms),
proximity: normalizeProximity(details.nearbyDistances),
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,
bookedCount: details.bookedCount || 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: normalizeServices(details),
terms: normalizeTerms(details.terms),
proximity: normalizeProximity(details.nearbyDistances),
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 rawServices = updatedProperty.services || {};
const serviceList = Array.isArray(rawServices)
? rawServices
: Object.keys(rawServices).filter((k) => rawServices[k]);
const details = {
services: serviceList,
serviceDetails: updatedProperty.serviceDetails || {},
terms: normalizeTerms(updatedProperty.terms),
displayType: "Both",
propertyCondition: updatedProperty.furnished
? "WithFurniture"
: "WithoutFurniture",
};
const detailsJSON = JSON.stringify(details);
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,
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: 1,
currencyId: updatedProperty.currencyId || raw.currencyId || 1,
rentType: rentTypeMap[updatedProperty.rentType] ?? 0,
type: updatedProperty.furnished ? 0 : 1,
allowedPaymentPeriod: "01:00:00:00",
};
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()} ل.س
)}
))}
)}
);
}