Untitled
unknown
plain_text
a year ago
22 kB
5
Indexable
"use client";
import CustomImage from "@/app/_components/ui/CustomImage";
import {
useCreateBookingMutation,
useGetTempBookingMutationMutation,
useGetTempBookingQuery,
} from "@/app/features/booking/bookingApi";
import {
useGetRoomsByDateMutationMutation,
useGetRoomsByDateQuery,
useGetRoomsQuery,
} from "@/app/features/room/roomApi";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import { AdvancedCheckbox, Text, Tooltip } from "rizzui";
import CustomButton from "../../_components/CustomButton";
import { useBookingCtx } from "../context/BookingProvider";
import DateSection from "./DateSection";
import GuestCounter from "./GuestCounter";
import PakageImageSlider from "./PakageImageSlider";
const Room1 = "/room/not-booked/Room1.png";
const Room2 = "/room/not-booked/Room2.png";
const Room3 = "/room/not-booked/Room3.png";
const Room4 = "/room/not-booked/Room4.png";
const Room5 = "/room/not-booked/Room5.png";
const Room6 = "/room/not-booked/Room6.png";
const selectedRoom1 = "/room/selected/Room1.png";
const selectedRoom2 = "/room/selected/Room2.png";
const selectedRoom3 = "/room/selected/Room3.png";
const selectedRoom4 = "/room/selected/Room4.png";
const selectedRoom5 = "/room/selected/Room5.png";
const selectedRoom6 = "/room/selected/Room6.png";
const bookRoom1 = "/room/booked/Room1.png";
const bookRoom2 = "/room/booked/Room2.png";
const bookRoom3 = "/room/booked/Room3.png";
const bookRoom4 = "/room/booked/Room4.png";
const bookRoom5 = "/room/booked/Room5.png";
const bookRoom6 = "/room/booked/Room6.png";
export default function BookingHome({ data }: any) {
const [createBooking] = useCreateBookingMutation({});
const {
availableRoom,
setAvailableRoom,
pickerDate,
setPickerDate,
toISOString,
holdData,
handleImageClick,
tempHoldRooms,
setSelectedRoomIndex,
selectedRoomIndex,
}: any = useBookingCtx();
const [roomInfo, setRoomInfo] = useState([]);
const [guests, setGuests] = useState<number>(1);
const [userInformation, setUserInformation] = useState<any>({
name: "",
phone: "",
});
const roomsImage = [Room1, Room2, Room3, Room4, Room5, Room6];
const selectedRoomsImage = [
selectedRoom1,
selectedRoom2,
selectedRoom3,
selectedRoom4,
selectedRoom5,
selectedRoom6,
];
const bookedRoomsImage = [
bookRoom1,
bookRoom2,
bookRoom3,
bookRoom4,
bookRoom5,
bookRoom6,
];
// this is a redux toolkit start
const { data: availableRooms, isLoading: avRoomIsLoading } =
useGetRoomsByDateQuery({
paginate: false,
startDate: pickerDate.startDate,
});
const { data: rooms, isLoading } = useGetRoomsQuery<any>({ paginate: false });
const [getRoomsByDateMutation] = useGetRoomsByDateMutationMutation({});
const { data: tempBook } = useGetTempBookingQuery({
date: pickerDate.startDate,
});
const [getTempBookingMutation] = useGetTempBookingMutationMutation({});
//@ts-ignore
async function getBookings(data: BookingData, available: any): Promise<any> {
// const filteredRoom = data?.totalHold?.filter((h: string) => !data?.holdByCurrentUser?.map((c: any) => c.id).includes(h)) || [];
//@ts-ignore
const updatedRooms = rooms?.data?.map((room: any, index: number) => {
const isSelected = data?.ownHold?.some((r: any) => r.id === room.id);
return {
id: room.id,
name: room.name,
selected: isSelected,
selectedRoomId: index + 1,
confirmed: "start",
price: room.price,
maxCapacity: room.maxCapacity,
status: room.status,
discount: room.discount,
image: roomsImage[index],
images: room.images,
videos: room.videos,
// booked: filteredRoom.includes(room.id) || !available?.data.some((avRoom: any) => avRoom.id === room.id),
booked: !available?.data.some((avRoom: any) => avRoom.id === room.id),
hold: data?.totalHolds?.includes(room.id),
holdByCurrentUser: data?.ownHold,
};
});
setAvailableRoom(updatedRooms);
}
useEffect(() => {
if (rooms?.data || availableRooms || tempBook) {
getBookings(tempBook?.data, availableRooms);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [rooms?.data, availableRooms, tempBook, pickerDate.startDate]);
const handleGuestChange = (delta: number) => {
if (selectedRoomIndex !== null) {
setRoomInfo((prevRoomInfo: any) =>
prevRoomInfo.map((room: any, i: number) =>
i === selectedRoomIndex
? { ...room, guests: Math.min(4, Math.max(1, room.guests + delta)) }
: room
)
);
}
};
// date picker
const handleDateChange = (date: string) => {
const mainDate = new Date(
new Date(date).setUTCHours(0, 0, 0, 0)
).toISOString();
const endDate = new Date(
new Date(mainDate).getTime() + 24 * 60 * 60 * 1000
).toISOString();
};
//booking section
const [activeRoom, setActiveRoom] = useState<number>(0);
const [userSubmitRoomData, setUserSubmitRoomData] = useState<any>();
const [userFinalRoomData, setUserFinalRoomData] = useState<any>();
const [numberOfGuest, setNumberOfGuest] = useState(2);
console.log("userFinalRoomData", userFinalRoomData);
function filterOwnHoldRooms(roomData: any, ownHold: any) {
setUserFinalRoomData(
roomData?.filter((room: any) => ownHold?.has(room.id))
);
}
useEffect(() => {
if (availableRoom) {
filterOwnHoldRooms(availableRoom, holdData);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [availableRoom]);
function getMatchedObjects(
userSubmitRoomData: any[],
userFinalRoomData: any[]
): any[] {
const matchedObjects: any[] = userSubmitRoomData?.filter((obj2) =>
userFinalRoomData?.some((obj1) => obj1.id === obj2.room)
);
return matchedObjects;
}
const res = getMatchedObjects(userSubmitRoomData, userFinalRoomData);
const handleNextButton = ({ index, id }: { index: number; id: string }) => {
setActiveRoom(index);
console.log(id, "select id");
console.log(index, "index");
console.log(numberOfGuest, "numberOfGuest");
const alreadyExists = userSubmitRoomData?.find(
(item: any) => item.room === id
);
console.log(alreadyExists, "---");
if (!alreadyExists) {
setUserSubmitRoomData((prevData: any[]) => {
const updatedData = prevData ? [...prevData] : [];
updatedData.push({
guests: numberOfGuest,
room: id,
});
return updatedData;
});
} else {
setUserSubmitRoomData((prevData: any[]) => {
const updatedData = prevData.map((item: any) =>
item.room === id ? { ...item, guests: numberOfGuest } : item
);
return updatedData;
});
}
};
const handlePreviousButton = () => {
setActiveRoom(activeRoom - 1);
};
async function handleFinalSubmitButton({
index,
id,
}: {
index: number;
id: number;
}) {
setActiveRoom(index);
console.log(id, "select id");
console.log(index, "index");
console.log(numberOfGuest, "numberOfGuest");
const alreadyExists = userSubmitRoomData?.find(
(item: any) => item.room === id
);
console.log(alreadyExists, "---");
if (!alreadyExists) {
setUserSubmitRoomData((prevData: any[]) => {
const updatedData = prevData ? [...prevData] : [];
updatedData.push({
guests: numberOfGuest,
room: id,
});
return updatedData;
});
} else {
setUserSubmitRoomData((prevData: any[]) => {
const updatedData = prevData.map((item: any) =>
item.room === id ? { ...item, guests: numberOfGuest } : item
);
return updatedData;
});
}
if (!userInformation.name || !userInformation.phone) {
toast.error("Fill name or phone number");
return;
}
const sendDAta = {
rooms: res,
name: userInformation.name,
phone: userInformation.phone,
startDate: pickerDate.startDate,
endDate: pickerDate.endDate,
};
try {
const res: any = await createBooking(sendDAta);
toast.success("Booking created successfully");
// window.location.href = "/success";
setActiveRoom(0);
setUserFinalRoomData([]);
setAvailableRoom([]);
} catch (error) {
toast.error("error");
}
console.log(sendDAta, "final submit");
setActiveRoom(0);
}
const inputOnChange = (e: any) => {
const { name, value } = e.target;
setUserInformation((prev: any) => ({ ...prev, [name]: value }));
setRoomInfo((prevRoomInfo: any) =>
prevRoomInfo.map((room: any) => ({ ...room, [name]: value }))
);
};
return (
<>
<DateSection
pickerDate={pickerDate}
handleDateChange={handleDateChange}
/>
<div className="">
<p className="px-1 pb-4 text-xs font-normal capitalize">
click to select or deselect rooms.
</p>
<div className="mb-5 flex gap-4">
<div className="flex gap-3">
<div className="h-5 w-5 rounded-sm border bg-[#F9FAFA]"></div>
<span className=" text-[10px] font-medium lg:text-xs">
Available Room
</span>
</div>
<div className="flex gap-3">
<div className="h-5 w-5 rounded-sm border bg-[#C7C8CA]"></div>
<span className=" text-[10px] font-medium lg:text-xs">
Booked Room
</span>
</div>
<div className="flex gap-3">
<div className="h-5 w-5 rounded-sm border bg-[#98C157]"></div>
<span className=" text-[10px] font-medium lg:text-xs">
Selected Room
</span>
</div>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-7 gap-4 content-center m-2 lg:m-0 ">
<div className="border border-gray-500 col-span-7 lg:col-span-2 w-full h-full flex justify-center items-center">
<div className="grid grid-cols-2 gap-3 my-2">
{availableRoom
? availableRoom?.map((room: any, index: number) => (
<div key={room.id}>
{room.booked ? (
<CustomImage
src={bookedRoomsImage[index]}
alt="book room"
className="cursor-not-allowed h-28 w-24 sm:h-36 md:h-44 md:w-32"
/>
) : room.selected && room.hold ? (
<Tooltip
placement="top"
color="invert"
className="bg-white"
content={room.name}
>
<CustomImage
src={selectedRoomsImage[index]}
alt="room"
className="h-28 w-24 sm:h-36 md:h-44 md:w-32 my-2"
onClick={() => handleImageClick(room.id, index)}
/>
</Tooltip>
) : room.hold ? (
<CustomImage
src={bookedRoomsImage[index]}
alt="book room"
className="cursor-not-allowed h-28 w-24 sm:h-36 md:h-44 md:w-32"
/>
) : room.selected ? (
<Tooltip
placement="top"
color="invert"
className="bg-white"
content={room.name}
>
<CustomImage
src={selectedRoomsImage[index]}
alt="room"
className="h-28 w-24 sm:h-36 md:h-44 md:w-32 my-2"
onClick={() => handleImageClick(room.id, index)}
/>
</Tooltip>
) : (
<Tooltip
placement="top"
color="invert"
className="bg-white"
content={room.name}
>
<CustomImage
src={roomsImage[index]}
alt="room"
className="h-28 w-24 sm:h-36 md:h-44 md:w-32 my-2"
onClick={() => handleImageClick(room.id, index)}
/>
</Tooltip>
)}
</div>
))
: data?.map((room: any, index: number) => (
<div key={room.id}>
{room.booked ? (
<CustomImage
src={bookedRoomsImage[index]}
alt="book room"
className="cursor-not-allowed h-28 w-24 sm:h-36 md:h-44 md:w-32"
/>
) : room.selected && room.hold ? (
<Tooltip
placement="top"
color="invert"
className="bg-white"
content={room.name}
>
<CustomImage
src={selectedRoomsImage[index]}
alt="room"
className="h-28 w-24 sm:h-36 md:h-44 md:w-32 my-2"
onClick={() => handleImageClick(room.id, index)}
/>
</Tooltip>
) : room.hold ? (
<CustomImage
src={bookedRoomsImage[index]}
alt="book room"
className="cursor-not-allowed h-28 w-24 sm:h-36 md:h-44 md:w-32"
/>
) : room.selected ? (
<Tooltip
placement="top"
color="invert"
className="bg-white"
content={room.name}
>
<CustomImage
src={selectedRoomsImage[index]}
alt="room"
className="h-28 w-24 sm:h-36 md:h-44 md:w-32 my-2"
onClick={() => handleImageClick(room.id, index)}
/>
</Tooltip>
) : (
<Tooltip
placement="top"
color="invert"
className="bg-white"
content={room.name}
>
<CustomImage
src={roomsImage[index]}
alt="room"
className="h-28 w-24 sm:h-36 md:h-44 md:w-32 my-2"
onClick={() => handleImageClick(room.id, index)}
/>
</Tooltip>
)}
</div>
))}
</div>
</div>
<div className="col-span-7 lg:col-span-5 w-full h-full flex flex-col justify-center items-center">
{/* Render buttons for selected rooms */}
<div className="mb-4 flex gap-2">
{userFinalRoomData?.map((room: any, index: number) => {
return (
<div key={index} className="">
{activeRoom === index ? (
<button
onClick={() => setActiveRoom(index)}
className={`px-4 py-2 bg-blue-500 text-white rounded m-2`}
>
{room.name}
</button>
) : (
<button
onClick={() => setActiveRoom(index)}
className={`px-4 py-2 bg-green-400 text-white rounded m-2`}
>
{room.name}
</button>
)}
</div>
);
})}
</div>
<div className="max-w-full lg:max-w-[60%] max-h-[100%] bg-white shadow-lg rounded-2xl overflow-hidden">
<div className="w-full">
<PakageImageSlider
images={
userFinalRoomData && userFinalRoomData[activeRoom]?.images
}
/>
<h2>
{" "}
{(userFinalRoomData && userFinalRoomData[activeRoom]?.name) ||
""}{" "}
</h2>
</div>
<div className="m-5 mt-10">
<GuestCounter
number={numberOfGuest}
setNumber={setNumberOfGuest}
maxCapacity={
(userFinalRoomData &&
userFinalRoomData[activeRoom]?.maxCapacity) ??
2
}
/>
<div className="flex gap-5 pb-3 pt-2">
<div>
<input
onChange={inputOnChange}
name="name"
type="text"
value={userInformation.name}
className="w-full border-b border-[#E3DBB7] px-1 py-2 text-sm font-light capitalize tracking-wide outline-none lg:text-base"
placeholder="Name"
/>
</div>
<div>
<input
onChange={inputOnChange}
name="phone"
type="text"
value={userInformation.phone}
className="w-full border-b border-[#E3DBB7] px-1 py-2 text-sm font-light capitalize tracking-wide outline-none lg:text-base"
placeholder="Phone Number"
/>
{!userInformation.phone && (
<div className="text-sm font-light text-red-500">
Phone Number field is required
</div>
)}
</div>
</div>
<div>
<AdvancedCheckbox name="currency" value="taka" defaultChecked>
<Text className="text-sm font-semibold lg:text-base">
ROOM{" "}
{userFinalRoomData && userFinalRoomData[activeRoom]?.name}
</Text>
<hr className="mb-2" />
<p className="mb-1 text-base font-light capitalize tracking-wider lg:text-lg">
from ৳{" "}
<strong className="text-base font-semibold lg:text-xl">
{userFinalRoomData &&
Math.ceil(
userFinalRoomData[activeRoom]?.price[
numberOfGuest - 1
]?.price /
userFinalRoomData[activeRoom]?.price[
numberOfGuest - 1
]?.numberOfPerson
)}
</strong>{" "}
{userFinalRoomData &&
userFinalRoomData[activeRoom]?.price[numberOfGuest - 1]
?.numberOfPerson}
<br />
{userFinalRoomData &&
userFinalRoomData[activeRoom]?.price[numberOfGuest - 1]
?.price}
per person
</p>
<p className="mb-1 text-base font-light capitalize tracking-wider lg:text-lg">
sub total ৳{" "}
<strong className="text-base font-semibold lg:text-xl">
{userFinalRoomData &&
userFinalRoomData[activeRoom]?.price[numberOfGuest - 1]
?.price}
</strong>{" "}
for this room
</p>
</AdvancedCheckbox>
</div>
{activeRoom > 0 && (
<CustomButton
onClick={handlePreviousButton}
customClass="w-[150px] text-white bg-[#1DC5CE] py-1 text-2xl rounded-none"
text="Previous"
/>
)}
{activeRoom < userFinalRoomData?.length - 1 ? (
<CustomButton
onClick={() =>
handleNextButton({
index: activeRoom + 1,
id: userFinalRoomData[activeRoom]?.id,
})
}
customClass="w-[150px] text-white bg-[#1DC5CE] py-1 text-2xl rounded-none"
text="Next"
/>
) : (
<CustomButton
onClick={() =>
handleFinalSubmitButton({
index: activeRoom + 1,
id: userFinalRoomData[activeRoom]?.id,
})
}
customClass="w-[150px] text-white bg-[#1DC5CE] py-1 text-2xl rounded-none"
text="Final Submit"
/>
)}
</div>
</div>
</div>
</div>
</>
);
}
Editor is loading...
Leave a Comment