
현재 데이터베이스에서 이벤트를 불러올때 전체 데이터를 불러오게 되어있음!! 전체적인 데이터를 가져오는건 비효율적이라고 생각해서 Fullcalendar에서 보여지는 달에서 앞뒤달을 포함한 데이터를 가져오도록 수정함! (캘린더에 그 달에 해당하는 데이터만 가져오면 전달~해당달에 해당하는 데이터들이 안보임! 그래서 앞뒤로 한달씩 총 세달치를 가져오기로 함!)
eventRouter
.route("/")
// .get(eventCtrl.getAllEvents)
.get( (req, res, next) => {
// 클라이언트가 날짜를 제공한 경우에는 getDateEvents 호출
if (req.query.date) {
return eventCtrl.getDateEvents(req, res, next);
} else {
// 그 외의 경우에는 getMonthEvents 호출
return eventCtrl.getMonthEvents(req,res,next);
}
})
export const getMonthEvents = asyncHandler(async (req, res) => {
console.log("Event Moth req.query:",req.query)
const {year , month} = req.query as { year: string, month: string} ;
const result = await findMonthEvents(year,month);
res.json(result.rows);
});
export const findMonthEvents = async (year: string, month: string) => {
const startDate = new Date(`${year}-${month}-01`);
// 시작 날짜로부터 앞뒤 한 달씩 총 세 달치의 범위 계산
const startPreviousMonth = new Date(startDate);
startPreviousMonth.setMonth(startPreviousMonth.getMonth() - 1);
const startNextMonth = new Date(startDate);
startNextMonth.setMonth(startNextMonth.getMonth() + 1);
// 각 범위의 마지막 날짜를 계산
const lastDayOfPreviousMonth = new Date(startPreviousMonth.getFullYear(), startPreviousMonth.getMonth() + 1, 0);
const lastDayOfCurrentMonth = new Date(startDate.getFullYear(), startDate.getMonth() + 1, 0);
const lastDayOfNextMonth = new Date(startNextMonth.getFullYear(), startNextMonth.getMonth() + 1, 0);
const result = await db.query<Event>('SELECT * FROM events WHERE start_date >= $1 AND start_date <= $2 OR start_date >= $3 AND start_date <= $4 OR start_date >= $5 AND start_date <= $6 ORDER BY start_date ASC',
[startPreviousMonth, lastDayOfPreviousMonth, startDate, lastDayOfCurrentMonth, startNextMonth, lastDayOfNextMonth]);
console.log("find three months events result:", result);
return result
};
const fetchEvents = async (viewMonth: string) => {
try {
console.log("fetchEvents:", viewMonth);
const year = viewMonth.split("-")[0];
const month = viewMonth.split("-")[1];
const events = await getMonthEvents(year, month);
// 날짜 객체로 변환
events.forEach((event: WithId<ChurchEvent>) => {
event.start_date = new Date(event.start_date);
event.end_date = new Date(event.end_date);
});
// console.log("converted date fetch events", events);
const filteredEvents = events.filter((event: WithId<ChurchEvent>) => {
const eventMonth = event.start_date.getMonth();
const eventYear = event.start_date.getFullYear();
const eventEndMonth = event.end_date.getMonth();
const eventEndYear = event.end_date.getFullYear();
return (
(eventMonth === parseInt(month) - 1 &&
eventYear === parseInt(year)) ||
(eventEndMonth === parseInt(month) - 1 &&
eventEndYear === parseInt(year))
);
});
setFilteredEvents(filteredEvents);
setEvents(events);
} catch (error) {
console.log("error", error);
}
};
useEffect(() => {
const initialViewMonth = `${new Date().getFullYear()}-${(new Date().getMonth() + 1).toString()}`;
fetchEvents(initialViewMonth);
}, []);
캘린더 밑에 해당 달에 있는 이벤트들이 드롭다운으로 나오게 되어있는데, 그 데이터를 넘겨줄때는 해당달에 있는 것(filteredevents)만 넘겨줌!
<Calendar events={events} onDataChange={handleDataChange} initialDate = {initialDate}/>
<div className="divide-y divide-slate-200">
{filteredEvents.map((event) => (
<div key={event.id}>
<ChurchEventView
event={event}
selectEvent={handleSelectEvent}
onDelete={handleDelete}
/>
</div>
))}
</div>
수정하거나 새로운 이벤트를 추가했을때 수정하거나 추가한 달을 캘린더에 보여지게 하고자함! 수정하거나 추가할때의 날짜를 Calendar 컴포넌트에 initialDate props로 전달해주고 fullcalendar에 initailDate옵션을 사용함!
const handleAddOrUpdateEvent = async (
event: WithId<ChurchEvent> | ChurchEvent
) => {
let addOrUpdatedMonth=""
if ("id" in event) {
// Update Church Event
console.log("update event:", event);
const result = await updateEvent(event);
// console.log("updated event result:", result);
addOrUpdatedMonth = getDateString(new Date(event.start_date));
console.log("업데이트 달",addOrUpdatedMonth)
setInitialDate(addOrUpdatedMonth);
} else {
// Add Church Event
console.log("add new event", event);
const result = await createEvent(event);
console.log("created event result:", result.start_date);
addOrUpdatedMonth = getDateString(new Date(result.start_date));
setInitialDate(addOrUpdatedMonth);
}
await fetchEvents(addOrUpdatedMonth);
};
export const Calendar = ({ events , onDataChange, initialDate }: CalendarProps ) => {
return (
<div className="p-3">
<FullCalendar
plugins={[dayGridPlugin]}
initialView="dayGridMonth"
initialDate={initialDate}
height={"500px"}
locale={"ko"}
titleFormat={{ month: "short" }}
headerToolbar={{
start: "title",
end: "prev,today,next",
}}
buttonText={{
// prev: "이전", // 부트스트랩 아이콘으로 변경 가능
// next: "다음",
// prevYear: "이전 년도",
// nextYear: "다음 년도",
today: "오늘",
month: "월별",
week: "주별",
day: "일별",
list: "리스트",
}}
events={events.map((event) => ({
title: event.title,
start: event.start_date,
end: new Date(new Date(event.end_date).getTime() + 86400000), // 현재 날짜에 24시간(하루)을 더함
allDay: true,
}))}
datesSet={(dateInfo) => {
const viewMonth = dateInfo.view;
const month = viewMonth.title.slice(0,1);
const year = viewMonth.currentStart.getFullYear().toString(); // 현재 보고 있는 달력 뷰의 년도를 추출
const newData = `${year}-${month}`
console.log("nonth",month,"year",year,"newData",newData)
onDataChange(newData)
}}
/>
</div>
);
};
현재 fullcalendar로 보고 있는 달을 onDataChange로 infoevents로 전달하고, 전달한 값으로 데이터를 가져오고 필터링한 데이터는ChurchEventView 컴포넌트로 전달해줌! 가져온 3달치 데이터는 Calendar 컴포넌트로 전달! 그리고 수정 및 추가할때 해당하는 데이터의 날짜를 가져와 fullcalendar의 initialdate로 설정해 해당하는 달이 보여지게 수정함..!