Skip to content

Commit 47d8f4a

Browse files
authored
[캠퍼스] 콜밴팟 API 이미지 업로드 추가 (#1209)
1 parent e882a1f commit 47d8f4a

7 files changed

Lines changed: 31 additions & 10 deletions

File tree

src/api/callvan/entity.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,18 @@ export interface CallvanReportReason {
159159
custom_text?: string;
160160
}
161161

162+
export type CallvanReportAttachmentType = 'IMAGE';
163+
164+
export interface CallvanReportAttachment {
165+
attachment_type: CallvanReportAttachmentType;
166+
url: string;
167+
}
168+
162169
export interface CallvanReportRequest {
163170
reported_user_id: number;
164171
description?: string;
165172
reasons: CallvanReportReason[];
173+
attachments?: CallvanReportAttachment[];
166174
}
167175

168176
export interface CreateCallvanRequest {

src/api/uploadFile/entity.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { APIResponse } from 'interfaces/APIResponse';
22

3-
export type UploadDomain = 'SHOPS' | 'LOST_ITEMS' | 'CLUB';
3+
export type UploadDomain = 'SHOPS' | 'LOST_ITEMS' | 'CLUB' | 'CALLVAN_REPORT' | 'CALLVAN_CHAT';
44

55
export interface UploadImage extends APIResponse {
66
file_url: string;
Lines changed: 2 additions & 4 deletions
Loading

src/components/Callvan/components/CallvanChatRoom/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export default function CallvanChatRoom({ postId }: CallvanChatRoomProps) {
6060
if (!file) return;
6161

6262
try {
63-
const { file_url } = await uploadFile({ domain: 'SHOPS', file });
63+
const { file_url } = await uploadFile({ domain: 'CALLVAN_CHAT', file });
6464
if (file_url) {
6565
sendMessage({ is_image: true, content: file_url });
6666
}

src/components/Callvan/components/ReportPage/DetailStep.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ export default function DetailStep({ description, images, onDescriptionChange, o
8686
</button>
8787
)}
8888
</div>
89-
{/* TODO: 이미지 API 완성 후 FormData로 업로드 연결 */}
9089
<input
9190
ref={fileInputRef}
9291
type="file"

src/components/Callvan/components/ReportPage/ReportPage.module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@
360360
justify-content: center;
361361
gap: 8px;
362362
width: 100%;
363+
height: 38px;
363364
background: #ead3fe;
364365
border: none;
365366
border-radius: 8px;

src/components/Callvan/components/ReportPage/index.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import ArrowBackIcon from 'assets/svg/Callvan/arrow-back.svg';
55
import useCallvanToast from 'components/Callvan/hooks/useCallvanToast';
66
import useReportCallvan from 'components/Callvan/hooks/useReportCallvan';
77
import ROUTES from 'static/routes';
8+
import useUploadFile from 'utils/hooks/uploadFile/useUploadFile';
89
import showToast from 'utils/ts/showToast';
910
import DetailStep from './DetailStep';
1011
import ReasonStep from './ReasonStep';
@@ -18,6 +19,7 @@ interface ReportPageProps {
1819
export default function ReportPage({ postId, reportedUserId }: ReportPageProps) {
1920
const router = useRouter();
2021
const { mutate, isPending } = useReportCallvan(postId);
22+
const { uploadFile, isPending: isUploading } = useUploadFile();
2123

2224
const [step, setStep] = useState<1 | 2>(1);
2325
const [selectedReasons, setSelectedReasons] = useState<Set<CallvanReportReasonCode>>(new Set());
@@ -59,18 +61,31 @@ export default function ReportPage({ postId, reportedUserId }: ReportPageProps)
5961
}
6062
};
6163

62-
const handleSubmit = () => {
64+
const handleSubmit = async () => {
6365
const reasons: CallvanReportReason[] = Array.from(selectedReasons).map((code) => ({
6466
reason_code: code,
6567
...(code === 'OTHER' ? { custom_text: customText } : {}),
6668
}));
6769

70+
let attachments: { attachment_type: 'IMAGE'; url: string }[] = [];
71+
if (images.length > 0) {
72+
try {
73+
const uploadResults = await Promise.all(
74+
images.map((file) => uploadFile({ domain: 'CALLVAN_REPORT', file })),
75+
);
76+
attachments = uploadResults.map((result: { file_url: string }) => ({ attachment_type: 'IMAGE' as const, url: result.file_url }));
77+
} catch {
78+
showToast('error', '이미지 업로드에 실패했습니다.');
79+
return;
80+
}
81+
}
82+
6883
mutate(
6984
{
7085
reported_user_id: reportedUserId,
7186
...(description.trim() ? { description: description.trim() } : {}),
7287
reasons,
73-
// TODO: images를 FormData로 업로드하는 API가 완성되면 여기에 연결
88+
...(attachments.length > 0 ? { attachments } : {}),
7489
},
7590
{
7691
onSuccess: () => {
@@ -120,7 +135,7 @@ export default function ReportPage({ postId, reportedUserId }: ReportPageProps)
120135
다음
121136
</button>
122137
) : (
123-
<button type="button" className={styles['page__submit-button']} onClick={handleSubmit} disabled={isPending}>
138+
<button type="button" className={styles['page__submit-button']} onClick={handleSubmit} disabled={isPending || isUploading}>
124139
신고하기
125140
</button>
126141
)}

0 commit comments

Comments
 (0)