Untitled

mail@pastecode.io avatar
unknown
plain_text
15 days ago
22 kB
0
Indexable
Never
"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>
    </>
  );
}
Leave a Comment