
이전 홈화면에서는 모든 events들을 불러와 보여주고 있음. 홈화면에서는 오늘 날짜를 기준으로 오늘 이후에 있는 행사들만 가져와 보여줌!
const fetchEvents = async () => {
try {
const events = await getDateEvents();
console.log(events);
// 날짜 객체로 변환
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);
setEvents(events);
} catch (error) {
console.log("error", error);
}
};
client에서 getDateEvents로 요청을 보냄
export const getDateEvents = async () => {
const currentDate = new Date();
const year = currentDate.getFullYear();
const month = currentDate.getMonth() + 1; // 월은 0부터 시작하므로 +1
const date = currentDate.getDate();
const { data } = await axios.get(
`${apiPath}/events?year=${year}&month=${month}&date=${date}`
);
console.log('getDateEvents: ', data)
return data;
};
현재 날짜를 기준으로 년도, 달, 날짜를 서버에 요청 보낼때 URL의 쿼리 문자열(query string)을 사용해서 year, month, date 파라미터를 서버에 전달해줌
eventRouter
.route("/")
// .get(eventCtrl.getAllEvents)
.get( (req, res, next) => {
// 클라이언트가 날짜를 제공한 경우에는 getDateEvents 호출
if (req.query.date) {
return eventCtrl.getDateEvents(req, res, next);
} else {
// 그 외의 경우에는 getAllEvents 호출
return eventCtrl.getAllEvents(req, res, next);
}
})
.post(
userCtrl.requireLogin,
userCtrl.hasRole(ROLE_NAME.staff),
eventCtrl.createEvent
);
eventrouter에서는 req.query가 있으면 날짜기준으로 이후에 있는 데이터를 불러오는 함수를 호출하고, 없으면 전체 이벤트를 불러오게 함!
export const getDateEvents = asyncHandler(async (req, res) => {
console.log("Event req.query:",req.query)
const {year , month, date} = req.query as { year: string, month: string, date: string } ;
console.log("year,month,date",year,month,date)
const result = await findDateEvents(year,month,date);
res.json(result.rows);
});
export const findDateEvents = async (year: string, month: string, date: string) => {
const startDate = new Date(`${year}-${month}-${date}`);
const result = await db.query<Event>('SELECT title,start_date FROM events WHERE start_date >= $1', [startDate]);
console.log("find event result:", result)
return result;
};
req.query로 받은 파라미터들을 DB에서 찾는데에 쓰기위해서 전달해줌.
날짜형식으로 다시 변환후에 그 날짜보다 이후에 있는 events데이터들에 title과 start_date를 가져옴!
{events.length === 0 ? (
<div className="p-2 text-center">
<Typography variant="body1">
이후 등록된 행사가 없습니다.
</Typography>
</div>
) : (
events.map((item, id) => (
<Link to="/infos/churchevents" key={id}>
<ContentBody
title={item.title}
date={getDateString(item.start_date).slice(5, 10)}
/>
</Link>
))
)}
이렇게 서버에서 받아온 event가 없으면 "이후 등록된 행사가 없습니다." 를 보여주고 있으면 map으로 한개씩 뿌려준당
교회 일정 페이지에서는 FullCalendar에서 보여주는 달에 따라서 그 달에 해당하는 이벤트들을 밑에 보여주고자 함. (원래는 모든 이벤트들을 다 보여줬음)
캘린더의 달을 바꿀때마다 화면이 refresh되는게 아니라서 서버에서는 전체 이벤트를 불러와 client쪽에서 같은 달에 해당하는 애들을 뿌려주도록 설정함!
interface CalendarProps {
events: WithId<ChurchEvent>[];
onDataChange(newData: string): void;
}
export const Calendar = ({ events , onDataChange }: CalendarProps ) => {
return (
<div className="p-3">
<FullCalendar
plugins={[dayGridPlugin]}
initialView="dayGridMonth"
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}`
onDataChange(newData)
}}
/>
</div>
);
};
fullcalendar에 datesSet을 사용해서 보여지고 있는 달이랑 년도를 합쳐서 onDataChange에 담아준당. onDataChange는 부모에서 useState로 상태를 조절함!
형제 컴포넌트간에 데이터 전달을 하는데 헷갈려서 https://velog.io/@dev_seongjoo/React%EC%97%90%EC%84%9C-%ED%98%95%EC%A0%9C-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EA%B0%84%EC%97%90-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EB%8B%AC%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%95%98%EB%82%98%EC%9A%94
여기를 참고해서 수정했다!
부모 컴포넌트에 이렇게 지정해주고 사용했다
const [viewMonth,setViewMonth] = useState('');
const handleDataChange = (newData : string) => {
setViewMonth(newData);
};
<Calendar events={events} onDataChange={handleDataChange} />
<div className="divide-y divide-slate-200">
{events.map((event) => (
<div key={event.id}>
<ChurchEventView
event={event}
selectEvent={handleSelectEvent}
onDelete={handleDelete}
viewMonth = {viewMonth}
/>
</div>
))}
</div>
viewMonth로 형제 컴포넌트간에 데이터를 전달해줬당
const currentMonth= new Date(viewMonth).getMonth();
const currentYear = new Date(viewMonth).getFullYear();
const eventMonth = event.start_date.getMonth();
const eventYear = event.start_date.getFullYear();
if (!(currentYear === eventYear && currentMonth === eventMonth)) {
return null; // 현재 년도와 월과 이벤트의 년도와 월이 다르면 이벤트를 표시하지 않음
}
전달받은 데이터를 달,년도를 추출해서 events들의 년도랑 달을 비교해서 같지않으면 아무것도 안보이게 지정해줌
3월기준 이벤트

2월기준 이벤트

홈화면에 오늘 이후 이벤트
