fixed the logic and build the ownerResirvation page
All checks were successful
Build frontend / build (push) Successful in 1m36s
All checks were successful
Build frontend / build (push) Successful in 1m36s
This commit is contained in:
@ -6,7 +6,7 @@ import { useRouter } from "next/navigation";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Calendar, User, Mail, Phone, CheckCircle, XCircle, Clock, MapPin, Bed, Bath, Square, CalendarDays, ChevronLeft, ChevronRight, Eye, Loader2, Search } from "lucide-react";
|
import { Calendar, User, Mail, Phone, CheckCircle, XCircle, Clock, MapPin, Bed, Bath, Square, CalendarDays, ChevronLeft, ChevronRight, Eye, Loader2, Search } from "lucide-react";
|
||||||
import toast, { Toaster } from "react-hot-toast";
|
import toast, { Toaster } from "react-hot-toast";
|
||||||
import { getMyRentListings, getOwnerReservationRequests } from "@/app/utils/api";
|
import { getRentProperty, getOwnerReservationsByStatuses, getRentProperties } from "@/app/utils/api";
|
||||||
import useAuth from "@/app/hooks/useAuth";
|
import useAuth from "@/app/hooks/useAuth";
|
||||||
import Loading from "@/app/loading";
|
import Loading from "@/app/loading";
|
||||||
|
|
||||||
@ -383,22 +383,63 @@ export default function OwnerBookingsPage() {
|
|||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await getOwnerReservationRequests();
|
const [response, rentProps] = await Promise.all([getOwnerReservationsByStatuses([0, 1, 2, 3, 4]), getRentProperties().catch(() => [])]);
|
||||||
|
|
||||||
let rawData = response;
|
let rawData = response;
|
||||||
|
|
||||||
if (response && response.data) {
|
if (response && response.data) {
|
||||||
rawData = response.data;
|
rawData = response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// تحويل البيانات إلى مصفوفة وتصفية العناصر الفارغة (null أو undefined)
|
|
||||||
const rawList = Array.isArray(rawData) ? rawData : rawData ? [rawData] : [];
|
const rawList = Array.isArray(rawData) ? rawData : rawData ? [rawData] : [];
|
||||||
|
|
||||||
const list = rawList.filter(Boolean);
|
const list = rawList.filter(Boolean);
|
||||||
|
|
||||||
const mappedBookings = list.map((item) => {
|
// Rent properties
|
||||||
|
const propsList = Array.isArray(rentProps) ? rentProps : [];
|
||||||
|
|
||||||
|
// مهم: تعريف propMap هون
|
||||||
|
const propMap = {};
|
||||||
|
|
||||||
|
propsList.forEach((rp) => {
|
||||||
|
const info = rp?.propertyInformation ?? {};
|
||||||
|
|
||||||
|
const propertyData = {
|
||||||
|
...info,
|
||||||
|
|
||||||
|
// إذا كانت موجودة داخل rp
|
||||||
|
dailyRent: rp?.dailyRent,
|
||||||
|
monthlyRent: rp?.monthlyRent,
|
||||||
|
deposit: rp?.deposit,
|
||||||
|
|
||||||
|
allowedPaymentPeriod: rp?.allowedPaymentPeriod,
|
||||||
|
};
|
||||||
|
|
||||||
|
propMap[rp.propertyInformationId] = propertyData;
|
||||||
|
propMap[rp.propertyInformation?.id] = propertyData;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("PROP MAP:", propMap);
|
||||||
|
|
||||||
|
// ربط الـ reservation بالعقار عن طريق propertyId
|
||||||
|
const enriched = list.map((item) => {
|
||||||
|
if (item.propertyId && propMap[item.propertyId]) {
|
||||||
|
item._prop = propMap[item.propertyId];
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("ENRICHED BOOKINGS:", enriched);
|
||||||
|
|
||||||
|
const mappedBookings = enriched.map((item) => {
|
||||||
|
const property = item._prop || {};
|
||||||
|
|
||||||
let parsedDetails = {};
|
let parsedDetails = {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (item?.propertyInformation?.detailsJSON) {
|
if (property?.detailsJSON) {
|
||||||
parsedDetails = JSON.parse(item.propertyInformation.detailsJSON);
|
parsedDetails = JSON.parse(property.detailsJSON);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error parsing detailsJSON", e);
|
console.error("Error parsing detailsJSON", e);
|
||||||
@ -406,31 +447,48 @@ export default function OwnerBookingsPage() {
|
|||||||
|
|
||||||
const statusMap = {
|
const statusMap = {
|
||||||
0: "pending",
|
0: "pending",
|
||||||
1: "confirmed",
|
1: "pending",
|
||||||
2: "completed",
|
2: "confirmed",
|
||||||
3: "cancelled",
|
3: "completed",
|
||||||
|
4: "cancelled",
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusKey = statusMap[item?.propertyInformation?.status] || "pending";
|
const statusKey = statusMap[item?.status] || "pending";
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: item?.id,
|
id: item?.id,
|
||||||
dailyRent: item?.dailyRent,
|
|
||||||
monthlyRent: item?.monthlyRent,
|
propertyId: item?.propertyId,
|
||||||
deposit: item?.deposit,
|
|
||||||
|
// هون صاروا ياخدوا من property
|
||||||
|
dailyRent: property?.dailyRent || 0,
|
||||||
|
monthlyRent: property?.monthlyRent || 0,
|
||||||
|
deposit: property?.deposit || 0,
|
||||||
|
|
||||||
createdAt: item?.createdAt,
|
createdAt: item?.createdAt,
|
||||||
startDate: item?.createdAt?.split("T")[0],
|
|
||||||
|
startDate: item?.startDate?.split("T")[0],
|
||||||
|
endDate: item?.endDate?.split("T")[0],
|
||||||
|
|
||||||
status: statusKey,
|
status: statusKey,
|
||||||
propertyTitle: parsedDetails.description || `${t("property")} #${item?.id}`,
|
|
||||||
location: item?.propertyInformation?.address || "",
|
propertyTitle: parsedDetails.description || `${t("property")} #${item?.propertyId}`,
|
||||||
images: item?.propertyInformation?.images || [],
|
|
||||||
|
location: property?.address || "",
|
||||||
|
|
||||||
|
images: property?.images || [],
|
||||||
|
|
||||||
propertyDetails: {
|
propertyDetails: {
|
||||||
bedrooms: item?.propertyInformation?.numberOfBedRooms || 0,
|
bedrooms: property?.numberOfBedRooms || 0,
|
||||||
bathrooms: item?.propertyInformation?.numberOfBathRooms || 0,
|
bathrooms: property?.numberOfBathRooms || 0,
|
||||||
salons: item?.propertyInformation?.numberOfSalons || 0,
|
salons: property?.numberOfSalons || 0,
|
||||||
area: item?.propertyInformation?.space || 0,
|
area: property?.space || 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
propertyInformation: property,
|
||||||
|
|
||||||
parsedDetails,
|
parsedDetails,
|
||||||
|
|
||||||
tenantName: item?.tenantName || null,
|
tenantName: item?.tenantName || null,
|
||||||
tenantPhone: item?.tenantPhone || null,
|
tenantPhone: item?.tenantPhone || null,
|
||||||
tenantEmail: item?.tenantEmail || null,
|
tenantEmail: item?.tenantEmail || null,
|
||||||
@ -476,9 +534,7 @@ export default function OwnerBookingsPage() {
|
|||||||
}, [bookings]);
|
}, [bookings]);
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return <Loading />;
|
||||||
<Loading/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -678,7 +678,6 @@ export default function PropertiesPage() {
|
|||||||
const saleList = Array.isArray(saleData) ? saleData : [];
|
const saleList = Array.isArray(saleData) ? saleData : [];
|
||||||
|
|
||||||
const mapped = [...rentList.map((p, i) => ({ ...mapApiProperty(t, p, i), purpose: "rent" })), ...saleList.map((p, i) => ({ ...mapApiProperty(t, p, rentList.length + i), purpose: "sale" }))];
|
const mapped = [...rentList.map((p, i) => ({ ...mapApiProperty(t, p, i), purpose: "rent" })), ...saleList.map((p, i) => ({ ...mapApiProperty(t, p, rentList.length + i), purpose: "sale" }))];
|
||||||
|
|
||||||
setProperties(mapped);
|
setProperties(mapped);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("[Properties] Failed to fetch properties:", err);
|
console.error("[Properties] Failed to fetch properties:", err);
|
||||||
@ -691,7 +690,9 @@ export default function PropertiesPage() {
|
|||||||
}, [filters, t]);
|
}, [filters, t]);
|
||||||
|
|
||||||
const filteredProperties = properties
|
const filteredProperties = properties
|
||||||
|
// العقارات يلي 0 ما تنعرض
|
||||||
.filter((p) => p.purpose === purposeTab)
|
.filter((p) => p.purpose === purposeTab)
|
||||||
|
.filter((p) => p.purpose === "rent" || p.status === 1)
|
||||||
.filter((property) => {
|
.filter((property) => {
|
||||||
if (filters.search && !property.title.includes(filters.search) && !property.description.includes(filters.search)) {
|
if (filters.search && !property.title.includes(filters.search) && !property.description.includes(filters.search)) {
|
||||||
return false;
|
return false;
|
||||||
@ -785,9 +786,12 @@ export default function PropertiesPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={viewMode === "grid" ? "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" : "space-y-4"}>
|
<div className={viewMode === "grid" ? "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" : "space-y-4"}>
|
||||||
{filteredProperties.map((property) => (
|
{/* شرط مشان ينعرض او لا */}
|
||||||
<PropertyCard key={property.id} property={property} viewMode={viewMode} type={property.purpose} onLoginRequired={() => setShowLoginDialog(true)} />
|
{filteredProperties.map((property) =>
|
||||||
))}
|
property.purpose === "rent" || property.status === 1 ? (
|
||||||
|
<PropertyCard key={property.id} property={property} viewMode={viewMode} type={property.purpose} onLoginRequired={() => setShowLoginDialog(true)} />
|
||||||
|
) : null,
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!loading && filteredProperties.length === 0 && (
|
{!loading && filteredProperties.length === 0 && (
|
||||||
|
|||||||
@ -502,9 +502,6 @@ const getAuthToken = () => {
|
|||||||
return (
|
return (
|
||||||
AuthService.getToken?.() ||
|
AuthService.getToken?.() ||
|
||||||
AuthService.getAccessToken?.() ||
|
AuthService.getAccessToken?.() ||
|
||||||
localStorage.getItem("token") ||
|
|
||||||
localStorage.getItem("accessToken") ||
|
|
||||||
localStorage.getItem("authToken") ||
|
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -663,6 +660,7 @@ function CountdownTimer({ deadline }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
function PaymentDialog({
|
function PaymentDialog({
|
||||||
isOpen,
|
isOpen,
|
||||||
reservation,
|
reservation,
|
||||||
@ -940,7 +938,7 @@ function PaymentDialog({
|
|||||||
)}
|
)}
|
||||||
</motion.button>
|
</motion.button>
|
||||||
</div>
|
</div>
|
||||||
|
{/* // */}
|
||||||
{/* Pay Cash button - commented out */}
|
{/* Pay Cash button - commented out */}
|
||||||
{/* <div className="px-6 py-4 border-b border-gray-100">
|
{/* <div className="px-6 py-4 border-b border-gray-100">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -222,6 +222,9 @@ export async function getReservations() {
|
|||||||
return apiFetch("/Reservations/GetAllReservations");
|
return apiFetch("/Reservations/GetAllReservations");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export async function getReservation(id) {
|
export async function getReservation(id) {
|
||||||
return apiFetch(`/Reservations/GetReservation?id=${id}`);
|
return apiFetch(`/Reservations/GetReservation?id=${id}`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user