160 lines
4.1 KiB
JavaScript
160 lines
4.1 KiB
JavaScript
"use client";
|
|
|
|
import { createContext, useContext, useState, useCallback } from "react";
|
|
|
|
const PropertyContext = createContext();
|
|
|
|
export const useProperties = () => {
|
|
const context = useContext(PropertyContext);
|
|
if (!context) {
|
|
throw new Error("useProperties must be used within PropertyProvider");
|
|
}
|
|
return context;
|
|
};
|
|
|
|
export const PropertyProvider = ({ children }) => {
|
|
const [properties, setProperties] = useState([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState(null);
|
|
|
|
const addProperty = useCallback(async (propertyData) => {
|
|
setLoading(true);
|
|
try {
|
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
|
|
const newProperty = {
|
|
id: Date.now().toString(),
|
|
...propertyData,
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
bookings: [],
|
|
status: propertyData.status || "available",
|
|
};
|
|
|
|
setProperties((prev) => [...prev, newProperty]);
|
|
return newProperty;
|
|
} catch (err) {
|
|
setError(err.message);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const updateProperty = useCallback(async (id, updates) => {
|
|
setLoading(true);
|
|
try {
|
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
|
|
setProperties((prev) =>
|
|
prev.map((p) =>
|
|
p.id === id
|
|
? { ...p, ...updates, updatedAt: new Date().toISOString() }
|
|
: p,
|
|
),
|
|
);
|
|
} catch (err) {
|
|
setError(err.message);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const deleteProperty = useCallback(async (id) => {
|
|
setLoading(true);
|
|
try {
|
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
setProperties((prev) => prev.filter((p) => p.id !== id));
|
|
} catch (err) {
|
|
setError(err.message);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const getProperty = useCallback(
|
|
(id) => {
|
|
return properties.find((p) => p.id === id);
|
|
},
|
|
[properties],
|
|
);
|
|
|
|
const checkAvailability = useCallback(
|
|
(propertyId, startDate, endDate) => {
|
|
const property = properties.find((p) => p.id === propertyId);
|
|
if (!property) return false;
|
|
|
|
const checkStart = new Date(startDate);
|
|
const checkEnd = new Date(endDate);
|
|
|
|
return !property.bookings?.some((booking) => {
|
|
if (booking.status === "cancelled" || booking.status === "rejected") {
|
|
return false;
|
|
}
|
|
|
|
const bookingStart = new Date(booking.startDate);
|
|
const bookingEnd = new Date(booking.endDate);
|
|
|
|
return (
|
|
(checkStart >= bookingStart && checkStart <= bookingEnd) ||
|
|
(checkEnd >= bookingStart && checkEnd <= bookingEnd) ||
|
|
(checkStart <= bookingStart && checkEnd >= bookingEnd)
|
|
);
|
|
});
|
|
},
|
|
[properties],
|
|
);
|
|
|
|
const getPropertiesByOwner = useCallback(
|
|
(ownerId) => {
|
|
return properties.filter((p) => p.ownerId === ownerId);
|
|
},
|
|
[properties],
|
|
);
|
|
|
|
const getAvailableProperties = useCallback(() => {
|
|
return properties.filter((p) => p.status === "available");
|
|
}, [properties]);
|
|
|
|
const updatePropertyStatus = useCallback(
|
|
async (id, status) => {
|
|
return updateProperty(id, { status });
|
|
},
|
|
[updateProperty],
|
|
);
|
|
|
|
const addBookingToProperty = useCallback(
|
|
async (propertyId, bookingData) => {
|
|
const property = getProperty(propertyId);
|
|
if (!property) throw new Error("Property not found");
|
|
|
|
const updatedBookings = [...(property.bookings || []), bookingData];
|
|
return updateProperty(propertyId, { bookings: updatedBookings });
|
|
},
|
|
[getProperty, updateProperty],
|
|
);
|
|
|
|
return (
|
|
<PropertyContext.Provider
|
|
value={{
|
|
properties,
|
|
loading,
|
|
error,
|
|
addProperty,
|
|
updateProperty,
|
|
deleteProperty,
|
|
getProperty,
|
|
checkAvailability,
|
|
getPropertiesByOwner,
|
|
getAvailableProperties,
|
|
updatePropertyStatus,
|
|
addBookingToProperty,
|
|
}}
|
|
>
|
|
{children}
|
|
</PropertyContext.Provider>
|
|
);
|
|
};
|