import React, { useMemo } from "react";
import "../Events/events.css";
import { NavLink } from "react-router-dom";
import { useState, useEffect } from "react";
import LoadingAnimation from "../Loading/LoadingAnimation";
import { Select } from "antd";
import { useGetEventsList } from "../../../apis/Events";
import RegisterModal from "./RegisterModal/RegisterModal";
import { AddToCalendarButton } from "add-to-calendar-button-react";
const companies = [
{
label: "All",
value: "",
},
{
label: "RKD Holdings Limited",
value: "RKD Holdings Limited",
},
{
label: "Tourism Investement Fund Limited",
value: "Tourism Investement Fund Limited",
},
{
label: "Bandipur Cable Car & Tourism Limited",
value: "Bandipur Cable Car & Tourism Limited",
},
{
label: "Panchase Cable Car and Tours Limited",
value: "Panchase Cable Car and Tours Limited",
},
{
label: "Bizbazar Limited",
value: "Bizbazar Limited",
},
];
const date_range = [
{
label: "All",
value: "",
},
{
label: "Upcoming Events",
value: "UP",
},
{
label: "Today",
value: "TD",
},
{
label: "This Month",
value: "TM",
},
{
label: "Past Events",
value: "PE",
},
];
/**
* Represents Events page component
* @module Events
* @returns {JSX.Element}
*/
const Events = () => {
/**
* React state that holds grid view status
* @constant
* @type {boolean}
* @default true
* @memberof module:Events
*/
const [gridView, setGridVied] = useState(true);
/**
* React state that holds sort by status
* @constant
* @type {string}
* @default ""
* @memberof module:Events
*/
const [sortBy, setSortBy] = useState("");
/**
* React state that holds filter dropdown status
* @constant
* @type {boolean}
* @default false
* @memberof module:Events
*/
const [filterDropdown, setFilterDropdown] = useState(false);
/**
* React state that holds search input status
* @constant
* @type {string}
* @default ""
* @memberof module:Events
*
*/
const [searchInput, setSearchInput] = useState("");
/**
* React state that holds location status
* @constant
* @type {string}
* @default ""
* @memberof module:Events
*/
const [location, setLocation] = useState("");
/**
* React state that holds date range status
* @constant
* @type {string}
* @default ""
* @memberof module:Events
*/
const [dateRange, setDateRange] = useState(date_range[0].value);
/**
* React state that holds modal status
* @constant
* @type {boolean}
* @default false
* @memberof module:Events
*/
const [isModalOpen, setIsModalOpen] = useState(false);
/**
* React state that holds company status
* @constant
* @type {string}
* @default "RKD Holdings Limited"
* @memberof module:Events
*/
const [company, setCompany] = useState("RKD Holdings Limited");
/**
* React state that holds event id status
* @constant
* @type {object}
* @default null
* @memberof module:Events
*/
const [eventId, setEventId] = useState(null);
/**
* React query hook to get events list
* @function useGetEventsList
* @memberof module:Events
* @inner
*/
const { data: event, isLoading: eventLoading } = useGetEventsList();
/**
* Function to get last day of the month
* @function getLastDayOfMonth
* @memberof module:Events
* @returns {number}
*/
function getLastDayOfMonth() {
const currentDate = new Date();
const currentYear = currentDate.getFullYear();
const currentMonth = currentDate.getMonth();
// Months are zero-based, so adding 1 to get the next month and day 0 to get the last day of the current month
const lastDayOfMonth = new Date(currentYear, currentMonth + 1, 0);
return lastDayOfMonth.getDate();
}
/**
* Function to get data by range
* @function getDataByRange
* @param data {Array} - array of events
* @returns {*[]}
* @memberof module:Events
*/
const getDataByRange = (data = []) => {
try {
let date = new Date();
let year = date.toLocaleDateString();
const currentTimestampMillis = new Date(year);
const currentTimestampSeconds = Math.floor(currentTimestampMillis / 1000);
const today = new Date();
const dayIndex = today.getDate();
switch (dateRange) {
case date_range[1].value:
let filteredUpData = data.filter((item, i) => {
const dateInMillis = new Date(item?.event_start_date);
const dateInSeconds = dateInMillis / 1000;
if (dateInSeconds > currentTimestampSeconds) {
return true;
}
return false;
});
return filteredUpData;
case date_range[2].value:
let filteredTData = data.filter((item, i) => {
const dateInMillis = new Date(item?.event_start_date);
const dateInSeconds = dateInMillis / 1000;
if (
dateInSeconds >= currentTimestampSeconds &&
dateInSeconds < parseInt(currentTimestampSeconds) + 86400
) {
return true;
}
return false;
});
return filteredTData;
case date_range[3].value:
let filteredTMData = data.filter((item, i) => {
const dateInMillis = new Date(item?.event_start_date);
const dateInSeconds = dateInMillis / 1000;
if (
dateInSeconds <=
currentTimestampSeconds +
(getLastDayOfMonth() - dayIndex) * 86400 &&
dateInSeconds >=
parseInt(currentTimestampSeconds) - 86400 * (dayIndex - 1)
) {
return true;
}
return false;
});
return filteredTMData;
case date_range[4].value:
let filteredPEData = data.filter((item, i) => {
const dateInMillis = new Date(item?.event_start_date);
const dateInSeconds = dateInMillis / 1000;
if (dateInSeconds < currentTimestampSeconds - 86400) {
return true;
}
return false;
});
return filteredPEData;
}
} catch (err) {
console.log(err.message);
}
};
/**
* React memo hook to memoize event data
* @constant eventData
* @memberof module:Events
* @type {unknown}
*/
const eventData = useMemo(() => {
let temp = event?.data?.data?.results || [];
temp = [...temp].reverse();
// Search with name
if (searchInput) {
const filteredList = temp.filter((item) =>
item.title.toLowerCase().includes(searchInput.toLowerCase())
);
temp = filteredList;
}
//handle company select
if (company) {
const filteredList = temp.filter((item) => {
let companies = item?.company || [];
let isCompanyExist = companies.some((el) => el.name === company);
if (isCompanyExist) {
return true;
}
return false;
});
temp = filteredList;
}
// handle location search
if (location) {
let filteredList = temp.filter((item) =>
item.location.toLowerCase().includes(location.toLowerCase())
);
temp = filteredList;
}
if (dateRange) {
let filteredList = getDataByRange(temp);
temp = filteredList;
}
// Sorting reports
switch (sortBy) {
case "OLD":
let revisedData = temp.map((el, i) => ({
...el,
date: new Date(el?.event_start_date),
}));
temp = revisedData.slice().sort((a, b) => a.date - b.date);
return temp;
case "RECENT":
let revisedRecentData = temp.map((el, i) => ({
...el,
date: new Date(el?.event_start_date),
}));
temp = revisedRecentData.slice().sort((a, b) => b.date - a.date);
return temp;
}
return temp;
}, [event?.data, sortBy, company, searchInput, location, dateRange]);
if (eventLoading) {
return <LoadingAnimation />;
}
return (
<div className="events_container">
<>
<RegisterModal
isModalOpen={isModalOpen}
setIsModalOpen={setIsModalOpen}
id={eventId?.id}
/>
<div className="events_heading">
<h2 className="main-title">Events</h2>
<div className="events_filter_wrapper flex w-100 justify-between mt-3 gap-2 flex-wrap">
<div className="report_selectors flex gap-2 flex-wrap justify-end">
<div className="single_selector ">
<div className="selector_label text-center">Company</div>
<Select
style={{
width: 200,
}}
defaultValue="RKD Holdings Limited"
className="report_company_selector parent_select "
onChange={(value) => setCompany(value)}
options={companies}
/>
</div>{" "}
<div className="single_selector ">
<div className="selector_label text-center">Date Range</div>
<Select
name="date_range"
defaultValue={date_range[0].label}
className="report_company_selector parent_select "
style={{
width: 200,
}}
onChange={(value) => setDateRange(value)}
options={date_range}
/>
</div>{" "}
</div>
<div className="events_search flex flex-wrap justify-end gap-2">
<div className="left_events_search">
{/* <div className="left_events_search">
<ion-icon name="search"></ion-icon>
</div> */}
<div className="search_input">
{/* <ion-icon name="search-outline"></ion-icon> */}
<input
type="text"
onChange={(e) => setLocation(e.target.value)}
placeholder="Search by location"
/>
</div>
</div>
<div className="left_events_search">
<div className="left_events_search">
<ion-icon name="search"></ion-icon>
</div>
<div className="search_input">
{/* <ion-icon name="search-outline"></ion-icon> */}
<input
type="text"
onChange={(e) => setSearchInput(e.target.value)}
placeholder="Search"
/>
</div>
</div>
<div className="right_events_search">
<div className="events_grid_list_view">
<ul>
{gridView ? (
<li
onClick={() => setGridVied(!gridView)}
style={{
background: "#53BF8A",
borderRadius: ".2rem",
color: "#ffffff",
}}
>
<ion-icon name="grid-outline"></ion-icon>
</li>
) : (
<li onClick={() => setGridVied(!gridView)}>
<ion-icon name="grid-outline"></ion-icon>
</li>
)}
{gridView ? (
<li onClick={() => setGridVied(!gridView)}>
<ion-icon name="list-outline"></ion-icon>
</li>
) : (
<li
onClick={() => setGridVied(!gridView)}
style={{
background: "#53BF8A",
borderRadius: ".2rem",
color: "#ffffff",
}}
>
<ion-icon name="list-outline"></ion-icon>
</li>
)}
</ul>
</div>
<div
className="events_filter_div"
onClick={() => {
setFilterDropdown(!filterDropdown);
}}
>
<p>Sort by</p>
{filterDropdown ? (
<ion-icon name="chevron-up-outline"></ion-icon>
) : (
<ion-icon name="chevron-down-outline"></ion-icon>
)}
{filterDropdown && (
<div className="events_filter_dropdown">
<p onClick={() => setSortBy("RECENT")}>Recent</p>
<p onClick={() => setSortBy("OLD")}>Oldest</p>
</div>
)}
</div>
</div>
</div>
</div>
</div>
<div className="navigation_for_mobile">
<div className="left_mobile_navigation">
<input
type="text"
onChange={(e) => setSearchInput(e.target.value)}
placeholder="search"
/>
<ion-icon name="search-outline"></ion-icon>
</div>
<div className="right_mobile_navigation">
<ul>
<li>
<ion-icon name="options"></ion-icon>
</li>
</ul>
</div>
</div>
<div className="events_body">
{!eventData?.length ? (
<div className="empty_event_container">
<div className="event_logo">
<ion-icon name="calendar-outline"></ion-icon>
<h3>No events added yet</h3>
<div className="add_new_event">
<p>Stay tuned for updates and secure your spot today.</p>
</div>
</div>
</div>
) : (
<div className="events_div">
{gridView ? (
<div className="documents_divfor_grid_view">
{eventData.map((dat, i) => {
const startDateObj = new Date(dat?.event_start_date);
const startMonth = startDateObj.toLocaleString("default", {
month: "short",
});
const startDay = startDateObj.getDate();
const formattedStartDate = `${startMonth} ${startDay}`;
const endDateObj = new Date(dat?.event_end_date);
const endMonth = endDateObj.toLocaleString("default", {
month: "short",
});
const endDay = endDateObj.getDate();
const formattedEndDate = `${endMonth} ${endDay}`;
return (
<div className="individual_events_card" key={i}>
<NavLink
to={`/dashboard/events/event-detail/${dat.id}`}
>
<div className="events_wrapper"></div>
</NavLink>
<img src={dat?.image} alt="" className="event_img" />
<div className="event_detail">
<h4>{dat?.title}</h4>
{/* <p className="event-content p-1 mb-2">
{String(dat?.content || "").substring(0, 100)}
</p> */}
<div className="location_container flex align-items-center mb-1">
<ion-icon
name="navigate-circle-outline"
className="location_icon"
></ion-icon>
{dat?.location || ""}
</div>
<div className="event_start_end_div ">
<div className="start_date">
<p className="font-[600]">Start Date</p>
<h6 className="font-[600]">
{formattedStartDate}
</h6>
</div>
<div className="end_date">
<p className="font-[600]">End Date</p>
<h6 className="font-[600]">{formattedEndDate}</h6>
</div>
</div>
<div className="register_add_to_calander">
<div className="event_register">
<button
className="event_register_btn"
onClick={() => {
setEventId(dat);
setIsModalOpen(true);
}}
>
Register
</button>
</div>
<div className="add_to_calendar">
<AddToCalendarButton
name={dat?.title || ""}
className="add-to-calendar-button"
options={["Apple", "Google", "Yahoo", "iCal"]}
location={dat?.location || ""}
startDate={dat?.event_start_date}
endDate={dat?.event_end_date}
description={dat?.content}
trigger="click"
size="3"
></AddToCalendarButton>
</div>
</div>
</div>
</div>
);
})}
</div>
) : (
<>
<div className="list_container">
{eventData.map((dat, i) => {
const startDateObj = new Date(dat?.event_start_date);
const startMonth = startDateObj.toLocaleString(
"default",
{
month: "short",
}
);
const startDay = startDateObj.getDate();
const formattedStartDate = `${startMonth} ${startDay}`;
const endDateObj = new Date(dat?.event_end_date);
const endMonth = endDateObj.toLocaleString("default", {
month: "short",
});
const endDay = endDateObj.getDate();
const formattedEndDate = `${endMonth} ${endDay}`;
return (
<div className="event_card relative" key={i}>
<NavLink
to={`/dashboard/events/event-detail/${dat.id}`}
>
<div className="events_wrapper"></div>
</NavLink>
{/* Left side with thumbnail image */}
<div className="thumbnail">
<img src={dat?.image} alt="Event Thumbnail" />
</div>
{/* Right side with event details */}
<div className="event-details">
{/* Top div with event title and content */}
<div className="event-header">
<h3 className="event-title mb-1">{dat?.title}</h3>
<p className="event-content">
{String(dat?.content || "").substring(0, 150)}
...
</p>
</div>
<div className="location_container flex align-items-center mb-1">
<div className="location_icon flex align-items-center mr-2">
<ion-icon name="navigate-circle-outline"></ion-icon>
</div>
{dat?.location || ""}
</div>
{/* Bottom div with date and buttons */}
<div className="event-footer font-semibold">
{/* Left div with date fields */}
<div className="event-dates">
<p className="event-date">
Start Date: {formattedStartDate}
</p>
<p className="event-date">
End Date: {formattedEndDate}
</p>
</div>
{/* Right div with buttons */}
<div className="event-buttons">
<button
className="register-button"
onClick={() => {
setEventId(dat);
setIsModalOpen(true);
}}
>
Register
</button>
<AddToCalendarButton
name={dat?.title || ""}
className="calander_btn"
options={["Apple", "Google", "Yahoo", "iCal"]}
location={dat?.location || ""}
startDate={dat?.event_start_date}
endDate={dat?.event_end_date}
description={dat?.content}
trigger="click"
size="4"
></AddToCalendarButton>
</div>
</div>
</div>
</div>
);
})}
</div>
</>
)}
</div>
)}
</div>
</>
</div>
);
};
export default Events;
Source