saya punya code ini = "use client";
import   FullCalendar from "@fullcalendar/react";
import   dayGridPlugin from "@fullcalendar/daygrid";
import   listWeekPlugin from "@fullcalendar/list";
import   { Avatar, Button, Checkbox, Input, Modal, Select, Spin } from "antd";
import   type { RadioChangeEvent } from "antd";
import   { useEffect, useRef, useState } from "react";
import   NotificationBellIcon from "@/components/common/notificationBellIcon";
import {
  FiBell,
  FiChevronLeft,
  FiChevronRight,
  FiFilter,
  FiGrid,
  FiInfo,
  FiList,
  FiSearch,
} from "react-icons/fi";
import dayjs from "dayjs";
import Link from "next/link";
import { UserOutlined, PlusOutlined } from "@ant-design/icons";
import { imageType } from "@/utils/imageType";
import Image from "next/image";
import { useGetCalendarQuery } from "@/store/api/user/eventApi";
import CheckboxValueType from "antd/es/checkbox/Group";
import { useRouter } from "next/navigation";
import ThemeSwitcher from "@/components/common/themeSwitcher";
import RadioButtonGroup from "@/components/common/feed/radioButtonGroup";
import { useIsDesktop } from "@/hooks/useIsDesktop";
import ListCalendar from "./partials/listCalendar";
import GridCalendar from "./partials/gridCalendar";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "@/store";
import BottomNav from "@/components/common/feed/bottomNav";
import debounce from "lodash/debounce";
interface EventData {
  event_id: string;
  title: string;
  event_date_start: string;
  event_date_end: string;
  location: {
     city: string;
  };
  category: string;
  subcategory: string;
  type: string;
  requirements: {
     age_from: string;
     age_to: string;
     gender: string;
     skill_level: string;
  };
  creator: string;
  creater: {
     avatar: string;
  };
}
export default function Calendar() {
  const router = useRouter();
  const [calendarView, setCalendarView] = useState("dayGridMonth");
  const calendarRef = useRef<FullCalendar>(null);
  const [dataCalendar, setDataCalendar] = useState<any>([]);
  const [calendarTitle, setCalendarTitle] = useState("");
  const [infoOpen, setInfoOpen] = useState(false);
  const [dataEvent, setDataEvent] = useState<{ [key: string]: EventData[] }>(
     {}
  );
  const [startDate, setStartDate] = useState("");
  const [endDate, setEndDate] = useState("");
  const [isPersonal, setIspersonal] = useState(false);
  const [eventPlace, setEventPlace] = useState("");
  const [checkedValues, setCheckedValues] = useState<string[]>([]);
  const [searchQuery, setSearchQuery] = useState("");
  const isDesktop = useIsDesktop(987);
  const trigger = useSelector((state: RootState) => state.calendar.trigger);
  const {
     data,
     refetch,
     isFetching,
     isUninitialized,
     isLoading,
     isSuccess,
     isError,
  } = useGetCalendarQuery(
     {
        date_start_from: startDate,
        date_start_to: endDate,
        is_personal: isPersonal,
        event_place: eventPlace,
        search: searchQuery
     },
     { skip: !startDate && !endDate && !eventPlace }
  );
  useEffect(() => {
    if (!isUninitialized && !isLoading && (isSuccess || isError)) {
      refetch();
    }
  }, [eventPlace, isUninitialized, isLoading, isSuccess, isError]);
  useEffect(() => {
    if (data) {
      setDataEvent(data?.data);
    }
  }, [data]);
  useEffect(() => {
    if (trigger > 0 && !isUninitialized) {
      refetch();
    }
  }, [trigger, isUninitialized]);
const handleEventPlaceChange = (checkedList: any) => {
  setCheckedValues(checkedList as string[]);
  let place = "";
  if (checkedList.includes("1")) place += "on-ice,";
  if (checkedList.includes("2")) place += "off-ice,";
  place = place.endsWith(",") ? place.slice(0, -1) : place;
  setEventPlace(place);
};
const handleDatesRender = (info: any) => {
   const start = dayjs(info.view.currentStart).format("YYYY-MM-DDTHH:mm:ssZ");
   const end = dayjs(info.view.currentEnd).format("YYYY-MM-DDTHH:mm:ssZ");
   setStartDate(start);
   setEndDate(end);
};
const handlePrev = () => {
   if (calendarRef.current) {
     calendarRef.current.getApi().prev();
     updateCalendarTitle();
   }
};
const handleNext = () => {
   if (calendarRef.current) {
     calendarRef.current.getApi().next();
     updateCalendarTitle();
   }
};
const updateCalendarTitle = () => {
   if (calendarRef.current) {
     const title = calendarRef.current.getApi().view.title;
     setCalendarTitle(title);
   }
};
useEffect(() => {
   updateCalendarTitle();
}, [calendarView]);
useEffect(() => {
  const formattedEvents = Object.keys(dataEvent).map((date: string) => {
    const eventsForDate = dataEvent[date];
    return eventsForDate.map((event: EventData) => ({
      event_id: event.event_id,
      title: event.title,
      start: date,
      event_date_end: event.event_date_end,
      creater: event.creater?.avatar,
      location: event.location?.city,
      category: event.category,
      subcategory: event.subcategory,
      type: event.type,
      age_from: event.requirements.age_from,
      age_to: event.requirements.age_to,
      creator: event.creator,
      skill_level: event.requirements.skill_level,
      gender: event.requirements.gender,
    }));
    });
    const flattenedEvents = formattedEvents.flat();
    setDataCalendar(flattenedEvents);
  }, [dataEvent]);
  const calenderViewChange = ({ target: { value } }: RadioChangeEvent) => {
     setCalendarView(value);
  };
  const handleDetail = (info: any) => {
     const id = info.event.extendedProps.event_id;
     router.push(`/calendar/${id}`);
  };
  const handleSearchChange = debounce((e) => {
    setSearchQuery(e.target.value);
  }, 100);
  return (
    <div className="py-[20px] md:pb-0 pb-[90px]">
      <div className="px-4 border-b-[1px] border-light-borderGrey dark:border-dark-
borderGrey border-solid">
        <div className=" pb-4 flex gap-3 items-center">
           <div className="flex-1">
             <Input
                placeholder="Search event here"
                prefix={<FiSearch size="20" className="text-[#D0D5DD]" />}
                onChange={handleSearchChange}
             />
           </div>
           <div className="pt-2">
             <NotificationBellIcon />
           </div>
        </div>
        <div className="flex items-center md:pb-0 pb-3">
           <div>
             <div className="md:text-[32px] text-[18px] font-[600] pr-5">
                {calendarTitle}
             </div>
           </div>
           <div>
             <div className="flex items-center gap-3">
                <div>
                  <Button
                    onClick={handlePrev}
                    className="p-0 w-[36px] h-[36px] flex items-center justify-center
bg-[#EAECF0] text-[#475467] hover:bg-[#b1bcd3] border-light-borderGrey dark:border-
dark-borderGrey hover:border-[#b1bcd3]"
                  >
                    <FiChevronLeft size="20" />
                  </Button>
                </div>
                <div>
                  <Button
                    onClick={handleNext}
                    className="p-0 w-[36px] h-[36px] flex items-center justify-center
bg-[#EAECF0] text-[#475467] hover:bg-[#b1bcd3] border-light-borderGrey dark:border-
dark-borderGrey hover:border-[#b1bcd3]"
                  >
                <FiChevronRight size="20" />
             </Button>
          </div>
       </div>
    </div>
    {/* <div className="ms-auto">
       <RadioButtonGroup
          options={[
             {
                value: "dayGridMonth",
                icon: <FiList />,
                label: isDesktop ? "Calendar view" : "",
             },
             {
                value: "listWeek",
                icon: <FiGrid />,
                label: isDesktop ? "List View" : "",
             },
          ]}
          defaultValue="dayGridMonth"
          onChange={calenderViewChange}
          className="switch-calendar"
       />
    </div> */}
  </div>
</div>
<div className="p-4">
  <div className="flex gap-3 justify-between items-center flex-wrap">
    <div className="flex gap-3 items-center">
       <Button
          shape="round"
          className={` border-0 text-[#344054] ${
             !isPersonal ? "bg-[#D6DCE4] text-[#061E3C]" : "bg-[#F2F4F7]"
          }`}
          onClick={() => setIspersonal(false)}
       >
          Master
       </Button>
       <Button
          shape="round"
          className={` border-0 text-[#344054] ${
             isPersonal ? "bg-[#D6DCE4] text-[#061E3C]" : "bg-[#F2F4F7]"
          }`}
          onClick={() => setIspersonal(true)}
       >
          Personal
       </Button>
       <div>
          <FiInfo
             className="text-[25px] text-[#D0D5DD] cursor-pointer"
             onClick={() => setInfoOpen(true)}
          />
          <Modal
             title=""
             closeIcon={false}
             open={infoOpen}
             centered
             footer={null}
             onCancel={() => setInfoOpen(false)}
        width={270}
    >
        <Image
           src={imageType.calendarConfirm}
           width={63}
           height={63}
           alt="icon"
           className="mx-auto"
        />
        <h4 className="text-center font-bold text-[16px] my-2">
           Event Color on Calendar
        </h4>
        <p className="text-center text-light-softerText">
           Please remember the color for each event because they
           represented by different color.
        </p>
        <div className="border border-Neutral-300 rounded-lg p-2 my-2">
          <div className="flex justify-between">
            <div className="flex items-center ml-5">
               <svg
                 xmlns="http://www.w3.org/2000/svg"
                 width="16"
                 height="16"
                 viewBox="0 0 16 16"
                 fill="none"
               >
                 <circle cx="8" cy="8" r="8" fill="#B9E6FE" />
               </svg>
               <span className="ml-2 font-[500] text-[12px]">
                 Event Group
               </span>
            </div>
            {/* mid */}
            <div className="flex items-center mr-5">
               <svg
                 xmlns="http://www.w3.org/2000/svg"
                 width="16"
                 height="16"
                 viewBox="0 0 16 16"
                 fill="none"
               >
                 <circle cx="8" cy="8" r="8" fill="#FECDD6" />
               </svg>
               <span className="ml-2 font-[500] text-[12px]">Event</span>
            </div>
          </div>
        </div>
       <Button
         type="primary"
         className="w-full"
         onClick={() => setInfoOpen(false)}
       >
         OK
       </Button>
    </Modal>
  </div>
</div>
           <div className="flex items-center flex-wrap gap-3 md:w-auto w-full
md:justify-start justify-between">
             <div>
                <Checkbox.Group
                  value={checkedValues}
                  style={{ width: "100%" }}
                  onChange={(checkedList: any) => {
                     const newValue =
                       checkedList.length > 0
                         ? [checkedList[checkedList.length - 1]]
                         : [];
                     handleEventPlaceChange(newValue);
                  }}
                >
                  <Checkbox value="1">On Ice</Checkbox>
                  <Checkbox value="2">Off Ice</Checkbox>
                </Checkbox.Group>
             </div>
             <div>
                {/* <Button type="default" className="flex items-center gap-2">
                  <FiFilter /> Filter{" "}
                </Button> */}
             </div>
           </div>
         </div>
      </div>
      {isFetching && (
         <Spin tip="Loading" size="large" className="h-[200px]">
           <div className="content" />
         </Spin>
      )}
      {/* {calendarView == "dayGridMonth" ? ( */}
      <FullCalendar
         ref={calendarRef}
         plugins={[dayGridPlugin, listWeekPlugin]}
         initialView="dayGridMonth"
         events={dataCalendar}
         headerToolbar={false}
         eventClick={handleDetail}
         datesSet={handleDatesRender}
         dayMaxEvents={1}
         handleWindowResize={true}
         eventContent={(eventInfo) => {
            // console.log("eventInfo = "+ JSON.stringify(eventInfo, null, 2));
            return (
               <div className="event-card max-h-96 overflow-y-auto">
                 <GridCalendar eventInfo={eventInfo} isDetail={false} />
               </div>
            );
         }}
         contentHeight="auto"
      />
      {/* ) : (
         <div className="calendar-list">
            <div></div>
            <FullCalendar
               ref={calendarRef}
               plugins={[dayGridPlugin, listWeekPlugin]}
              initialView="listWeek"
              events={dataCalendar}
              headerToolbar={false}
              eventContent={(eventInfo) => <ListCalendar eventInfo={eventInfo} />}
              listDayFormat={false}
              listDaySideFormat={false}
              handleWindowResize={true}
              contentHeight="auto"
             />
          </div>
        )} */}
        <div className="md:hidden block">
          <BottomNav />
        </div>
      </div>
    );
}
saya ingin ketika mengarah ke fungsi = const handleSearchChange = debounce((e) => {
    setSearchQuery(e.target.value);
  }, 100);
maka dijalankan loading ketika masih proses get data dari useGetCalendarQuery