MIF_E31222881/resources/js/Components/CalendarView/index.jsx

146 lines
5.6 KiB
JavaScript

import { useEffect, useState } from "react";
import ChevronLeftIcon from "@heroicons/react/24/solid/ChevronLeftIcon";
import ChevronRightIcon from "@heroicons/react/24/solid/ChevronRightIcon";
import moment from "moment";
import { CALENDAR_EVENT_STYLE } from "./util";
const THEME_BG = CALENDAR_EVENT_STYLE
function CalendarView({calendarEvents, addNewEvent, openDayDetail}){
const today = moment().startOf('day')
const weekdays = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
const colStartClasses = [
"",
"col-start-2",
"col-start-3",
"col-start-4",
"col-start-5",
"col-start-6",
"col-start-7",
];
const [firstDayOfMonth, setFirstDayOfMonth] = useState(moment().startOf('month'))
const [events, setEvents] = useState([])
const [currMonth, setCurrMonth] = useState(() => moment(today).format("MMM-yyyy"));
useEffect(() => {
setEvents(calendarEvents)
}, [calendarEvents])
const allDaysInMonth = ()=> {
let start = moment(firstDayOfMonth).startOf('week')
let end = moment(moment(firstDayOfMonth).endOf('month')).endOf('week')
var days = [];
var day = start;
while (day <= end) {
days.push(day.toDate());
day = day.clone().add(1, 'd');
}
return days
}
const getEventsForCurrentDate = (date) => {
let filteredEvents = events.filter((e) => {return moment(date).isSame(moment(e.startTime), 'day') } )
if(filteredEvents.length > 2){
let originalLength = filteredEvents.length
filteredEvents = filteredEvents.slice(0, 2)
filteredEvents.push({title : `${originalLength - 2} more`, theme : "MORE"})
}
return filteredEvents
}
const openAllEventsDetail = (date, theme) => {
if(theme != "MORE")return 1
let filteredEvents = events.filter((e) => {return moment(date).isSame(moment(e.startTime), 'day') } ).map((e) => {return {title : e.title, theme : e.theme}})
openDayDetail({filteredEvents, title : moment(date).format("D MMM YYYY")})
}
const isToday = (date) => {
return moment(date).isSame(moment(), 'day');
}
const isDifferentMonth = (date) => {
return moment(date).month() != moment(firstDayOfMonth).month()
}
const getPrevMonth = (event) => {
const firstDayOfPrevMonth = moment(firstDayOfMonth).add(-1, 'M').startOf('month');
setFirstDayOfMonth(firstDayOfPrevMonth)
setCurrMonth(moment(firstDayOfPrevMonth).format("MMM-yyyy"));
};
const getCurrentMonth = (event) => {
const firstDayOfCurrMonth = moment().startOf('month');
setFirstDayOfMonth(firstDayOfCurrMonth)
setCurrMonth(moment(firstDayOfCurrMonth).format("MMM-yyyy"));
};
const getNextMonth = (event) => {
const firstDayOfNextMonth = moment(firstDayOfMonth).add(1, 'M').startOf('month');
setFirstDayOfMonth(firstDayOfNextMonth)
setCurrMonth(moment(firstDayOfNextMonth).format("MMM-yyyy"));
};
return(
<>
<div className="w-full bg-base-100 p-4 rounded-lg">
<div className="flex items-center justify-between">
<div className="flex justify-normal gap-2 sm:gap-4">
<p className="font-semibold text-xl w-48">
{moment(firstDayOfMonth).format("MMMM yyyy").toString()}<span className="text-xs ml-2 ">Beta</span>
</p>
<button className="btn btn-square btn-sm btn-ghost" onClick={getPrevMonth}><ChevronLeftIcon
className="w-5 h-5"
/></button>
<button className="btn btn-sm btn-ghost normal-case" onClick={getCurrentMonth}>
Current Month</button>
<button className="btn btn-square btn-sm btn-ghost" onClick={getNextMonth}><ChevronRightIcon
className="w-5 h-5"
/></button>
</div>
<div>
<button className="btn btn-sm btn-ghost btn-outline normal-case" onClick={addNewEvent}>Add New Event</button>
</div>
</div>
<div className="my-4 divider" />
<div className="grid grid-cols-7 gap-6 sm:gap-12 place-items-center">
{weekdays.map((day, key) => {
return (
<div className="text-xs capitalize" key={key}>
{day}
</div>
);
})}
</div>
<div className="grid grid-cols-7 mt-1 place-items-center">
{allDaysInMonth().map((day, idx) => {
return (
<div key={idx} className={colStartClasses[moment(day).day().toString()] + " border border-solid w-full h-28 "}>
<p className={`inline-block flex items-center justify-center h-8 w-8 rounded-full mx-1 mt-1 text-sm cursor-pointer hover:bg-base-300 ${isToday(day) && " bg-blue-100 dark:bg-blue-400 dark:hover:bg-base-300 dark:text-white"} ${isDifferentMonth(day) && " text-slate-400 dark:text-slate-600"}`} onClick={() => addNewEvent(day)}> { moment(day).format("D") }</p>
{
getEventsForCurrentDate(day).map((e, k) => {
return <p key={k} onClick={() => openAllEventsDetail(day, e.theme)} className={`text-xs px-2 mt-1 truncate ${THEME_BG[e.theme] || ""}`}>{e.title}</p>
})
}
</div>
);
})}
</div>
</div>
</>
)
}
export default CalendarView