Skip to content

Commit c3fed30

Browse files
authored
[Feat Fix Refector] 카드수정모달: 담당자 선택 가능하게 변경
[Feat Fix Refector] 담당자 선택 갱신 수정
2 parents b963e14 + 3a4e76e commit c3fed30

File tree

4 files changed

+104
-123
lines changed

4 files changed

+104
-123
lines changed

src/api/card.ts

Lines changed: 17 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
import axiosInstance from "./axiosInstance";
2-
import type { CardDetailType } from "@/types/cards"; // Dashboard 타입 import
2+
import type { CardDetailType } from "@/types/cards";
33
import { apiRoutes } from "@/api/apiRoutes";
44
import { TEAM_ID } from "@/constants/team";
55

6+
/** 카드 수정용 타입 */
7+
export interface EditCardPayload {
8+
columnId?: number;
9+
assigneeUserId?: number;
10+
title?: string;
11+
description?: string;
12+
dueDate?: string;
13+
tags?: string[];
14+
imageUrl?: string;
15+
}
16+
617
/** 1. 카드 이미지 업로드 */
718
export const uploadCardImage = async ({
819
columnId,
@@ -83,43 +94,12 @@ export const getDashboardMembers = async ({
8394
};
8495

8596
/** 4. 카드 수정 */
86-
export const updateCard = async (
87-
id: number,
88-
data: Partial<CardDetailType>,
89-
{
90-
cardId,
91-
columnId,
92-
assigneeUserId,
93-
title,
94-
description,
95-
dueDate,
96-
tags,
97-
imageUrl,
98-
}: {
99-
cardId: number;
100-
columnId: number;
101-
assigneeUserId: number;
102-
title: string;
103-
description: string;
104-
dueDate: string;
105-
tags: string[];
106-
imageUrl?: string;
107-
}
108-
) => {
109-
const response = await axiosInstance.put(apiRoutes.cardDetail(cardId), {
110-
columnId,
111-
assigneeUserId,
112-
title,
113-
description,
114-
dueDate,
115-
tags,
116-
imageUrl,
117-
});
118-
97+
export const EditCard = async (cardId: number, data: EditCardPayload) => {
98+
const response = await axiosInstance.put(apiRoutes.cardDetail(cardId), data);
11999
return response.data;
120100
};
121101

122-
// 카드 목록 조회
102+
/** 5. 카드 목록 조회 */
123103
export const getCardsByColumn = async ({
124104
columnId,
125105
cursorId,
@@ -140,10 +120,9 @@ export const getCardsByColumn = async ({
140120
return res.data;
141121
};
142122

143-
// 카드 상세 조회
123+
/** 6. 카드 상세 조회 */
144124
export async function getCardDetail(cardId: number): Promise<CardDetailType> {
145125
try {
146-
// apiRoutes를 사용하여 URL 동적 생성
147126
const url = apiRoutes.cardDetail(cardId);
148127
const response = await axiosInstance.get(url);
149128
return response.data as CardDetailType;
@@ -153,17 +132,9 @@ export async function getCardDetail(cardId: number): Promise<CardDetailType> {
153132
}
154133
}
155134

156-
// 카드 삭제
135+
/** 7. 카드 삭제 */
157136
export const deleteCard = async (cardId: number) => {
158137
const url = apiRoutes.cardDetail(cardId);
159138
const response = await axiosInstance.delete(url);
160139
return response.data;
161140
};
162-
//카드 수정저장
163-
export const EditCard = async (
164-
cardId: number,
165-
data: Partial<CardDetailType>
166-
) => {
167-
const response = await axiosInstance.put(apiRoutes.cardDetail(cardId), data);
168-
return response.data;
169-
};

src/components/modalDashboard/CardDetail.tsx

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from "react";
1+
import { useEffect, useState } from "react";
22
import Image from "next/image";
33
import { CardDetailType } from "@/types/cards";
44
import { ColumnNameTag } from "../modalInput/chips/ColumnNameTag";
@@ -14,17 +14,20 @@ interface CardDetailProps {
1414

1515
export default function CardDetail({ card, columnName }: CardDetailProps) {
1616
const [isImageModalOpen, setIsImageModalOpen] = useState(false);
17+
const [currentCard, setCurrentCard] = useState<CardDetailType>(card);
18+
19+
useEffect(() => {
20+
setCurrentCard(card);
21+
}, [card]);
1722

1823
return (
1924
<div className="flex flex-col gap-5 w-full">
25+
{/* 상태 + 태그 */}
2026
<div className="flex flex-wrap items-center gap-5">
21-
{/* 칼럼 이름 태그 */}
2227
<ColumnNameTag label={columnName} />
23-
{/* 구분선 */}
2428
<div className="w-[1px] h-[20px] bg-[var(--color-gray3)]" />
25-
{/* 카드 태그 */}
2629
<div className="flex flex-wrap gap-[6px]">
27-
{card.tags.map((tag, idx) => {
30+
{currentCard.tags.map((tag, idx) => {
2831
const { textColor, bgColor } = getTagColor(idx);
2932
return (
3033
<ColorTagChip key={idx} className={`${textColor} ${bgColor}`}>
@@ -35,39 +38,52 @@ export default function CardDetail({ card, columnName }: CardDetailProps) {
3538
</div>
3639
</div>
3740

38-
{/* 내용 */}
39-
<p
40-
className="
41-
text-black font-normal sm:text-[16px] text-[14px] overflow-auto pr-1
42-
w-full lg:max-w-[445px] sm:max-w-[420px] max-w-[295px]
43-
min-h-0 sm:max-h-[100px] max-h-[80px]
44-
whitespace-pre-wrap word-break break-words
45-
"
46-
>
47-
{card.description}
41+
{/* 설명 */}
42+
<p className="text-black font-normal sm:text-[16px] text-[14px] overflow-auto pr-1 w-full lg:max-w-[445px] sm:max-w-[420px] max-w-[295px] min-h-0 sm:max-h-[100px] max-h-[80px] whitespace-pre-wrap word-break break-words">
43+
{currentCard.description}
4844
</p>
4945

46+
{/* 담당자 */}
47+
<div className="flex items-center gap-2 text-sm text-[var(--color-gray1)]">
48+
<span className="font-medium">담당자:</span>
49+
{currentCard.assignee.profileImageUrl ? (
50+
<Image
51+
src={currentCard.assignee.profileImageUrl}
52+
alt="프로필 이미지"
53+
width={24}
54+
height={24}
55+
className="w-6 h-6 rounded-full object-cover"
56+
/>
57+
) : (
58+
<div className="w-6 h-6 flex items-center justify-center bg-[#A3C4A2] text-white font-medium rounded-full text-xs">
59+
{currentCard.assignee.nickname[0]}
60+
</div>
61+
)}
62+
<span>{currentCard.assignee.nickname}</span>
63+
</div>
64+
5065
{/* 이미지 */}
51-
{card.imageUrl && (
66+
{currentCard.imageUrl && (
5267
<div
5368
className="md:w-[420px] lg:w-[445px] cursor-pointer"
5469
onClick={() => setIsImageModalOpen(true)}
5570
>
5671
<Image
57-
src={card.imageUrl}
72+
src={currentCard.imageUrl}
5873
alt="카드 이미지"
5974
width={290}
6075
height={168}
6176
className="rounded-lg object-cover
62-
lg:w-[445px] md:w-[420px]
63-
lg:h-[280px] md:h-[240px]
64-
sm:max-h-none max-h-[180px]"
77+
lg:w-[445px] md:w-[420px]
78+
lg:h-[280px] md:h-[240px]
79+
sm:max-h-none max-h-[180px]"
6580
/>
6681
</div>
6782
)}
68-
{isImageModalOpen && (
83+
84+
{isImageModalOpen && currentCard.imageUrl && (
6985
<PopupImageModal
70-
imageUrl={card.imageUrl!}
86+
imageUrl={currentCard.imageUrl}
7187
onClose={() => setIsImageModalOpen(false)}
7288
/>
7389
)}

0 commit comments

Comments
 (0)