code 1
code 1
code 1
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 {
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,";
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]);
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>
<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>
)}
maka dijalankan loading ketika masih proses get data dari useGetCalendarQuery