Skip to content

Commit 0ceef02

Browse files
authored
[Fix] 카드, 칼럼 상태 변경 오류 해결
[Fix] 카드, 칼럼 상태 변경오류 해결
2 parents 57bd5e3 + 221f1e4 commit 0ceef02

File tree

14 files changed

+100
-92
lines changed

14 files changed

+100
-92
lines changed

src/api/columns.ts

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import axiosInstance from "./axiosInstance";
33
import { apiRoutes } from "./apiRoutes";
44
import { TEAM_ID } from "@/constants/team";
55

6-
// 칼럼 생성
6+
// 칼럼 생성
77
export const createColumn = async ({
88
title,
99
dashboardId,
@@ -19,8 +19,11 @@ export const createColumn = async ({
1919
return res.data;
2020
};
2121

22-
// 칼럼 목록 조회
23-
export const getColumns = async ({ dashboardId }: { dashboardId: number }) => {
22+
export const getColumns = async ({
23+
dashboardId,
24+
}: {
25+
dashboardId: number;
26+
}): Promise<ColumnType[]> => {
2427
const res = await axiosInstance.get(apiRoutes.columns(), {
2528
params: {
2629
dashboardId,
@@ -29,8 +32,7 @@ export const getColumns = async ({ dashboardId }: { dashboardId: number }) => {
2932

3033
return res.data;
3134
};
32-
33-
// 칼럼 수정
35+
// 칼럼 수정
3436
export const updateColumn = async ({
3537
columnId,
3638
title,
@@ -44,22 +46,8 @@ export const updateColumn = async ({
4446
return res.data;
4547
};
4648

47-
// 칼럼 삭제
49+
// 칼럼 삭제
4850
export const deleteColumn = async ({ columnId }: { columnId: number }) => {
4951
const res = await axiosInstance.delete(apiRoutes.columnDetail(columnId));
5052
return res;
5153
};
52-
53-
export const getColumn = async ({
54-
dashboardId,
55-
}: {
56-
dashboardId: number;
57-
columnId: number;
58-
}) => {
59-
const res = await axiosInstance.get(apiRoutes.columns(), {
60-
params: {
61-
dashboardId,
62-
},
63-
});
64-
return res.data.data;
65-
};

src/components/columnCard/Column.tsx

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
// Column.tsx
21
import { useEffect, useState, useRef } from "react";
32
import Image from "next/image";
4-
import { CardType } from "@/types/task";
3+
import { CardType, ColumnType } from "@/types/task";
54
import TaskModal from "@/components/modalInput/TaskModal";
65
import { TodoButton, ShortTodoButton } from "@/components/button/TodoButton";
76
import ColumnDeleteModal from "@/components/columnCard/ColumnDeleteModal";
@@ -24,6 +23,7 @@ type ColumnProps = {
2423
createdByMe: boolean;
2524
columnDelete: (columnId: number) => void;
2625
fetchColumnsAndCards: () => void;
26+
columns: ColumnType[];
2727
};
2828

2929
export default function Column({
@@ -34,6 +34,7 @@ export default function Column({
3434
createdByMe,
3535
columnDelete,
3636
fetchColumnsAndCards,
37+
columns,
3738
}: ColumnProps) {
3839
const { canEditColumns } = useDashboardPermission(dashboardId, createdByMe);
3940

@@ -56,10 +57,8 @@ export default function Column({
5657

5758
const maxColumnTitleLength = 15;
5859

59-
// 카드리스트의 스크롤을 칼럼 영역으로 이동
6060
const scrollRef = useRef<HTMLDivElement | null>(null);
6161

62-
// ✅ 멤버 불러오기
6362
useEffect(() => {
6463
const fetchMembers = async () => {
6564
try {
@@ -86,7 +85,6 @@ export default function Column({
8685
toast.error("칼럼 제목을 입력해 주세요.");
8786
return;
8887
}
89-
setIsColumnModalOpen(false);
9088

9189
try {
9290
const updated = await updateColumn({ columnId, title: newTitle });
@@ -133,23 +131,17 @@ export default function Column({
133131
{/* 칼럼 헤더 */}
134132
<div className="shrink-0 mb-2">
135133
<div className="flex items-center justify-between">
136-
{/* 왼쪽: 타이틀 + 카드 개수 */}
134+
{/* 타이틀 + 개수 */}
137135
<div className="flex items-center gap-2">
138136
<Image src="/svgs/ellipse.svg" alt="circle" width={8} height={8} />
139-
<h2
140-
className="text-black3 text-[16px] md:text-[18px] font-bold
141-
break-words sm:max-w-none max-w-[90px]"
142-
>
137+
<h2 className="text-black3 text-[16px] md:text-[18px] font-bold break-words sm:max-w-none max-w-[90px]">
143138
{columnTitle}
144139
</h2>
145-
<span
146-
className="flex items-center justify-center leading-none
147-
w-[20px] h-[20px] bg-white text-[var(--primary)] font-14m rounded-[4px]"
148-
>
140+
<span className="flex items-center justify-center leading-none w-[20px] h-[20px] bg-white text-[var(--primary)] font-14m rounded-[4px]">
149141
{tasks.length}
150142
</span>
151143
</div>
152-
{/* 오른쪽: 생성 버튼 + 설정 버튼 */}
144+
{/* 버튼 */}
153145
<div className="flex items-center gap-2">
154146
<div
155147
onClick={() => {
@@ -199,9 +191,8 @@ export default function Column({
199191
</div>
200192
</div>
201193

202-
{/* 스크롤바 컨테이너 */}
194+
{/* 카드 리스트 */}
203195
<div className="flex flex-col lg:pl-[21px] overflow-y-auto w-full lg:w-[357px] rounded-md bg-[#F5F2FC]">
204-
{/* 카드 리스트 */}
205196
<div
206197
className="flex-1 overflow-y-auto overflow-x-hidden"
207198
style={{ scrollbarGutter: "stable" }}
@@ -217,7 +208,7 @@ export default function Column({
217208
</div>
218209
</div>
219210

220-
{/* 카드 생성 모달 */}
211+
{/* 카드 생성 */}
221212
{isTaskModalOpen && (
222213
<TaskModal
223214
mode="create"
@@ -226,14 +217,18 @@ export default function Column({
226217
dashboardId={dashboardId}
227218
columnId={columnId}
228219
members={members}
220+
columns={columns}
229221
initialData={{
230222
status: columnTitle,
231223
}}
232-
onSubmit={fetchColumnsAndCards}
224+
onSubmit={() => {
225+
fetchColumnsAndCards();
226+
setIsTaskModalOpen(false);
227+
}}
233228
/>
234229
)}
235230

236-
{/* 칼럼 관리 모달 */}
231+
{/* 칼럼 수정 */}
237232
{isColumnModalOpen && (
238233
<FormModal
239234
title="칼럼 이름 수정"
@@ -265,25 +260,25 @@ export default function Column({
265260
/>
266261
)}
267262

268-
{/* 칼럼 삭제 확인 모달 */}
269263
<ColumnDeleteModal
270264
isOpen={isDeleteModalOpen}
271265
onClose={() => setIsDeleteModalOpen(false)}
272266
onDelete={handleDeleteColumn}
273267
/>
274268

275-
{/* 카드 상세 모달 */}
269+
{/* 카드 상세 */}
276270
{isCardDetailModalOpen && selectedCard && (
277271
<CardDetailModal
278272
card={selectedCard}
279273
currentUserId={selectedCard.assignee.id}
280274
dashboardId={dashboardId}
275+
createdByMe={createdByMe}
281276
onClose={() => {
282277
setIsCardDetailModalOpen(false);
283278
setSelectedCard(null);
284279
}}
285280
onChangeCard={fetchColumnsAndCards}
286-
createdByMe={createdByMe}
281+
columns={columns}
287282
/>
288283
)}
289284
</div>

src/components/modalDashboard/CardDetailModal.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@ import { useCardDetailState } from "@/hooks/useCardDetailState";
1212
import { useCardDetail } from "@/hooks/useCardDetail";
1313
import { getCardDetail } from "@/api/card";
1414
import type { CardDetailType } from "@/types/cards";
15+
import type { ColumnType } from "@/types/task";
1516

1617
interface CardDetailModalProps {
1718
card: CardDetailType;
1819
dashboardId: number;
1920
createdByMe: boolean;
2021
onClose: () => void;
2122
onChangeCard?: () => void;
23+
columns: ColumnType[];
24+
currentUserId?: number;
2225
}
2326

2427
export default function CardDetailPage({
@@ -27,6 +30,7 @@ export default function CardDetailPage({
2730
createdByMe,
2831
onClose,
2932
onChangeCard,
33+
columns,
3034
}: CardDetailModalProps) {
3135
const { canEditCards } = useDashboardPermission(dashboardId, createdByMe);
3236
const { cardData, setCardData, columnName, members } = useCardDetailState(
@@ -148,6 +152,7 @@ export default function CardDetailPage({
148152
</div>
149153
</div>
150154

155+
{/* 수정 모달 */}
151156
{isEditModalOpen && (
152157
<TaskModal
153158
isOpen={true}
@@ -156,6 +161,7 @@ export default function CardDetailPage({
156161
cardId={cardData.id}
157162
dashboardId={dashboardId}
158163
members={members}
164+
columns={columns}
159165
onClose={() => setIsEditModalOpen(false)}
160166
onSubmit={async () => {
161167
try {
@@ -170,7 +176,8 @@ export default function CardDetailPage({
170176
}
171177
}}
172178
initialData={{
173-
status: columnName,
179+
status:
180+
columns.find((col) => col.id === cardData.columnId)?.title ?? "",
174181
assignee: cardData.assignee.nickname,
175182
title: cardData.title,
176183
description: cardData.description,

src/components/modalDashboard/UpdateComment.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// ✅ UpdateComment.tsx
21
import { useState } from "react";
32
import { useQueryClient } from "@tanstack/react-query";
43
import { deleteComment, updateComment } from "@/api/comment";

src/components/modalDashboard/formatDate.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// src/utils/formatDate.ts (혹은 components 폴더 내)
2-
31
export default function formatDate(
42
dateString: string,
53
includeTime: boolean = true,

src/components/modalInput/CardInput.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ export default function CardInput({
4141
className
4242
)}
4343
style={{
44-
overflowY: "auto", // 내용이 넘치면 스크롤 생성
44+
overflowY: "auto",
4545
wordWrap: "break-word",
4646
whiteSpace: "pre-wrap",
47-
boxSizing: "border-box", // padding과 border를 높이에 포함
47+
boxSizing: "border-box",
4848
}}
4949
/>
5050
{hasButton && (

src/components/modalInput/ModalImage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ interface ModalImageProps {
88
label: string;
99
columnId: number;
1010
defaultImageUrl?: string;
11-
onImageSelect: (imageUrl: string) => void; // ✅ string만 넘김
11+
onImageSelect: (imageUrl: string) => void;
1212
}
1313

1414
export default function ModalImage({
@@ -43,7 +43,7 @@ export default function ModalImage({
4343
};
4444
reader.readAsDataURL(file);
4545

46-
// 업로드 후 URL 전달
46+
// 업로드 후 URL 전달
4747
try {
4848
const imageUrl = await uploadCardImage({
4949
columnId,

src/components/modalInput/ModalTextarea.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ interface ModalTextareaProps {
66
required?: boolean;
77
isButton: boolean;
88
small?: boolean;
9-
defaultValue?: string; // ✅ 추가됨
9+
defaultValue?: string;
1010
onTextChange: (value: string) => void;
1111
onButtonClick?: () => void;
1212
}
@@ -35,7 +35,6 @@ export default function ModalTextarea({
3535
}
3636
};
3737

38-
// ✅ 초기 defaultValue 기준으로 height 조절
3938
useEffect(() => {
4039
const textarea = textareaRef.current;
4140
if (textarea) {
@@ -48,7 +47,7 @@ export default function ModalTextarea({
4847
<div className="inline-flex flex-col items-start gap-2.5 w-full">
4948
<label
5049
htmlFor="comment"
51-
className="font-medium text-black3 text-[16px] sm:text-[18px]"
50+
className="font-medium text-black3 text-[14px] sm:text-[18px]"
5251
>
5352
{label} {required && <span className="text-[var(--primary)]"> *</span>}
5453
</label>
@@ -71,7 +70,7 @@ export default function ModalTextarea({
7170
onChange={handleTextareaChange}
7271
className={`
7372
w-full resize-none rounded-md border-none px-4 py-3
74-
text-black3 text-[16px] sm:text-[18px] font:normal
73+
text-black3 text-[14px] sm:text-[16px] font:normal
7574
outline-none bg-transparent overflow-hidden
7675
${small ? "h-[50px]" : "min-h-[110px]"}
7776
`}

src/components/modalInput/TaskModal.tsx

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import TextButton from "@/components/modalInput/TextButton";
55
import StatusSelect from "@/components/modalInput/StatusSelect";
66
import AssigneeSelect from "@/components/modalInput/AssigneeSelect";
77
import { useTaskForm } from "@/hooks/useTaskForm";
8-
import { useColumnStatus } from "@/hooks/useColumnStatus";
8+
import { ColumnType } from "@/types/task";
99

1010
interface TaskModalProps {
1111
mode?: "create" | "edit";
@@ -22,6 +22,7 @@ interface TaskModalProps {
2222
columnId: number;
2323
dashboardId: number;
2424
cardId?: number;
25+
columns: ColumnType[];
2526
}
2627

2728
export interface TaskData {
@@ -43,24 +44,34 @@ export default function TaskModal({
4344
columnId,
4445
dashboardId,
4546
cardId,
47+
columns,
4648
}: TaskModalProps) {
47-
const updatedColumnId = useColumnStatus(
48-
dashboardId,
49-
columnId,
50-
initialData.status || ""
51-
);
52-
53-
const { formData, handleChange, isFormValid, handleSubmit } = useTaskForm({
49+
const {
50+
formData,
51+
handleChange,
52+
isFormValid,
53+
handleSubmit: baseHandleSubmit,
54+
} = useTaskForm({
5455
mode,
5556
initialData,
5657
members,
5758
dashboardId,
5859
columnId,
5960
cardId,
60-
updatedColumnId,
61+
columns,
6162
onClose,
6263
onSubmit,
6364
});
65+
66+
const updatedColumnId =
67+
columns?.find(
68+
(col) => col.title.toLowerCase() === formData.status?.toLowerCase()
69+
)?.id ?? columnId;
70+
71+
const handleSubmit = () => {
72+
baseHandleSubmit(updatedColumnId);
73+
};
74+
6475
return (
6576
<div className="fixed inset-0 flex items-center justify-center bg-black/35 z-50">
6677
<div className="sm:w-[584px] w-[320px] h-[calc(var(--vh)_*_90)] rounded-lg bg-white p-4 sm:p-8 shadow-lg flex flex-col gap-4 sm:gap-8 overflow-y-auto">
@@ -77,7 +88,6 @@ export default function TaskModal({
7788
required
7889
onChange={(value) => handleChange("status", value)}
7990
/>
80-
8191
<AssigneeSelect
8292
label="담당자"
8393
value={formData.assignee}

0 commit comments

Comments
 (0)