Skip to content

Commit

Permalink
Feat: #204 일정 수정 모달에서 일정 상세 모달로 돌아가기 버튼 추가 (#205)
Browse files Browse the repository at this point in the history
* Feat: #204 일정 정보 수정후 모달을 닫는 기능 제거

* Feat: ModalButton의 버튼 text 색상 props로 전환

* Feat: #204 일정 상세보기 모달 props 변경, 단일 일정 검색 추가

* Refactor: #204 캘린더 일정 hover시 가시성 개선

* Refactor: #204 QueryFilter 옵션 수정을 통한 refetch 요청 최소화

* Feat: #204 일정 목록 로딩시 대체 UI(Spinner)가 나오도록 수정

* Comment: #204 React Reparenting 문제 주석 추가

* Fix: #204 useEffect 의존성 추가

* UI: #204 돌아가기 버튼 margin 간격 조정
  • Loading branch information
Seok93 authored Oct 14, 2024
1 parent aa79669 commit 4ae00e8
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 103 deletions.
5 changes: 3 additions & 2 deletions src/components/modal/ModalButton.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
type ModalButtonProps = React.PropsWithChildren<{
formId?: string;
color: 'text-white' | 'text-emphasis' | 'text-default';
backgroundColor: 'bg-main' | 'bg-delete' | 'bg-sub' | 'bg-button' | 'bg-kakao';
onClick?: () => void;
}>;

export default function ModalButton({ formId, backgroundColor, onClick, children }: ModalButtonProps) {
export default function ModalButton({ formId, color, backgroundColor, onClick, children }: ModalButtonProps) {
const handleClick = () => onClick && onClick();

return (
<button
type={formId ? 'submit' : 'button'}
form={formId}
className={`h-25 w-full rounded-md px-10 text-white outline-none ${backgroundColor} hover:brightness-90`}
className={`h-25 w-full rounded-md px-10 font-bold outline-none ${color} ${backgroundColor} hover:brightness-90`}
onClick={handleClick}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function CreateModalProjectStatus({ project, onClose: handleClose
<ModalPortal>
<ModalLayout onClose={handleClose}>
<ModalProjectStatusForm formId={createStatusFormId} project={project} onSubmit={handleSubmit} />
<ModalButton formId={createStatusFormId} backgroundColor="bg-main">
<ModalButton formId={createStatusFormId} color="text-white" backgroundColor="bg-main">
등록
</ModalButton>
</ModalLayout>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ export default function UpdateModalProjectStatus({
onSubmit={handleSubmit}
/>
<div className="flex min-h-25 w-4/5 gap-10">
<ModalButton formId={updateStatusFormId} backgroundColor="bg-main">
<ModalButton formId={updateStatusFormId} color="text-white" backgroundColor="bg-main">
수정
</ModalButton>
<ModalButton backgroundColor="bg-delete" onClick={() => handleDeleteClick(statusId)}>
<ModalButton color="text-white" backgroundColor="bg-delete" onClick={() => handleDeleteClick(statusId)}>
삭제
</ModalButton>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/modal/project/CreateModalProject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function CreateModalProject({ onClose: handleClose }: CreateModal
<ModalPortal>
<ModalLayout onClose={handleClose}>
<ModalProjectForm formId={createProjectFormId} onSubmit={handleSubmit} />
<ModalButton formId={createProjectFormId} backgroundColor="bg-main">
<ModalButton formId={createProjectFormId} color="text-white" backgroundColor="bg-main">
등록
</ModalButton>
</ModalLayout>
Expand Down
7 changes: 6 additions & 1 deletion src/components/modal/project/UpdateModalProject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ export default function UpdateModalProject({ projectId, onClose: handleClose }:
<ModalPortal>
<ModalLayout onClose={handleClose}>
<ModalProjectForm formId={updateProjectFormId} projectId={projectId} onSubmit={handleSubmit} />
<ModalButton formId={updateProjectFormId} backgroundColor="bg-main" onClick={handleUpdateClick}>
<ModalButton
formId={updateProjectFormId}
color="text-white"
backgroundColor="bg-main"
onClick={handleUpdateClick}
>
수정
</ModalButton>
</ModalLayout>
Expand Down
2 changes: 1 addition & 1 deletion src/components/modal/task/CreateModalTask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default function CreateModalTask({ project, onClose: handleClose }: Creat
<ModalPortal>
<ModalLayout onClose={handleClose}>
<ModalTaskForm formId={createTaskFormId} project={project} onSubmit={handleSubmit} />
<ModalButton formId={createTaskFormId} backgroundColor="bg-main">
<ModalButton formId={createTaskFormId} color="text-white" backgroundColor="bg-main">
등록
</ModalButton>
</ModalLayout>
Expand Down
46 changes: 26 additions & 20 deletions src/components/modal/task/DetailModalTask.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useMemo } from 'react';
import { LuDownload } from 'react-icons/lu';
import ModalPortal from '@components/modal/ModalPortal';
import ModalLayout from '@layouts/ModalLayout';
Expand All @@ -10,31 +9,38 @@ import { downloadTaskFile } from '@services/taskService';
import useAxios from '@hooks/useAxios';
import useToast from '@hooks/useToast';
import { useReadStatuses } from '@hooks/query/useStatusQuery';
import { useDeleteTask, useReadAssignees, useReadTaskFiles } from '@hooks/query/useTaskQuery';
import { useDeleteTask, useReadAssignees, useReadStatusTasks, useReadTaskFiles } from '@hooks/query/useTaskQuery';

import type { Task } from '@/types/TaskType';
import type { Project } from '@/types/ProjectType';
import type { ProjectStatus } from '@/types/ProjectStatusType';

type ViewModalTaskProps = {
project: Project;
task: Task;
projectId: Project['projectId'];
statusId: ProjectStatus['statusId'];
taskId: Task['taskId'];
openUpdateModal: () => void;
onClose: () => void;
};

export default function DetailModalTask({ project, task, openUpdateModal, onClose: handleClose }: ViewModalTaskProps) {
const { mutate: deleteTaskMutate } = useDeleteTask(project.projectId);
const { status, isStatusLoading } = useReadStatuses(project.projectId, task.statusId);
const { assigneeList, isAssigneeLoading } = useReadAssignees(project.projectId, task.taskId);
const { taskFileList, isTaskFileLoading } = useReadTaskFiles(project.projectId, task.taskId);
export default function DetailModalTask({
projectId,
statusId,
taskId,
openUpdateModal,
onClose: handleClose,
}: ViewModalTaskProps) {
const { mutate: deleteTaskMutate } = useDeleteTask(projectId);
const { status, isStatusLoading } = useReadStatuses(projectId, statusId);
const { task, isTaskLoading } = useReadStatusTasks(projectId, taskId);
const { assigneeList, isAssigneeLoading } = useReadAssignees(projectId, taskId);
const { taskFileList, isTaskFileLoading } = useReadTaskFiles(projectId, taskId);
const { fetchData } = useAxios(downloadTaskFile);
const { toastError } = useToast();

const { taskName, startDate, endDate } = task;
const period = useMemo(
() => (endDate && startDate !== endDate ? `${startDate} - ${endDate}` : startDate),
[startDate, endDate],
);
const getTaskPeriod = ({ startDate, endDate }: Task) => {
return endDate && startDate !== endDate ? `${startDate} - ${endDate}` : startDate;
};

const handleUpdateClick = () => {
openUpdateModal();
Expand All @@ -45,7 +51,7 @@ export default function DetailModalTask({ project, task, openUpdateModal, onClos
const handleDeleteClick = (taskId: Task['taskId']) => deleteTaskMutate(taskId);

const handleDownloadClick = async (originName: string, uploadName: string) => {
const response = await fetchData(project.projectId, task.taskId, uploadName);
const response = await fetchData(projectId, taskId, uploadName);
if (response == null) return toastError('파일 다운로드 중 문제가 발생했습니다. 잠시 후 다시 시도해주세요.');

const blob = new Blob([response.data], { type: response.headers['content-type'] });
Expand All @@ -64,7 +70,7 @@ export default function DetailModalTask({ project, task, openUpdateModal, onClos
return (
<ModalPortal>
<ModalLayout onClose={handleClose}>
{isStatusLoading || isAssigneeLoading || isTaskFileLoading ? (
{isStatusLoading || isTaskLoading || isAssigneeLoading || isTaskFileLoading || !task ? (
<Spinner />
) : (
<article className="flex h-full flex-col justify-center gap-20">
Expand All @@ -77,11 +83,11 @@ export default function DetailModalTask({ project, task, openUpdateModal, onClos
</div>
<div className="flex gap-10">
<h2 className="w-50 shrink-0 text-large font-bold">일정명</h2>
<span>{taskName}</span>
<span>{task.taskName}</span>
</div>
<div className="flex gap-10">
<h2 className="w-50 shrink-0 text-large font-bold">기간</h2>
<span>{period}</span>
<span>{getTaskPeriod(task)}</span>
</div>
<div className="flex gap-10">
<h2 className="w-50 shrink-0 text-large font-bold">수행자</h2>
Expand Down Expand Up @@ -119,10 +125,10 @@ export default function DetailModalTask({ project, task, openUpdateModal, onClos
)}
</section>
<div className="flex min-h-25 gap-10">
<ModalButton backgroundColor="bg-main" onClick={handleUpdateClick}>
<ModalButton color="text-white" backgroundColor="bg-main" onClick={handleUpdateClick}>
수정
</ModalButton>
<ModalButton backgroundColor="bg-delete" onClick={() => handleDeleteClick(task.taskId)}>
<ModalButton color="text-white" backgroundColor="bg-delete" onClick={() => handleDeleteClick(taskId)}>
삭제
</ModalButton>
</div>
Expand Down
38 changes: 26 additions & 12 deletions src/components/modal/task/UpdateModalTask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,16 @@ import type { ProjectSearchCallback } from '@/types/SearchCallbackType';
type UpdateModalTaskProps = {
project: Project;
taskId: Task['taskId'];
openDetailModal: () => void;
onClose: () => void;
};

export default function UpdateModalTask({ project, taskId, onClose: handleClose }: UpdateModalTaskProps) {
export default function UpdateModalTask({
project,
taskId,
openDetailModal,
onClose: handleClose,
}: UpdateModalTaskProps) {
const updateTaskFormId = 'updateTaskForm';
const { projectId, startDate, endDate } = project;

Expand Down Expand Up @@ -126,10 +132,13 @@ export default function UpdateModalTask({ project, taskId, onClose: handleClose
return <Spinner />;
}

const handleFormSubmit: SubmitHandler<TaskUpdateForm> = async (formData) => {
updateTaskInfoMutate(formData);
const handleFormSubmit: SubmitHandler<TaskUpdateForm> = async (formData) => updateTaskInfoMutate(formData);

const handleDetailClick = () => {
openDetailModal();
handleClose();
};

return (
<ModalPortal>
<ModalLayout onClose={handleClose}>
Expand Down Expand Up @@ -168,7 +177,7 @@ export default function UpdateModalTask({ project, taskId, onClose: handleClose
<MarkdownEditor id="content" label="내용" contentFieldName="content" />
</form>
</FormProvider>
<ModalButton formId={updateTaskFormId} backgroundColor="bg-main">
<ModalButton formId={updateTaskFormId} color="text-white" backgroundColor="bg-main">
수정
</ModalButton>
</>
Expand Down Expand Up @@ -196,14 +205,19 @@ export default function UpdateModalTask({ project, taskId, onClose: handleClose
{isTaskFileLoading ? (
<Spinner />
) : (
<FileDropZone
id="files"
label="첨부파일"
files={taskFileList}
accept={TASK_SETTINGS.FILE_ACCEPT}
updateFiles={updateTaskFiles}
onFileDeleteClick={handleFileDeleteClick}
/>
<section className="space-y-20">
<FileDropZone
id="files"
label="첨부파일"
files={taskFileList}
accept={TASK_SETTINGS.FILE_ACCEPT}
updateFiles={updateTaskFiles}
onFileDeleteClick={handleFileDeleteClick}
/>
<ModalButton color="text-emphasis" backgroundColor="bg-button" onClick={handleDetailClick}>
돌아가기
</ModalButton>
</section>
)}
</ModalLayout>
</ModalPortal>
Expand Down
2 changes: 1 addition & 1 deletion src/components/modal/team/CreateModalTeam.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function CreateModalTeam({ onClose: handleClose }: CreateModalPro
<ModalPortal>
<ModalLayout onClose={handleClose}>
<ModalTeamForm formId={createTeamFormId} onSubmit={handleSubmit} />
<ModalButton formId={createTeamFormId} backgroundColor="bg-main">
<ModalButton formId={createTeamFormId} color="text-white" backgroundColor="bg-main">
등록
</ModalButton>
</ModalLayout>
Expand Down
2 changes: 1 addition & 1 deletion src/components/modal/team/UpdateModalTeam.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export default function UpdateModalTeam({ teamId, onClose: handleClose }: Update
</form>
</FormProvider>

<ModalButton formId={updateTeamFormId} backgroundColor="bg-main">
<ModalButton formId={updateTeamFormId} color="text-white" backgroundColor="bg-main">
수정
</ModalButton>

Expand Down
2 changes: 1 addition & 1 deletion src/components/task/calendar/CustomEventWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function CustomEventWrapper(props: EventWrapperProps<CustomEvent>
return (
<div
style={{ backgroundColor: event.task.colorCode }}
className={`overflow-hidden text-ellipsis rounded-md px-3 py-1 ${continuesClass}`}
className={`overflow-hidden text-ellipsis rounded-md px-3 py-1 ${continuesClass} hover:brightness-90`}
>
{children}
</div>
Expand Down
20 changes: 17 additions & 3 deletions src/components/task/kanban/TaskItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ type TaskItemProps = {
colorCode: ProjectStatus['colorCode'];
};

// ToDo: React Reparenting 관련된 문제가 있음.
export default function TaskItem({ task, colorCode }: TaskItemProps) {
const { project } = useProjectContext();
const { showModal: showDetailModal, openModal: openDetailModal, closeModal: closeDetailModal } = useModal();
const { showModal: showUpdateModal, openModal: openUpdateModal, closeModal: closeUpdateModal } = useModal();

const { taskId, taskName, sortOrder } = task;
const { taskId, statusId, taskName, sortOrder } = task;
const index = useMemo(() => sortOrder - 1, [sortOrder]);
const draggableId = useMemo(() => generatePrefixId(taskId, DND_DRAGGABLE_PREFIX.TASK), [taskId]);

Expand All @@ -45,9 +46,22 @@ export default function TaskItem({ task, colorCode }: TaskItemProps) {
)}
</Draggable>
{showDetailModal && (
<DetailModalTask project={project} task={task} openUpdateModal={openUpdateModal} onClose={closeDetailModal} />
<DetailModalTask
projectId={project.projectId}
statusId={statusId}
taskId={taskId}
openUpdateModal={openUpdateModal}
onClose={closeDetailModal}
/>
)}
{showUpdateModal && (
<UpdateModalTask
project={project}
taskId={taskId}
openDetailModal={openDetailModal}
onClose={closeUpdateModal}
/>
)}
{showUpdateModal && <UpdateModalTask project={project} taskId={task.taskId} onClose={closeUpdateModal} />}
</>
);
}
2 changes: 1 addition & 1 deletion src/hooks/query/useTaskQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export function useUpdateTaskInfo(projectId: Project['projectId'], taskId: Task[
onError: () => toastError('일정 정보 수정에 실패했습니다. 잠시 후 다시 시도해 주세요.'),
onSuccess: () => {
toastSuccess('일정 정보를 수정했습니다.');
queryClient.invalidateQueries({ queryKey: tasksQueryKey });
queryClient.invalidateQueries({ queryKey: tasksQueryKey, exact: true });
},
});

Expand Down
Loading

0 comments on commit 4ae00e8

Please sign in to comment.