Skip to content

Commit 72e6bdd

Browse files
committed
refactor: 첨부 이미지가 10장 이상인 경우 알림창 및 이미지 초기화
1 parent 78b89da commit 72e6bdd

3 files changed

Lines changed: 162 additions & 126 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Modal, Button } from "flowbite-react";
2+
3+
interface ImageLimitModalProps {
4+
show: boolean;
5+
onClose: () => void;
6+
}
7+
8+
export const ImageLimitModal = ({ show, onClose }: ImageLimitModalProps) => {
9+
return (
10+
<Modal show={show} size="md" onClose={onClose} position="center">
11+
<div className="px-6 py-8 text-center">
12+
<p className="mb-2 text-base whitespace-nowrap text-gray-700 dark:text-gray-300">
13+
이미지는 최대 10장까지만 업로드할 수 있습니다.
14+
</p>
15+
<p className="mb-8 text-base text-gray-700 dark:text-gray-300">
16+
다시 선택해주세요.
17+
</p>
18+
19+
<div className="flex justify-center">
20+
<Button color="gray" onClick={onClose}>
21+
확인
22+
</Button>
23+
</div>
24+
</div>
25+
</Modal>
26+
);
27+
};
Lines changed: 59 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {useState} from "react";
1+
import React, { useState } from "react";
22
import {
33
Button,
44
FileInput,
@@ -10,20 +10,22 @@ import {
1010
Label,
1111
TextInput,
1212
} from "flowbite-react";
13-
import {TagForm} from "./TagForm";
14-
import api from "../api/axiosInstance.ts";
13+
import { TagForm } from "./TagForm";
14+
import api from "../api/axiosInstance";
15+
import { ImageLimitModal } from "./ImageLimitModal"; // 모달 추가
1516

1617
interface ModalComponentProps {
1718
open: boolean;
1819
onClose: () => void;
1920
}
2021

21-
export const ModalBoardForm = ({open, onClose}: ModalComponentProps) => {
22+
export const ModalBoardForm = ({ open, onClose }: ModalComponentProps) => {
2223
const [tags, setTags] = useState<string[]>([]);
2324
const [title, setTitle] = useState<string>("");
2425
const [content, setContent] = useState<string>("");
2526
const [recruitmentStatus, setRecruitmentStatus] = useState<string>("NONE");
2627
const [files, setFiles] = useState<File[]>([]);
28+
const [showLimitModal, setShowLimitModal] = useState(false); // 모달 상태
2729

2830
const resetForm = () => {
2931
setTags([]);
@@ -42,11 +44,18 @@ export const ModalBoardForm = ({open, onClose}: ModalComponentProps) => {
4244
const selected = e.target.files;
4345
if (selected) {
4446
const newFiles = Array.from(selected);
45-
setFiles((prev) => [...prev, ...newFiles].slice(0, 10)); // 최대 10개 누적
47+
const totalFiles = files.length + newFiles.length;
48+
if (totalFiles > 10) {
49+
setFiles([]);
50+
e.target.value = "";
51+
setShowLimitModal(true);
52+
} else {
53+
setFiles((prev) => [...prev, ...newFiles]);
54+
}
4655
}
4756
};
4857

49-
const handleSubmit = async () => {
58+
const handleSubmit = async () => {
5059
const formData = new FormData();
5160
formData.append("title", title);
5261
formData.append("content", content);
@@ -60,7 +69,6 @@ export const ModalBoardForm = ({open, onClose}: ModalComponentProps) => {
6069
"Content-Type": "multipart/form-data",
6170
},
6271
});
63-
console.log("Post created successfully.");
6472
window.location.reload();
6573
handleClose();
6674
} catch (error) {
@@ -69,93 +77,89 @@ export const ModalBoardForm = ({open, onClose}: ModalComponentProps) => {
6977
};
7078

7179
return (
80+
<>
7281
<Modal show={open} onClose={handleClose}>
7382
<ModalHeader>게시글 작성</ModalHeader>
7483
<ModalBody>
7584
<div className="space-y-4">
7685
<div>
7786
<Label htmlFor="title">제목</Label>
7887
<TextInput
79-
id="title"
80-
placeholder="제목을 입력해주세요"
81-
value={title}
82-
onChange={(e) => setTitle(e.target.value)}
83-
required
88+
id="title"
89+
placeholder="제목을 입력해주세요"
90+
value={title}
91+
onChange={(e) => setTitle(e.target.value)}
92+
required
8493
/>
8594
</div>
8695

8796
<div>
8897
<Label htmlFor="content">내용</Label>
8998
<Textarea
90-
id="content"
91-
placeholder="내용을 입력해주세요"
92-
value={content}
93-
rows={4}
94-
onChange={(e) => setContent(e.target.value)}
95-
required
99+
id="content"
100+
placeholder="내용을 입력해주세요"
101+
value={content}
102+
rows={4}
103+
onChange={(e) => setContent(e.target.value)}
104+
required
96105
/>
97106
</div>
98107

99-
<div className="flex items-center gap-4 mt-2 text-sm">
108+
<div className="mt-2 flex items-center gap-4 text-sm">
100109
<Label className="whitespace-nowrap">모집 상태</Label>
101110
<div className="flex gap-4">
102-
<label className="flex items-center gap-1">
103-
<input
111+
{["NONE", "RECRUITING", "DONE"].map((status) => (
112+
<label key={status} className="flex items-center gap-1">
113+
<input
104114
type="radio"
105115
name="recruitmentStatus"
106-
value="NONE"
107-
checked={recruitmentStatus === "NONE"}
116+
value={status}
117+
checked={recruitmentStatus === status}
108118
onChange={(e) => setRecruitmentStatus(e.target.value)}
109-
/>
110-
선택 안 함
111-
</label>
112-
<label className="flex items-center gap-1">
113-
<input
114-
type="radio"
115-
name="recruitmentStatus"
116-
value="RECRUITING"
117-
checked={recruitmentStatus === "RECRUITING"}
118-
onChange={(e) => setRecruitmentStatus(e.target.value)}
119-
/>
120-
모집 중
121-
</label>
122-
<label className="flex items-center gap-1">
123-
<input
124-
type="radio"
125-
name="recruitmentStatus"
126-
value="DONE"
127-
checked={recruitmentStatus === "DONE"}
128-
onChange={(e) => setRecruitmentStatus(e.target.value)}
129-
/>
130-
모집 마감
131-
</label>
119+
/>
120+
{status === "NONE"
121+
? "선택 안 함"
122+
: status === "RECRUITING"
123+
? "모집 중"
124+
: "모집 마감"}
125+
</label>
126+
))}
132127
</div>
133128
</div>
134129

135130
<div>
136-
<Label htmlFor="file">이미지 (10개까지만 첨부됩니다)</Label>
137-
<FileInput id="file" multiple={true} onChange={handleFileChange}/>
131+
<Label htmlFor="file">
132+
이미지 (최대 10장까지만 업로드할 수 있습니다)
133+
</Label>
134+
<FileInput id="file" multiple onChange={handleFileChange} />
138135
<ul className="mt-2 text-sm text-gray-600">
139136
{files.map((file, idx) => (
140-
<li key={idx}>📎 {file.name}</li>
137+
<li key={idx}>📎 {file.name}</li>
141138
))}
142139
</ul>
143140
</div>
144141

145-
<TagForm
146-
externalTags={tags}
147-
onTagsChange={(updatedTags) => setTags(updatedTags)}
148-
/>
142+
<TagForm externalTags={tags} onTagsChange={setTags} />
149143
</div>
150144
</ModalBody>
151145
<ModalFooter className="flex justify-end space-x-2">
152-
<Button className="!bg-blue-900 hover:!bg-blue-800" onClick={handleSubmit}>
146+
<Button
147+
className="!bg-blue-900 hover:!bg-blue-800"
148+
onClick={handleSubmit}
149+
>
153150
작성
154151
</Button>
155152
<Button color="gray" onClick={handleClose}>
156153
취소
157154
</Button>
158155
</ModalFooter>
159156
</Modal>
157+
158+
{/* 이미지 제한 모달 */}
159+
<ImageLimitModal
160+
show={showLimitModal}
161+
onClose={() => setShowLimitModal(false)}
162+
/>
163+
</>
160164
);
161-
};
165+
};

0 commit comments

Comments
 (0)