Skip to content

Commit

Permalink
feat: timeblock 위치 수정 및 사이즈 조절(시간관리 관련) 수정 api 연결
Browse files Browse the repository at this point in the history
  • Loading branch information
Kjiw0n committed Jul 18, 2024
1 parent bb78d1e commit 557895a
Showing 1 changed file with 54 additions and 39 deletions.
93 changes: 54 additions & 39 deletions src/components/common/fullCalendar/FullCalendarBox.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import styled from '@emotion/styled';
import { ViewMountArg, DatesSetArg, EventClickArg } from '@fullcalendar/core';
import { ViewMountArg, DatesSetArg, EventClickArg, EventDropArg } from '@fullcalendar/core';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
import FullCalendar from '@fullcalendar/react';
import timeGridPlugin from '@fullcalendar/timegrid';
import { DateSelectArg } from 'fullcalendar/index.js';
import { DateSelectArg, EventResizeDoneArg } from 'fullcalendar/index.js';
import { useState, useRef, useEffect } from 'react';

import Modal from '../modal/Modal';
Expand All @@ -13,6 +13,7 @@ import processEvents from './processEvents';

import useGetTimeBlock from '@/apis/timeBlocks/getTimeBlock/query';
import usePostTimeBlock from '@/apis/timeBlocks/postTimeBlock/query';
import useUpdateTimeBlock from '@/apis/timeBlocks/updateTimeBlock/query';
import RefreshBtn from '@/components/common/button/RefreshBtn';
import DayHeaderContent from '@/components/common/fullCalendar/DayHeaderContent';
import FullCalendarLayout from '@/components/common/fullCalendar/FullCalendarStyle';
Expand All @@ -28,25 +29,41 @@ interface FullCalendarBoxProps {

function FullCalendarBox({ size, selectDate, selectedTarget }: FullCalendarBoxProps) {
const today = new Date().toDateString();
const todayDate = new Date().toISOString().split('T')[0];
const [currentView, setCurrentView] = useState('timeGridWeek');
const [range, setRange] = useState(7);
const todayDate = new Date().toISOString().split('T')[0];
const [startDate, setStartDate] = useState<string>(todayDate);

const [isModalOpen, setModalOpen] = useState(false);
const [top, setTop] = useState(0);
const [left, setLeft] = useState(0);

const calendarRef = useRef<FullCalendar>(null);

const { data: timeBlockData } = useGetTimeBlock({ startDate, range });
const { mutate: createMutate } = usePostTimeBlock();
const { mutate: updateMutate } = useUpdateTimeBlock();

const calendarEvents = timeBlockData ? processEvents(timeBlockData.data.data) : [];

useEffect(() => {
if (selectDate && calendarRef.current) {
const calendarApi = calendarRef.current.getApi();
calendarApi.gotoDate(selectDate);
}
}, [selectDate]);

const handleViewChange = (view: ViewMountArg) => {
setCurrentView(view.view.type);
updateRange(view.view.type);
};

const handleDatesSet = (dateInfo: DatesSetArg) => {
setCurrentView(dateInfo.view.type);
const currentViewType = dateInfo.view.type;
const newStartDate = new Date(dateInfo.start);
newStartDate.setDate(newStartDate.getDate() + 1);
const formattedStartDate = newStartDate.toISOString().split('T')[0];

setCurrentView(dateInfo.view.type);
setStartDate(formattedStartDate);
updateRange(currentViewType);
};
Expand All @@ -67,17 +84,6 @@ function FullCalendarBox({ size, selectDate, selectedTarget }: FullCalendarBoxPr
}
};

const calendarRef = useRef<FullCalendar>(null);
useEffect(() => {
if (selectDate && calendarRef.current) {
const calendarApi = calendarRef.current.getApi();
calendarApi.gotoDate(selectDate);
}
}, [selectDate]);

const [top, setTop] = useState(0);
const [left, setLeft] = useState(0);

const handleEventClick = (info: EventClickArg) => {
const rect = info.el.getBoundingClientRect();
const calculatedTop = rect.top;
Expand All @@ -87,56 +93,65 @@ function FullCalendarBox({ size, selectDate, selectedTarget }: FullCalendarBoxPr
setModalOpen(true);
};

/** 모달 닫기 */
const closeModal = () => {
setModalOpen(false);
};

// Get timeblock
const { data: timeBlockData } = useGetTimeBlock({ startDate, range });
console.log('timeBlockData.data.data', timeBlockData?.data.data);

const { mutate } = usePostTimeBlock();

const calendarEvents = timeBlockData ? processEvents(timeBlockData.data.data) : [];

/** 드래그해서 이벤트 추가하기 */
const addEventWhenDragged = (selectInfo: DateSelectArg) => {
if (calendarRef.current && (selectedTarget?.id === 0 || selectedTarget)) {
const calendarApi = calendarRef.current.getApi();

// 기존에 같은 id 가진 이벤트가 캘린더에 있다면 삭제
const existingEvents = calendarApi.getEvents();
existingEvents.forEach((event) => {
if (event.id === selectedTarget.id.toString()) {
event.remove();
}
});

// 이벤트 추가
calendarApi.addEvent({
id: selectedTarget.id.toString(),
title: selectedTarget.name,
start: selectInfo.startStr,
end: selectInfo.endStr,
allDay: selectInfo.allDay,
classNames: 'tasks',
extendedProps: {
taskId: selectedTarget.id,
timeBlockId: null,
},
});

// console.log('selectedTarget.name,', selectedTarget.name);

const removeTimezone = (str: string) => str.replace(/:\d{2}[+-]\d{2}:\d{2}$/, '');

const startStr = removeTimezone(selectInfo.startStr);
const endStr = removeTimezone(selectInfo.endStr);

// console.log('selectedTarget.id.toString(),', selectedTarget.id.toString());
// console.log('startStr:', startStr);
// console.log('endStr:', endStr);
createMutate({ taskId: selectedTarget.id, startTime: startStr, endTime: endStr });
}
};

const updateEvent = (info: EventDropArg | EventResizeDoneArg) => {
const { event } = info;
const { taskId, timeBlockId } = event.extendedProps;
const removeTimezone = (str: string) => str.replace(/:\d{2}[+-]\d{2}:\d{2}$/, '');

const startStr = removeTimezone(event.startStr);
const endStr = removeTimezone(event.endStr);

mutate({ taskId: selectedTarget.id, startTime: startStr, endTime: endStr });
updateMutate({ taskId, timeBlockId, startTime: startStr, endTime: endStr });
};

const handleSelect = (selectInfo: DateSelectArg) => {
if (calendarRef.current) {
const calendarApi = calendarRef.current.getApi();
calendarApi.unselect();
}

if (selectedTarget) {
addEventWhenDragged(selectInfo);
}
};

return (
<FullCalendarLayout size={size}>
<CustomButtonContainer>
Expand Down Expand Up @@ -168,7 +183,6 @@ function FullCalendarBox({ size, selectDate, selectedTarget }: FullCalendarBoxPr
selectable
nowIndicator
dayMaxEvents
// netshell에서 할당한 이벤트 : tasks, 구글 캘린더에서 가져온 이벤트 : schedule
events={calendarEvents}
buttonText={{
today: '오늘',
Expand All @@ -195,19 +209,20 @@ function FullCalendarBox({ size, selectDate, selectedTarget }: FullCalendarBoxPr
minute: '2-digit',
hour12: false,
}}
droppable={true}
droppable
eventClick={handleEventClick}
select={addEventWhenDragged}
select={handleSelect} // 선택된 날짜가 변경될 때마다 호출
eventDrop={updateEvent} // 기존 이벤트 드래그 수정 핸들러
eventResize={updateEvent} // 기존 이벤트 리사이즈 수정 핸들러
/>
{isModalOpen && (
// 🚨 임시 taskID ... 데이터 형식 확정 후 수정할 것 🚨
<Modal
isOpen={isModalOpen}
sizeType={{ type: 'short' }}
top={top}
left={left}
onClose={closeModal}
taskId={5}
taskId={5} // 예시 taskId, 실제 데이터로 교체 필요
/>
)}
</FullCalendarLayout>
Expand Down

0 comments on commit 557895a

Please sign in to comment.