Skip to content

Commit 78a3ddd

Browse files
authored
Merge pull request #101 from part3-4team-Taskify/modalInputApi2
[feat] 할일 수정모달 api연결
2 parents 251abd8 + af09c12 commit 78a3ddd

File tree

3 files changed

+70
-14
lines changed

3 files changed

+70
-14
lines changed

src/api/card.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,38 @@ export const getDashboardMembers = async ({
8484

8585
return res.data.members;
8686
};
87+
88+
/** 4. 카드 수정 */
89+
export const updateCard = async ({
90+
teamId,
91+
cardId,
92+
columnId,
93+
assigneeUserId,
94+
title,
95+
description,
96+
dueDate,
97+
tags,
98+
imageUrl,
99+
}: {
100+
teamId: string;
101+
cardId: number;
102+
columnId: number;
103+
assigneeUserId: number;
104+
title: string;
105+
description: string;
106+
dueDate: string;
107+
tags: string[];
108+
imageUrl?: string;
109+
}) => {
110+
const response = await axiosInstance.put(`/${teamId}/cards/${cardId}`, {
111+
columnId,
112+
assigneeUserId,
113+
title,
114+
description,
115+
dueDate,
116+
tags,
117+
imageUrl,
118+
});
119+
120+
return response.data;
121+
};

src/components/modalInput/ModalImage.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,33 @@
11
import Image from "next/image";
2-
import { ChangeEvent, useRef, useState } from "react";
2+
import { ChangeEvent, useEffect, useRef, useState } from "react";
33
import AddButton from "./AddButton";
44
import { uploadCardImage } from "@/api/card";
55

66
interface ModalImageProps {
77
label: string;
88
teamId: string;
99
columnId: number;
10-
onImageSelect: (imageUrl: string) => void;
10+
defaultImageUrl?: string;
11+
onImageSelect: (imageUrl: string) => void; // ✅ string만 넘김
1112
}
1213

1314
export default function ModalImage({
1415
label,
1516
teamId,
1617
columnId,
18+
defaultImageUrl,
1719
onImageSelect,
1820
}: ModalImageProps) {
1921
const [backgroundImage, setBackgroundImage] = useState<string | null>(null);
2022
const fileInputRef = useRef<HTMLInputElement | null>(null);
2123

24+
// 기존 이미지 표시
25+
useEffect(() => {
26+
if (defaultImageUrl) {
27+
setBackgroundImage(defaultImageUrl);
28+
}
29+
}, [defaultImageUrl]);
30+
2231
const handleFileInputClick = () => {
2332
fileInputRef.current?.click();
2433
};
@@ -27,21 +36,22 @@ export default function ModalImage({
2736
const file = e.target.files?.[0];
2837
if (!file) return;
2938

30-
// 이미지 미리보기
39+
// 미리보기용
3140
const reader = new FileReader();
3241
reader.onload = (event) => {
3342
const imageSrc = event.target?.result as string;
3443
setBackgroundImage(imageSrc);
3544
};
3645
reader.readAsDataURL(file);
3746

47+
// ✅ 업로드 후 URL 전달
3848
try {
3949
const imageUrl = await uploadCardImage({
4050
teamId,
4151
columnId,
42-
imageFile: file, // ✅ File만 넘김
52+
imageFile: file,
4353
});
44-
onImageSelect(imageUrl); // 부모로 전달
54+
onImageSelect(imageUrl);
4555
} catch (error) {
4656
console.error("이미지 업로드 실패:", error);
4757
alert("이미지 업로드에 실패했어요.");
@@ -64,7 +74,7 @@ export default function ModalImage({
6474
src={backgroundImage}
6575
fill
6676
alt="Selected Image"
67-
className="rounded-md"
77+
className="rounded-md object-cover"
6878
unoptimized
6979
/>
7080
<div className="z-10 flex w-[76px] h-[76px] items-center justify-center rounded-md bg-[var(--color-black4)] opacity-0 transition-opacity duration-200 ease-in-out group-hover:opacity-60">

src/components/modalInput/TaskModal.tsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,25 @@ interface TaskModalProps {
1111
onClose: () => void;
1212
onSubmit: (data: TaskData) => void;
1313
initialData?: Partial<TaskData>;
14+
members: { nickname: string }[]; // ✅ 담당자 목록 받기
1415
}
1516

16-
interface TaskData {
17+
export interface TaskData {
1718
status: string;
1819
assignee: string;
1920
title: string;
2021
description: string;
2122
deadline: string;
2223
tags: string[];
23-
image?: File;
24+
image?: string; // ✅ 이미지 URL
2425
}
2526

2627
export default function TaskModal({
2728
mode = "create",
2829
onClose,
2930
onSubmit,
3031
initialData = {},
32+
members,
3133
}: TaskModalProps) {
3234
const [formData, setFormData] = useState<TaskData>({
3335
status: initialData.status || "",
@@ -36,19 +38,23 @@ export default function TaskModal({
3638
description: initialData.description || "",
3739
deadline: initialData.deadline || "",
3840
tags: initialData.tags || [],
39-
image: initialData.image,
41+
image: initialData.image || "",
4042
});
4143

42-
const handleChange = (
43-
field: keyof TaskData,
44-
value: string | string[] | File
45-
) => {
44+
const handleChange = (field: keyof TaskData, value: string | string[]) => {
4645
setFormData((prev) => ({
4746
...prev,
4847
[field]: value,
4948
}));
5049
};
5150

51+
const isFormValid =
52+
formData.assignee &&
53+
formData.status &&
54+
formData.title &&
55+
formData.description &&
56+
formData.deadline;
57+
5258
return (
5359
<div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-30 p-4 z-50">
5460
<div className="w-full max-w-[584px] h-auto max-h-[90vh] rounded-lg bg-white p-4 sm:p-8 shadow-lg flex flex-col gap-4 sm:gap-8 overflow-y-auto">
@@ -69,6 +75,7 @@ export default function TaskModal({
6975
<AssigneeSelect
7076
label="담당자"
7177
value={formData.assignee}
78+
users={members.map((m) => m.nickname)} // ✅ 드롭다운용
7279
required
7380
onChange={(value) => handleChange("assignee", value)}
7481
/>
@@ -104,7 +111,10 @@ export default function TaskModal({
104111

105112
<ModalImage
106113
label="이미지"
107-
onImageSelect={(file) => handleChange("image", file)}
114+
teamId={""} // ✅ 부모에서 넘겨줘야 함
115+
columnId={0}
116+
defaultImageUrl={formData.image}
117+
onImageSelect={(url) => handleChange("image", url)}
108118
/>
109119
</div>
110120

@@ -123,6 +133,7 @@ export default function TaskModal({
123133
buttonSize="md"
124134
onClick={() => onSubmit(formData)}
125135
className="w-full sm:w-[256px] h-[54px] bg-[var(--primary)] text-white rounded-lg"
136+
disabled={!isFormValid}
126137
>
127138
{mode === "edit" ? "수정" : "생성"}
128139
</TextButton>

0 commit comments

Comments
 (0)