edited middle ware and calender component
This commit is contained in:
246
app/components/property/DateSelectionCalendar.js
Normal file
246
app/components/property/DateSelectionCalendar.js
Normal file
@ -0,0 +1,246 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ChevronRight, ChevronLeft } from "lucide-react";
|
||||
|
||||
const MONTH_KEYS = [
|
||||
"month.january",
|
||||
"month.february",
|
||||
"month.march",
|
||||
"month.april",
|
||||
"month.may",
|
||||
"month.june",
|
||||
"month.july",
|
||||
"month.august",
|
||||
"month.september",
|
||||
"month.october",
|
||||
"month.november",
|
||||
"month.december",
|
||||
];
|
||||
|
||||
const DAY_KEYS = [
|
||||
"dayAbbr.sun",
|
||||
"dayAbbr.mon",
|
||||
"dayAbbr.tue",
|
||||
"dayAbbr.wed",
|
||||
"dayAbbr.thu",
|
||||
"dayAbbr.fri",
|
||||
"dayAbbr.sat",
|
||||
];
|
||||
|
||||
export default function DateSelectionCalendar({
|
||||
mode,
|
||||
availableDates,
|
||||
selectedStart,
|
||||
selectedEnd,
|
||||
onSelectStart,
|
||||
onSelectEnd,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [calendarMonth, setCalendarMonth] = useState(() => new Date().getMonth());
|
||||
const [calendarYear, setCalendarYear] = useState(() => new Date().getFullYear());
|
||||
const [rangeError, setRangeError] = useState(null);
|
||||
|
||||
const isPastDate = useCallback((dateStr) => {
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
return new Date(dateStr) < today;
|
||||
}, []);
|
||||
|
||||
const isDateAvailable = useCallback(
|
||||
(dateStr) => (availableDates ? availableDates.has(dateStr) : true),
|
||||
[availableDates]
|
||||
);
|
||||
|
||||
const isMonthFullyAvailable = useCallback(
|
||||
(year, monthIdx) => {
|
||||
const daysInMonth = new Date(year, monthIdx + 1, 0).getDate();
|
||||
for (let day = 1; day <= daysInMonth; day++) {
|
||||
const dateStr = `${year}-${String(monthIdx + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
||||
if (isPastDate(dateStr) || !isDateAvailable(dateStr)) return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[isPastDate, isDateAvailable]
|
||||
);
|
||||
|
||||
const isPastMonth = useCallback((year, monthIdx) => {
|
||||
const now = new Date();
|
||||
return (
|
||||
year < now.getFullYear() ||
|
||||
(year === now.getFullYear() && monthIdx < now.getMonth())
|
||||
);
|
||||
}, []);
|
||||
|
||||
const handleDayClick = (dateStr) => {
|
||||
setRangeError(null);
|
||||
if (!selectedStart || selectedEnd) {
|
||||
onSelectStart(dateStr);
|
||||
onSelectEnd(null);
|
||||
return;
|
||||
}
|
||||
if (new Date(dateStr) <= new Date(selectedStart)) {
|
||||
onSelectStart(dateStr);
|
||||
onSelectEnd(null);
|
||||
return;
|
||||
}
|
||||
const start = new Date(selectedStart);
|
||||
const end = new Date(dateStr);
|
||||
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
|
||||
const ds = d.toISOString().split("T")[0];
|
||||
if (!isDateAvailable(ds)) {
|
||||
setRangeError(t("unavailableInRange", { defaultValue: "توجد أيام غير متاحة ضمن الفترة المحددة" }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
onSelectEnd(dateStr);
|
||||
};
|
||||
|
||||
const handleMonthClick = (year, monthIdx) => {
|
||||
setRangeError(null);
|
||||
const monthStr = `${year}-${String(monthIdx + 1).padStart(2, "0")}`;
|
||||
const firstDay = `${monthStr}-01`;
|
||||
if (!selectedStart || selectedEnd || monthStr <= (selectedStart || "").substring(0, 7)) {
|
||||
onSelectStart(firstDay);
|
||||
onSelectEnd(null);
|
||||
} else {
|
||||
const lastDay = new Date(year, monthIdx + 1, 0).getDate();
|
||||
onSelectEnd(`${monthStr}-${String(lastDay).padStart(2, "0")}`);
|
||||
}
|
||||
};
|
||||
|
||||
const navigateMonth = (delta) => {
|
||||
let month = calendarMonth + delta;
|
||||
let year = calendarYear;
|
||||
if (month < 0) {
|
||||
month = 11;
|
||||
year--;
|
||||
}
|
||||
if (month > 11) {
|
||||
month = 0;
|
||||
year++;
|
||||
}
|
||||
setCalendarMonth(month);
|
||||
setCalendarYear(year);
|
||||
};
|
||||
|
||||
const isEntryStep = !selectedStart || !!selectedEnd;
|
||||
|
||||
return (
|
||||
<div className="mb-3">
|
||||
{/* Step Indicator */}
|
||||
<div className="flex items-center justify-center gap-2 mb-3">
|
||||
<div
|
||||
className={`flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium ${isEntryStep ? "bg-amber-100 text-amber-800" : "bg-gray-100 text-gray-500"}`}
|
||||
>
|
||||
<div className={`w-1.5 h-1.5 rounded-full ${isEntryStep ? "bg-amber-500" : "bg-gray-400"}`} />
|
||||
{t("selectStartDate")}
|
||||
</div>
|
||||
<div className="text-gray-300 text-xs">←</div>
|
||||
<div className={`flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium ${!isEntryStep ? "bg-amber-100 text-amber-800" : "bg-gray-100 text-gray-500"}`}>
|
||||
<div className={`w-1.5 h-1.5 rounded-full ${!isEntryStep ? "bg-amber-500" : "bg-gray-400"}`} />
|
||||
{t("selectEndDate")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{mode === "daily" ? (
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<button onClick={() => navigateMonth(-1)} className="p-1 rounded-lg hover:bg-gray-100 transition-colors">
|
||||
<ChevronRight className="w-4 h-4 text-gray-600" />
|
||||
</button>
|
||||
<span className="text-sm font-bold text-gray-900">
|
||||
{t(MONTH_KEYS[calendarMonth])} {calendarYear}
|
||||
</span>
|
||||
<button onClick={() => navigateMonth(1)} className="p-1 rounded-lg hover:bg-gray-100 transition-colors">
|
||||
<ChevronLeft className="w-4 h-4 text-gray-600" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-7 mb-1">
|
||||
{DAY_KEYS.map((dk, i) => (
|
||||
<div key={i} className="text-center text-[10px] text-gray-400 font-medium py-1">
|
||||
{t(dk)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{(() => {
|
||||
const firstDay = new Date(calendarYear, calendarMonth, 1).getDay();
|
||||
const daysInMonth = new Date(calendarYear, calendarMonth + 1, 0).getDate();
|
||||
const cells = [];
|
||||
for (let i = 0; i < firstDay; i++) {
|
||||
cells.push(<div key={`e-${i}`} />);
|
||||
}
|
||||
for (let day = 1; day <= daysInMonth; day++) {
|
||||
const dateStr = `${calendarYear}-${String(calendarMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
||||
const past = isPastDate(dateStr);
|
||||
const available = isDateAvailable(dateStr);
|
||||
const isSelStart = dateStr === selectedStart;
|
||||
const isSelEnd = dateStr === selectedEnd;
|
||||
const inRange =
|
||||
selectedStart &&
|
||||
selectedEnd &&
|
||||
new Date(dateStr) > new Date(selectedStart) &&
|
||||
new Date(dateStr) < new Date(selectedEnd);
|
||||
const disabled = past || !available;
|
||||
cells.push(
|
||||
<button
|
||||
key={dateStr}
|
||||
onClick={() => !disabled && handleDayClick(dateStr)}
|
||||
disabled={disabled}
|
||||
className={`text-center py-1.5 text-xs rounded-lg transition-all ${disabled ? "text-gray-300 cursor-not-allowed" : ""} ${isSelStart || isSelEnd ? "bg-amber-500 text-white font-bold shadow-sm" : ""} ${inRange ? "bg-amber-100 text-amber-800" : ""} ${!disabled && !isSelStart && !isSelEnd && !inRange && available ? "hover:bg-amber-50 text-gray-700" : ""} ${!disabled && !isSelStart && !isSelEnd && !inRange && !available ? "text-red-300" : ""}`}
|
||||
>
|
||||
{day}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
return <div className="grid grid-cols-7 gap-0.5">{cells}</div>;
|
||||
})()}
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<button onClick={() => setCalendarYear((prev) => prev - 1)} className="p-1 rounded-lg hover:bg-gray-100 transition-colors">
|
||||
<ChevronRight className="w-4 h-4 text-gray-600" />
|
||||
</button>
|
||||
<span className="text-sm font-bold text-gray-900">{calendarYear}</span>
|
||||
<button onClick={() => setCalendarYear((prev) => prev + 1)} className="p-1 rounded-lg hover:bg-gray-100 transition-colors">
|
||||
<ChevronLeft className="w-4 h-4 text-gray-600" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
{MONTH_KEYS.map((mk, idx) => {
|
||||
const monthStr = `${calendarYear}-${String(idx + 1).padStart(2, "0")}`;
|
||||
const isSelStart = selectedStart && selectedStart.startsWith(monthStr);
|
||||
const isSelEnd = selectedEnd && selectedEnd.startsWith(monthStr);
|
||||
const inRange =
|
||||
selectedStart &&
|
||||
selectedEnd &&
|
||||
monthStr > selectedStart.substring(0, 7) &&
|
||||
monthStr < selectedEnd.substring(0, 7);
|
||||
const disabled = isPastMonth(calendarYear, idx) || !isMonthFullyAvailable(calendarYear, idx);
|
||||
return (
|
||||
<button
|
||||
key={idx}
|
||||
onClick={() => !disabled && handleMonthClick(calendarYear, idx)}
|
||||
disabled={disabled}
|
||||
className={`p-2.5 rounded-xl text-center text-xs font-medium transition-all border ${disabled ? "text-gray-300 border-gray-100 bg-gray-50 cursor-not-allowed" : ""} ${isSelStart || isSelEnd ? "bg-amber-500 text-white border-amber-500 shadow-sm" : ""} ${!disabled && inRange ? "bg-amber-100 text-amber-800 border-amber-200" : ""} ${!disabled && !isSelStart && !isSelEnd && !inRange ? "bg-white text-gray-700 border-gray-200 hover:border-amber-300" : ""}`}
|
||||
>
|
||||
{t(mk)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{rangeError && (
|
||||
<div className="bg-red-50 text-red-600 p-2.5 rounded-xl text-xs mt-3">
|
||||
{rangeError}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -60,6 +60,7 @@ import AuthService from "../../services/AuthService";
|
||||
import { useFavorites } from "@/app/contexts/FavoritesContext";
|
||||
import { BuildingTypeKeys, PropertyStatusKeys, extractCity } from "../../enums";
|
||||
import PropertyRatingList from "@/app/components/ratings/PropertyRatingList";
|
||||
import DateSelectionCalendar from "@/app/components/property/DateSelectionCalendar";
|
||||
import { getPropertyAverageRating } from "../../utils/ratings";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
import Loading from "@/app/loading";
|
||||
@ -257,11 +258,8 @@ export default function PropertyDetailsPage() {
|
||||
const [bookingError, setBookingError] = useState(null);
|
||||
const [bookingSuccess, setBookingSuccess] = useState(false);
|
||||
const [availableRanges, setAvailableRanges] = useState([]);
|
||||
const [bookingStep, setBookingStep] = useState("entry");
|
||||
const [selectedStart, setSelectedStart] = useState(null);
|
||||
const [selectedEnd, setSelectedEnd] = useState(null);
|
||||
const [calendarMonth, setCalendarMonth] = useState(() => new Date().getMonth());
|
||||
const [calendarYear, setCalendarYear] = useState(() => new Date().getFullYear());
|
||||
const [pricingMode, setPricingMode] = useState("daily");
|
||||
const [isOwnProperty, setIsOwnProperty] = useState(false);
|
||||
const [favLoading, setFavLoading] = useState(false);
|
||||
@ -402,22 +400,6 @@ export default function PropertyDetailsPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const MONTH_KEYS = [
|
||||
"month.january",
|
||||
"month.february",
|
||||
"month.march",
|
||||
"month.april",
|
||||
"month.may",
|
||||
"month.june",
|
||||
"month.july",
|
||||
"month.august",
|
||||
"month.september",
|
||||
"month.october",
|
||||
"month.november",
|
||||
"month.december",
|
||||
];
|
||||
const DAY_KEYS = ["dayAbbr.sun", "dayAbbr.mon", "dayAbbr.tue", "dayAbbr.wed", "dayAbbr.thu", "dayAbbr.fri", "dayAbbr.sat"];
|
||||
|
||||
const availableDatesSet = useMemo(() => {
|
||||
const dates = new Set();
|
||||
if (!Array.isArray(availableRanges)) return dates;
|
||||
@ -431,30 +413,6 @@ export default function PropertyDetailsPage() {
|
||||
return dates;
|
||||
}, [availableRanges]);
|
||||
|
||||
const isDateAvailable = (dateStr) => availableDatesSet.has(dateStr);
|
||||
const isPastDate = (dateStr) => {
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
return new Date(dateStr) < today;
|
||||
};
|
||||
|
||||
const handleDayClick = (dateStr) => {
|
||||
if (bookingStep === "entry") {
|
||||
setSelectedStart(dateStr);
|
||||
setSelectedEnd(null);
|
||||
setBookingStep("exit");
|
||||
} else {
|
||||
if (new Date(dateStr) <= new Date(selectedStart)) {
|
||||
setSelectedStart(dateStr);
|
||||
setSelectedEnd(null);
|
||||
setBookingStep("exit");
|
||||
} else {
|
||||
setSelectedEnd(dateStr);
|
||||
setBookingStep("entry");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleBookingConfirm = async () => {
|
||||
if (!AuthService.isAuthenticated()) {
|
||||
setShowLoginDialog(true);
|
||||
@ -480,21 +438,6 @@ export default function PropertyDetailsPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const navigateMonth = (delta) => {
|
||||
let month = calendarMonth + delta;
|
||||
let year = calendarYear;
|
||||
if (month < 0) {
|
||||
month = 11;
|
||||
year--;
|
||||
}
|
||||
if (month > 11) {
|
||||
month = 0;
|
||||
year++;
|
||||
}
|
||||
setCalendarMonth(month);
|
||||
setCalendarYear(year);
|
||||
};
|
||||
|
||||
const handleRatingSuccess = () => {
|
||||
setShowRatingForm(false);
|
||||
if (property) fetchAvgRating(property.id);
|
||||
@ -1028,115 +971,18 @@ export default function PropertyDetailsPage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Step Indicator */}
|
||||
<div className="flex items-center justify-center gap-2 mb-3">
|
||||
<div
|
||||
className={`flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium ${bookingStep === "entry" ? "bg-amber-100 text-amber-800" : "bg-gray-100 text-gray-500"}`}
|
||||
>
|
||||
<div className={`w-1.5 h-1.5 rounded-full ${bookingStep === "entry" ? "bg-amber-500" : "bg-gray-400"}`} />
|
||||
{t("selectStartDate")}
|
||||
</div>
|
||||
<div className="text-gray-300 text-xs">←</div>
|
||||
<div className={`flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium ${bookingStep === "exit" ? "bg-amber-100 text-amber-800" : "bg-gray-100 text-gray-500"}`}>
|
||||
<div className={`w-1.5 h-1.5 rounded-full ${bookingStep === "exit" ? "bg-amber-500" : "bg-gray-400"}`} />
|
||||
{t("selectEndDate")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Calendar */}
|
||||
{effectivePricingMode === "daily" ? (
|
||||
<div className="mb-3">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<button onClick={() => navigateMonth(-1)} className="p-1 rounded-lg hover:bg-gray-100 transition-colors">
|
||||
<ChevronRight className="w-4 h-4 text-gray-600" />
|
||||
</button>
|
||||
<span className="text-sm font-bold text-gray-900">
|
||||
{t(MONTH_KEYS[calendarMonth])} {calendarYear}
|
||||
</span>
|
||||
<button onClick={() => navigateMonth(1)} className="p-1 rounded-lg hover:bg-gray-100 transition-colors">
|
||||
<ChevronLeft className="w-4 h-4 text-gray-600" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-7 mb-1">
|
||||
{DAY_KEYS.map((dk, i) => (
|
||||
<div key={i} className="text-center text-[10px] text-gray-400 font-medium py-1">
|
||||
{t(dk)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{(() => {
|
||||
const firstDay = new Date(calendarYear, calendarMonth, 1).getDay();
|
||||
const daysInMonth = new Date(calendarYear, calendarMonth + 1, 0).getDate();
|
||||
const adjustedFirstDay = (firstDay + 1) % 7;
|
||||
const cells = [];
|
||||
for (let i = 0; i < adjustedFirstDay; i++) {
|
||||
cells.push(<div key={`e-${i}`} />);
|
||||
}
|
||||
for (let day = 1; day <= daysInMonth; day++) {
|
||||
const dateStr = `${calendarYear}-${String(calendarMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
||||
const past = isPastDate(dateStr);
|
||||
const available = isDateAvailable(dateStr);
|
||||
const isSelStart = dateStr === selectedStart;
|
||||
const isSelEnd = dateStr === selectedEnd;
|
||||
const inRange = selectedStart && selectedEnd && new Date(dateStr) > new Date(selectedStart) && new Date(dateStr) < new Date(selectedEnd);
|
||||
const disabled = past || !available;
|
||||
cells.push(
|
||||
<button
|
||||
key={dateStr}
|
||||
onClick={() => !disabled && handleDayClick(dateStr)}
|
||||
disabled={disabled}
|
||||
className={`text-center py-1.5 text-xs rounded-lg transition-all ${disabled ? "text-gray-300 cursor-not-allowed" : ""} ${isSelStart || isSelEnd ? "bg-amber-500 text-white font-bold shadow-sm" : ""} ${inRange ? "bg-amber-100 text-amber-800" : ""} ${!disabled && !isSelStart && !isSelEnd && !inRange && available ? "hover:bg-amber-50 text-gray-700" : ""} ${!disabled && !isSelStart && !isSelEnd && !inRange && !available ? "text-red-300" : ""}`}
|
||||
>
|
||||
{day}
|
||||
</button>,
|
||||
);
|
||||
}
|
||||
return <div className="grid grid-cols-7 gap-0.5">{cells}</div>;
|
||||
})()}
|
||||
</div>
|
||||
) : (
|
||||
<div className="mb-3">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<button onClick={() => setCalendarYear((prev) => prev - 1)} className="p-1 rounded-lg hover:bg-gray-100 transition-colors">
|
||||
<ChevronRight className="w-4 h-4 text-gray-600" />
|
||||
</button>
|
||||
<span className="text-sm font-bold text-gray-900">{calendarYear}</span>
|
||||
<button onClick={() => setCalendarYear((prev) => prev + 1)} className="p-1 rounded-lg hover:bg-gray-100 transition-colors">
|
||||
<ChevronLeft className="w-4 h-4 text-gray-600" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
{MONTH_KEYS.map((mk, idx) => {
|
||||
const monthStr = `${calendarYear}-${String(idx + 1).padStart(2, "0")}`;
|
||||
const isSelStart = selectedStart && selectedStart.startsWith(monthStr);
|
||||
const isSelEnd = selectedEnd && selectedEnd.startsWith(monthStr);
|
||||
const inRange = selectedStart && selectedEnd && monthStr > selectedStart.substring(0, 7) && monthStr < selectedEnd.substring(0, 7);
|
||||
return (
|
||||
<button
|
||||
key={idx}
|
||||
onClick={() => {
|
||||
const firstDay = `${monthStr}-01`;
|
||||
if (bookingStep === "entry" || (selectedStart && monthStr <= selectedStart.substring(0, 7))) {
|
||||
setSelectedStart(firstDay);
|
||||
setSelectedEnd(null);
|
||||
setBookingStep("exit");
|
||||
} else {
|
||||
const lastDay = new Date(calendarYear, idx + 1, 0).getDate();
|
||||
setSelectedEnd(`${monthStr}-${String(lastDay).padStart(2, "0")}`);
|
||||
setBookingStep("entry");
|
||||
}
|
||||
}}
|
||||
className={`p-2.5 rounded-xl text-center text-xs font-medium transition-all border ${isSelStart || isSelEnd ? "bg-amber-500 text-white border-amber-500 shadow-sm" : inRange ? "bg-amber-100 text-amber-800 border-amber-200" : "bg-white text-gray-700 border-gray-200 hover:border-amber-300"}`}
|
||||
>
|
||||
{t(mk)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<DateSelectionCalendar
|
||||
mode={effectivePricingMode}
|
||||
availableDates={availableDatesSet}
|
||||
selectedStart={selectedStart}
|
||||
selectedEnd={selectedEnd}
|
||||
onSelectStart={(d) => {
|
||||
setSelectedStart(d);
|
||||
setSelectedEnd(null);
|
||||
}}
|
||||
onSelectEnd={setSelectedEnd}
|
||||
/>
|
||||
|
||||
{/* Summary */}
|
||||
{selectedStart && (
|
||||
@ -1156,7 +1002,7 @@ export default function PropertyDetailsPage() {
|
||||
<span className="text-gray-500">{effectivePricingMode === "daily" ? t("numberOfDays") : t("numberOfMonths")}</span>
|
||||
<span className="font-medium text-gray-900">
|
||||
{effectivePricingMode === "daily"
|
||||
? Math.max(1, Math.round((new Date(selectedEnd) - new Date(selectedStart)) / (1000 * 60 * 60 * 24)) + 1)
|
||||
? Math.max(1, Math.round((new Date(selectedEnd) - new Date(selectedStart)) / (1000 * 60 * 60 * 24)))
|
||||
: new Date(selectedEnd).getMonth() - new Date(selectedStart).getMonth() + (new Date(selectedEnd).getFullYear() - new Date(selectedStart).getFullYear()) * 12 + 1}
|
||||
</span>
|
||||
</div>
|
||||
@ -1165,7 +1011,7 @@ export default function PropertyDetailsPage() {
|
||||
<span className="text-amber-600">
|
||||
{formatCurrency(
|
||||
effectivePricingMode === "daily"
|
||||
? Math.max(1, Math.round((new Date(selectedEnd) - new Date(selectedStart)) / (1000 * 60 * 60 * 24)) + 1) * property.priceDisplay.daily
|
||||
? Math.max(1, Math.round((new Date(selectedEnd) - new Date(selectedStart)) / (1000 * 60 * 60 * 24))) * property.priceDisplay.daily
|
||||
: (new Date(selectedEnd).getMonth() - new Date(selectedStart).getMonth() + (new Date(selectedEnd).getFullYear() - new Date(selectedStart).getFullYear()) * 12 + 1) *
|
||||
property.priceDisplay.monthly,
|
||||
)}{" "}
|
||||
|
||||
Reference in New Issue
Block a user