Hello creators ๐
240813 ์ผ์ผ ๊ฐ๋ฐ ์ผ์ง ๋ณธ๋ฌธ
[ํ๋ก ํธ์๋(FE) ๊ฐ๋ฐ] (feat. ์ฃผ๋์ด)/TIL
240813 ์ผ์ผ ๊ฐ๋ฐ ์ผ์ง
๋ถ์๋งค๋_HA 2024. 8. 13. 20:53728x90
๋ฐ์ํ
done ํ task ๊ธฐ๋ก
[240813] ์บ๋ฆฐ๋ ๊ฐ์ ธ์ค๋ ๊ตฌ์กฐ
1. ์ฌ์ฉ์๊ฐ ์ ์ฅํ๋ฉด -> DB ๋ฅผ ๊ฑฐ์ณค๋ค๊ฐ -> ๊ทธ๋ ค์ง๊ฒ ํ ๊ฒ ์ธ๊ฐ
2. ๊ตฌ๊ธ ์บ๋ฆฐ๋์ ์ ์ฅ๋ ๊ฒ์ ๊ฐ์ ธ์์ -> ๊ทธ๋ ค์ง๊ฒ ํ ๊ฒ ์ธ๊ฐ
- ์ด ์ค 2๊ฐ์ง๋ฅผ ๋ค ํ๋ค.
- ์ฌ์ค, full calendar ์์ฒด์ 'ํด์ผ' ์ ๊ฐ์ ธ์ค๋ ๊ธฐ๋ฅ์ด ์์ผ๋ฉด, ๊ตณ์ด google api ์ฐ๋์ ์ ํด๋ ๋๋ค.
[240813-1340] ๋๋ฏธdate ์ event ์๊ธฐ๊ฒ ํ๊ธฐ
- ์ฐธ๊ณ
https://bit.ly/3YGzr81 views\fullcalendar.ejs
- ํฌ์ธํธ
```bash
- ์ผ์ ์์ฑ ๋ฒํผ ํด๋ฆญ -> addEvent(calendarRef) ์ด ์คํ๋จ
- ๋ง๋ค์ด๋๊ณ -> ๋ชจ๋๋ก ๋นผ๋๊น ์ข์ โญโญโญโญโญโญโญโญโญ
- ์ด๊ฑฐ๋ฅผ ์ด์ ํ ์คํธ ํ์ผ์์ ๋นผ์ -> ํ๋ก์ ํธ์ ์ ์ฉํ ์ ์์.
<br>
- addEvent ๋ด๋ถ ๊ตฌํ
```jsx
/* 1. const calendarApi = calendarRef?.current?.getApi();
- calendarRef ์ด๊ฒ ์๋ํ๋ ค๋ฉด, FullCalendar ์ ref ์์ฑ์ ์ฐ๊ฒฐํด์, addEvent ๋ฅผ ํธ์ถํ๋ 'โญ๋ถ๋ชจ ์ปดํฌ๋ํธโญ' ์์ 'FullCalenar' ์ ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์์ผ ํ๋ค. โญโญโญโญโญ
- ์ง๊ธ ์์ ํ๋ก์ ํธ์ ๊ฒฝ์ฐ์๋ 'calendar.js' ์์!!!
- ์ด ๋ถ๋ถ์์ ์ด๋ก ์ ์ผ๋ก ๋ถ์กฑํ๋ค.
*/
<FullCalendar
ref={calendarRef} // ์ด ๋ถ๋ถ ์ถ๊ฐ โ
โ
plugins={[
resourceTimelinePlugin,
dayGridPlugin,
interactionPlugin,
timeGridPlugin,
]}
/* 2. ๊ทธ๋์, full calendar ๋ด๋ถ์ ์กด์ฌํ๋ addEvent ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ด์ผ ํ๋ค. โญโญโญ
- ์ด addEvent ๋ฅผ ๊ฐ์ ธ์ค๋ ค๋ฉด, useRef ๊ฐ ํ์์ ์ด๋ค.
*/
- ์ ์ฒด ์์ ์ฝ๋
export function addEvent(calendarRef) { const calendarApi = calendarRef?.current?.getApi(); const dateString = '2024-08-11'; const testDate = new Date(dateString + 'T00:00:00'); calendarApi?.addEvent({ title: 'ํ ์คํธ ์ ๋๋คโ โ ', start: testDate, allday: true, color: 'blue', }); }
<br>
### [240813-1340] 'calendar์ ํน์ ์ผ์'๋ฅผ 'ํด๋ฆญ'ํ๋ฉด, event ๊ฐ ์๊ธฐ๊ฒ ํ๊ธฐ
``` jsx
/* 1. 'calendar์ ํน์ ์ผ์'๋ฅผ 'ํด๋ฆญ'ํ๋ฉด ์ ์ด๋ป๊ฒ ์์?
- Full Calendar ๊ฐ ์ด๋ฏธ ๋ง๋ค์ด๋์์ ๊ฒ.
- ์ฐพ์๋ณด๋, dateClick ์์ฑ์ด ์์
-> ํด๋น ์์ฑ์ ๋ฐ์ธ๋ฉ๋๋ ํจ์(handleDateClick) ๋ฅผ ๋ฃ์ ์์ .
(์ถ์ฒ: https://fullcalendar.io/docs/dateClick)
*/
const handleDateClick = (clickedDate) => {
const {date} = clickedDate
addEvent(calendarRef, date)
debugger
}
/* 2. clickedDate ๊ฐ์ฒด ๋ด๋ถ๋ฅผ ์ด์ด๋ณด๋โญโญโญ, date ์์ฑ์ด ๋ ์ง๊ฐ์ ๊ฐ์ง๊ณ ์์์
- ๊ทธ๋์, const {date} = clickedDate ์ด๋ ๊ฒ ๊น๋ณด๊ฒ ๋จ
- ์ด๊ฑธ ์์์ ๋ง๋ addEvent ํจ์์ ์ ๋ฌํ๋ฉด ๋จ
*/
- ์ ์ฒด ์ฝ๋
// Context๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ์ปค์คํ ํ โญโญโญโญโญโญโญโญ export function useModal() { return useContext(ModalContext) }
export default function CalendarPage() {
const calendarRef = useRef(null) // ์บ๋ฆฐ๋ ์ฐธ์กฐ
const [isModalOpen, setIsModalOpen] = useState(false)
const handleDateClick = (clickedDate) => {
const {date} = clickedDate
addEvent(calendarRef, date)
debugger
}
return (
<ModalContext.Provider value={{ isModalOpen, setIsModalOpen }}>
<FullCalendar
ref={calendarRef} // ์ด ๋ถ๋ถ ์ถ๊ฐ โ โ
plugins={[
resourceTimelinePlugin,
dayGridPlugin,
interactionPlugin,
timeGridPlugin,
]}
// ์ปค์คํ ๋ฒํผ ์ถ๊ฐ
customButtons={{
createEventButton: {
text: '์ผ์ ์์ฑ',
click: function () {
addEvent(calendarRef)
// setIsModalOpen(true)
},
},
}}
headerToolbar={{
left: 'prev,next today createEventButton',
center: 'title',
right: 'resourceTimelineWeek,dayGridMonth,timeGridWeek',
}}
initialView='resourceTimelineWeek'
nowIndicator={true}
editable={true}
selectable={true}
selectMirror={true}
resources={[
{ id: 'a', title: 'Auditorium A' },
{ id: 'b', title: 'Auditorium B', eventColor: 'green' },
{ id: 'c', title: 'Auditorium C', eventColor: 'orange' },
]}
initialEvents={[
{ title: 'nice event', start: new Date(), resourceId: 'a' },
]}
dateClick={handleDateClick} // ์บ๋ฆฐ๋์ ๋ ์ง ํด๋ฆญ์ 'handleDateClick' ์คํ
/>
{isModalOpen ? <Modal setIsModalOpen={setIsModalOpen} /> : <></>}
</Layout>
</ModalContext.Provider>
)
}
<br>
### [240813-1400] '์์ฑ๋ฒํผ' ์ ํด๋ฆญํ์ ๋, event ๊ฐ ์๊ธฐ๊ฒ ํ๊ธฐ
- ๋ณ๊ฒฝ๋ ์๊ฐ
``` bash
1. ๋ ์ง๋ฅผ ํด๋ฆญํ๋ฉด, event ๋ฅผ ์์ฑํ๋๊ฒ ์๋๋ผ, '์์ฑ ๋ฒํผ' ์ ํด๋ฆญํ๋ฉด, event๊ฐ ์์ฑ๋๊ฒ ํ๋๊ฒ, ์ข ๋ ์ฐ์ ์ด๋ผ๊ณ ์๊ฐํจ
- ์๋๋ฉด, ๋ฌ๋ ฅ์ ๋ค๋ก ๋๊ธฐ๋ ค๋ฉด, ์ฌ์ค ๊ท์ฐฎ๋ค.
- ์ถํ์, ๋ฌ๋ ฅํด๋ฆญํ์ ๋ -> ์ด๋ฒคํธ๊ฐ ๋์ค๊ฒ ํ๋๊ฑธ ๋ฆฌํฉํ ๋ง ํ์
-> ๋ ์ด์ ์ ๊ฒฝ์ฐ์ง ๋ง๊ณ ๋์ด๊ฐ์ โญโญโญ | ์ฐ์ ์์๋ฅผ ์๊ฐ โญโญโญ
// 1. Modal ์ด ์ด๋ฆด ๋, calendarRef ์ ๋ฌ ํด์ผ ํ๋๋ฐ,
{isModalOpen ? (
<Modal calendarRef={calendarRef} setIsModalOpen={setIsModalOpen} />
) : (
<></>
)}
// 2. ๋ฌธ์ ๊ฐ ๋์๋ ๊ฑด, onSubmit ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์คํ๋๋ ์์ ์ด 'ํด๋ฆญ' ์ด ์๋๋ผ, 'Modal ์ด ์คํ' ๋ ๋ ์์.
// ์ด๊ฑด, onClick={onSubmit(calendarRef)} ์ด๋ ๊ฒ ์์ฑํด์ ์์
<button type='submit' onClick={()=>onSubmit(calendarRef)}> ์ ์ถ </button>
[240813-1820] google calendar ์์ 'ํด์ผ' ๊ฐ์ ธ์ค๊ธฐ
- google api key ๋ฐ๊ธ๋ฐ๊ธฐ
- ์ฐธ๊ณ : https://idealist.tistory.com/92 โญโญโญ
- ๋ฐ๊ธ๋ฐ์ api key : AIzaSyDOp-C30NyBcZVgTUER4WYZp4zBLwAPC1s
- [๋ฐ๊ธ๊ณผ์ ์์ ๋ธ๋ก๊ทธ์ ๋ค๋ฅด๊ฒ ํ๋ ๊ฒ] api key ๋ฐ๊ธ ๋ฐ๋ ๊ฒ.
- https://www.notion.so/google-calendar-12a5ca4f91e8410c9b69a21166bf0c5c
- ์ฌ๊ธฐ ๋ ธ์ ๊ธฐ๋ก ์ฐธ๊ณ
- [๋ธ๋ก๊ทธ์ ์์๊ณ , ์ค์ ๊ฐ๋ฐํ ๋๋ ๋ณด์ํด์ผ ํ๋ ๊ฒ] O Auth ์ค์ ํ๋ ๊ฒ
- ์ฌ๊ธฐ ๋ ธ์ ๊ธฐ๋ก ์ฐธ๊ณ
- https://www.notion.so/google-calendar-12a5ca4f91e8410c9b69a21166bf0c5c
[240813-1900] calendar ์์ ๋ณด์ด๋ ํ๋ฉด์, month ๋ก ์กฐ์
- ์ ์ด์ ์ฝ๋๋ ์๋์ ๊ฐ์
headerToolbar={{ left: 'prev,next today createEventButton', center: 'title', right: 'resourceTimelineWeek,dayGridMonth,timeGridWeek', }}
- ์ด๊ฑธ ์๋์ ๊ฐ์ด ์์
headerToolbar={{ left: 'prev,next today createEventButton', center: 'title', right: 'dayGridMonth,timeGridWeek', }}
[240813] DB ์์ ๋ฐ์ ์ผ์ ์ ๊ทธ๋ ค์ฃผ๊ธฐ
- ๋ฐ์ดํฐ๋ฅผ fetchedData ๋ณ์์ ์ ์ฅ
const fetchedData = [ { title: 'test event - 1', start: '2024-08-12', resourceId: 'a' , color: 'blue'}, { title: 'test event - 2', start: '2024-08-11', resourceId: 'a' , color: 'yellow'}, { title: 'test event - 3', start: '2024-08-11', end : '2024-08-16' , resourceId: 'a' , color: 'green'}, ]
events={combinedEvents}
์ด๋ ๊ฒ events ์์ฑ์ ๋ฐ์ธ๋ฉ ๋ ์ ์๊ฒ ๋ฐฐ์ด๋ก ์ค๋นconst combinedEvents = [ ...fetchedData, ...googleCalendarEvents, ]
- ์ด๋ ๊ฒ events ์์ฑ์,
๊ฐ์ฒด ์์๋ก ๋ ๋ฐฐ์ด
๋ก ๊ฝ์์ฃผ๋ฉด, ๊ทธ๋ ค์ง๋ค.
์ ๋๋ก ํ์ต์ด ํ์ํ ๋ถ๋ถ
1. ์คํ๋ ๋ ์ฐ์ฐ์ ํ์ต โญโญโญ
const fetchedData = [
{ title: 'nice event', start: '2024-08-12', resourceId: 'a' , color: 'blue'},
{ title: 'nice event', start: '2024-08-11', resourceId: 'a' , color: 'yellow'},
{ title: 'nice event', start: '2024-08-11', end : '2024-08-16' , resourceId: 'a' , color: 'green'},
]
const googleCalendarEvents = [
{
googleCalendarId : 'ko.south_korea#holiday@group.v.calendar.google.com',
className: 'holiday',
}
]
// ๐๐๐ ์ด๊ฒ ํ์ฌ ์ ์๋?
const combinedEvents = [
...fetchedData,
...googleCalendarEvents,
]
<FullCalendar
ref={calendarRef} // ์ด ๋ถ๋ถ ์ถ๊ฐ โ
โ
plugins={[
resourceTimelinePlugin,
dayGridPlugin,
interactionPlugin,
timeGridPlugin,
googleCalendarPlugin,
]}
// ์ปค์คํ
๋ฒํผ ์ถ๊ฐ
customButtons={{
createEventButton: {
text: '์ผ์ ์์ฑ',
click: function () {
// addEvent(calendarRef)
setIsModalOpen(true)
},
},
}}
headerToolbar={{
left: 'prev,next today createEventButton',
center: 'title',
right: 'resourceTimelineWeek,dayGridMonth,timeGridWeek',
}}
initialView='resourceTimelineWeek'
nowIndicator={true}
editable={true}
selectable={true}
selectMirror={true}
resources={[
{ id: 'a', title: 'Auditorium A' },
{ id: 'b', title: 'Auditorium B', eventColor: 'green' },
{ id: 'c', title: 'Auditorium C', eventColor: 'orange' },
]}
2. ๋ถ๋ชจ์์ ์์์๊ฒ useState ๋ก์จ 'set ํจ์' ๋ฅผ ๋ด๋ ค๋ณด๋ด์ค๋ค. ํ์ง๋ง, ์ด ๋ฐฉ์์ flux ํจํด์ ๋ฐํ๋ค๊ณ ํ๋ค. ๊ทธ ๋์์ผ๋ก์จ context api ๊ฐ ์ฌ์ฉ๋ ์ ์๋ ๊ฑด๊ฐ?
- ํ์ฌ gpt ์ ์๊ฒฌ์ ๋ฃ๊ณ ์์ฑํ ๊ฑด, context api ๋ฅผ ๊ทธ๋ ๊ฒ ์ด๊ฑด๋ฐ, ์ด ๋ถ๋ถ์ context api ์ ๋ํ ๊ณต๋ถ๊ฐ ํ์
๋ฆฌํฉํ ๋ง ํ ๊ฒ ๋ค
1. event ์์ฑ '๋ฒํผ' ์ด ์๋๋ผ, '๋ฌ๋ ฅ' ์ ๋๋ ์ ๋๋, ์์ฑ๋ ์ ์๊ฒ ํ๊ธฐ
728x90
๋ฐ์ํ
'[ํ๋ก ํธ์๋(FE) ๊ฐ๋ฐ] (feat. ์ฃผ๋์ด) > TIL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Comments