Skip to content

Commit

Permalink
feat: timeblock delete api 연결
Browse files Browse the repository at this point in the history
  • Loading branch information
Kjiw0n committed Jul 18, 2024
1 parent 53ff83b commit 5587a55
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 25 deletions.
4 changes: 4 additions & 0 deletions src/apis/timeBlocks/deleteTimeBlock/DeleteTimeBlockType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface DeleteTimeBlokType {
taskId: number;
timeBlockId: number;
}
10 changes: 10 additions & 0 deletions src/apis/timeBlocks/deleteTimeBlock/axios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { DeleteTimeBlokType } from './DeleteTimeBlockType';

import { privateInstance } from '@/apis/instance';

/** TimeBlock 삭제 */
const deleteTimeBlock = async ({ taskId, timeBlockId }: DeleteTimeBlokType) => {
await privateInstance.delete(`/api/tasks/${taskId}/time-blocks/${timeBlockId}`);
};

export default deleteTimeBlock;
17 changes: 17 additions & 0 deletions src/apis/timeBlocks/deleteTimeBlock/query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';

import deleteTimeBlock from './axios';
import { DeleteTimeBlokType } from './DeleteTimeBlockType';

/** TimeBlock 삭제 */
const useDeleteTimeBlock = () => {
const queryClient = useQueryClient();
const mutation = useMutation({
mutationFn: ({ taskId, timeBlockId }: DeleteTimeBlokType) => deleteTimeBlock({ taskId, timeBlockId }),
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['timeblock'] }),
});

return { mutate: mutation.mutate };
};

export default useDeleteTimeBlock;
38 changes: 26 additions & 12 deletions src/components/common/fullCalendar/FullCalendarBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ function FullCalendarBox({ size, selectDate, selectedTarget }: FullCalendarBoxPr
const [startDate, setStartDate] = useState<string>(todayDate);

const [isModalOpen, setModalOpen] = useState(false);
const [modalTaskId, setModalTaskId] = useState<number | null>(null);
const [modalTimeBlockId, setModalTimeBlockId] = useState<number | null>(null);

const handleViewChange = (view: ViewMountArg) => {
setCurrentView(view.view.type);
Expand Down Expand Up @@ -84,21 +86,38 @@ function FullCalendarBox({ size, selectDate, selectedTarget }: FullCalendarBoxPr
const adjustedTop = Math.min(calculatedTop, MODAL.SCREEN_HEIGHT - MODAL.TASK_MODAL_HEIGHT);
setTop(adjustedTop);
setLeft(rect.left - MODAL.TASK_MODAL_WIDTH + 40);
setModalOpen(true);

// eslint-disable-next-line no-underscore-dangle
const clickedEvent = info.event._def.extendedProps;

if (clickedEvent) {
setModalTaskId(clickedEvent.taskId);
setModalTimeBlockId(clickedEvent.timeBlockId);
setModalOpen(true);
}
};

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

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

const { mutate } = usePostTimeBlock();

const calendarEvents = timeBlockData ? processEvents(timeBlockData.data.data) : [];
const { events, taskEvents } = timeBlockData
? processEvents(timeBlockData.data.data)
: { events: [], taskEvents: [] };

// TODO: 캘린더 모달 상세조회 부분 구현 시 해당 부분 참고
console.log('taskEvents', taskEvents);

const calendarEvents = timeBlockData ? events : [];

/** 드래그해서 이벤트 추가하기 */
const addEventWhenDragged = (selectInfo: DateSelectArg) => {
Expand All @@ -123,20 +142,15 @@ function FullCalendarBox({ size, selectDate, selectedTarget }: FullCalendarBoxPr
classNames: 'tasks',
});

// 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);

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

return (
<FullCalendarLayout size={size}>
<CustomButtonContainer>
Expand Down Expand Up @@ -199,15 +213,15 @@ function FullCalendarBox({ size, selectDate, selectedTarget }: FullCalendarBoxPr
eventClick={handleEventClick}
select={addEventWhenDragged}
/>
{isModalOpen && (
// 🚨 임시 taskID ... 데이터 형식 확정 후 수정할 것 🚨
{isModalOpen && modalTaskId !== null && modalTimeBlockId !== null && (
<Modal
isOpen={isModalOpen}
sizeType={{ type: 'short' }}
top={top}
left={left}
onClose={closeModal}
taskId={5}
taskId={modalTaskId}
timeBlockId={modalTimeBlockId}
/>
)}
</FullCalendarLayout>
Expand Down
23 changes: 19 additions & 4 deletions src/components/common/fullCalendar/processEvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,33 @@ interface EventData {
classNames: string;
}

const processEvents = (timeBlockData: TimeBlockData): EventData[] => {
interface TasksEventData {
taskId: number;
timeBlockId: number;
title: string;
start: string;
end: string;
allDay?: boolean;
classNames: string;
}

const processEvents = (timeBlockData: TimeBlockData): { events: EventData[]; taskEvents: TasksEventData[] } => {
const events: EventData[] = [];
const taskEvents: TasksEventData[] = [];

// tasks 데이터 처리
timeBlockData.tasks.forEach((task) => {
task.timeBlocks.forEach((timeBlock) => {
events.push({
const taskEvent = {
taskId: task.id,
timeBlockId: timeBlock.id,
title: task.name,
start: timeBlock.startTime,
end: timeBlock.endTime,
classNames: 'tasks',
});
};
events.push(taskEvent);
taskEvents.push(taskEvent);
});
});

Expand All @@ -36,7 +51,7 @@ const processEvents = (timeBlockData: TimeBlockData): EventData[] => {
});
});

return events;
return { events, taskEvents };
};

export default processEvents;
19 changes: 15 additions & 4 deletions src/components/common/modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import styled from '@emotion/styled';

import ModalBackdrop from './ModalBackdrop';

import useDeleteTimeBlock from '@/apis/timeBlocks/deleteTimeBlock/query';
import BtnDate from '@/components/common/BtnDate/BtnDate';
import OkayCancelBtn from '@/components/common/button/OkayCancelBtn';
import ModalHeaderBtn from '@/components/common/modal/ModalHeaderBtn';
Expand All @@ -16,12 +17,12 @@ interface ModalProps {
left: number;
onClose: () => void;
taskId: number;
timeBlockId: number;
}

function Modal({ isOpen, sizeType, top, left, onClose, taskId }: ModalProps) {
// taskId 가지고 api로 상세정보 요청하면 됨
function Modal({ isOpen, sizeType, top, left, onClose, taskId, timeBlockId }: ModalProps) {
const dummyData = {
id: taskId, // 안쓰는 변수 린트 통과용 필드
id: taskId,
name: 'task name',
description: 'task description',
deadLine: {
Expand All @@ -35,13 +36,23 @@ function Modal({ isOpen, sizeType, top, left, onClose, taskId }: ModalProps) {
endTime: '2024-07-08T14:30',
},
};

const { mutate } = useDeleteTimeBlock();

const handleDelete = () => {
console.log('taskId, timeBlockId', taskId, timeBlockId);
mutate({ taskId, timeBlockId });

onClose();
};

return (
isOpen && (
<ModalBackdrop onClick={onClose}>
<ModalLayout type={sizeType.type} top={top} left={left} onClick={(e) => e.stopPropagation()}>
<ModalHeader>
<BtnDate date={dummyData.deadLine.date} time={dummyData.deadLine.time} />
<ModalHeaderBtn type={sizeType.type} />
<ModalHeaderBtn type={sizeType.type} onDelete={handleDelete} />
</ModalHeader>
<ModalBody>
<TextInputBox type={sizeType.type} name={dummyData.name} desc={dummyData.description} />
Expand Down
8 changes: 6 additions & 2 deletions src/components/common/modal/ModalDeleteBtn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { useState } from 'react';
import SettingDeleteBtn from '@/components/common/button/settingBtn/SettingDeleteBtn';
import ModalDeleteDetail from '@/components/common/modal/ModalDeleteDetail';

function ModalDeleteBtn() {
interface ModalDeleteBtnProps {
onDelete: (e: React.MouseEvent) => void;
}

function ModalDeleteBtn({ onDelete }: ModalDeleteBtnProps) {
const [isClicked, setIsClicked] = useState(false);

const [top, setTop] = useState(0);
Expand All @@ -22,7 +26,7 @@ function ModalDeleteBtn() {
<SettingDeleteBtn size="big" isHover isPressed={false} isActive onClick={handleBtnClick} />
{isClicked && (
<ModalDeleteDetailWapper>
<ModalDeleteDetail top={top} left={left} onClose={handleBtnClick} />
<ModalDeleteDetail top={top} left={left} onClose={handleBtnClick} onDelete={onDelete} />
</ModalDeleteDetailWapper>
)}
</ModalDeleteBtnLayout>
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/modal/ModalDeleteDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface ModalDeleteDetailProps {
top: number;
left: number;
onClose: (e: React.MouseEvent) => void;
onDelete?: () => void;
onDelete: (e: React.MouseEvent) => void;
}

function ModalDeleteDetail({ top, left, onClose, onDelete }: ModalDeleteDetailProps) {
Expand Down
8 changes: 6 additions & 2 deletions src/components/common/modal/ModalHeaderBtn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import SettingCheckBtn from '@/components/common/button/settingBtn/SettingCheckB
import ModalDeleteBtn from '@/components/common/modal/ModalDeleteBtn';
import { SizeType } from '@/types/textInputType';

function ModalHeaderBtn({ type }: SizeType) {
interface ModalHeaderBtnProps extends SizeType {
onDelete: () => void;
}

function ModalHeaderBtn({ type, onDelete }: ModalHeaderBtnProps) {
return (
<ModalHeaderBtnLayout>
<ModalDeleteBtn />
<ModalDeleteBtn onDelete={onDelete} />
{type === 'long' && <SettingCheckBtn type="progress" size="big" isHover isPressed={false} isActive />}
<SettingCheckBtn type="complete" size="big" isHover isPressed={false} isActive />
</ModalHeaderBtnLayout>
Expand Down

0 comments on commit 5587a55

Please sign in to comment.