22
33import { useState } from "react" ;
44
5+ import { useMutation } from "@tanstack/react-query" ;
6+ import Image from "next/image" ;
7+ import { useRouter } from "next/navigation" ;
8+
59import ArtTooltip from "@/components/archive-form/ArtToolTip" ;
610import DatePicker from "@/components/archive-form/DayPicker" ;
711import Dropdown from "@/components/archive-form/Dropdown" ;
@@ -14,16 +18,18 @@ import Textarea from "@/components/archive-form/Textarea";
1418import ToggleButton from "@/components/archive-form/ToggleButton" ;
1519import Header from "@/components/common/Header" ;
1620import { ART_TYPES } from "@/constants/art" ;
17- import { useImageStore } from "@/stores/useImageStore" ;
1821import { useUploadImage } from "@/hooks/useImageUploader" ;
19- import { useRouter } from "next/navigation" ;
20- import { useMutation } from "@tanstack/react-query" ;
2122import { createArtwork } from "@/services/artworks" ;
23+ import { useImageStore } from "@/stores/useImageStore" ;
2224
2325function FieldWrapper ( { children } : { children : React . ReactNode } ) {
2426 return < div className = "flex flex-col gap-2" > { children } </ div > ;
2527}
2628
29+ function getErrorMessage ( error : unknown ) {
30+ return error instanceof Error ? error . message : "작품 등록에 실패했습니다." ;
31+ }
32+
2733export default function ArtCreatePage ( ) {
2834 const router = useRouter ( ) ;
2935
@@ -47,6 +53,8 @@ export default function ArtCreatePage() {
4753 const [ notes , setNotes ] = useState ( "" ) ;
4854
4955 const [ isPublic , setIsPublic ] = useState ( false ) ;
56+ const [ isSubmitting , setIsSubmitting ] = useState ( false ) ;
57+ const [ submitErrorMessage , setSubmitErrorMessage ] = useState < string | null > ( null ) ;
5058
5159 const isFormValid =
5260 images . length > 0 &&
@@ -62,6 +70,11 @@ export default function ArtCreatePage() {
6270 } ) ;
6371
6472 const handleSubmit = async ( ) => {
73+ if ( isSubmitting ) return ;
74+
75+ setIsSubmitting ( true ) ;
76+ setSubmitErrorMessage ( null ) ;
77+
6578 try {
6679 const uploadedImages = await Promise . all ( images . map ( image => uploadImage ( image . file ) ) ) ;
6780
@@ -91,7 +104,9 @@ export default function ArtCreatePage() {
91104 clearImages ( ) ;
92105 router . push ( "/" ) ;
93106 } catch ( error ) {
94- console . error ( error ) ;
107+ setSubmitErrorMessage ( getErrorMessage ( error ) ) ;
108+ } finally {
109+ setIsSubmitting ( false ) ;
95110 }
96111 } ;
97112 return (
@@ -112,9 +127,11 @@ export default function ArtCreatePage() {
112127 < div className = "flex justify-between" >
113128 < Label required > 작품 유형</ Label >
114129 < div className = "relative" >
115- < img
130+ < Image
116131 src = "/info-icon.svg"
117132 alt = "작품 유형"
133+ width = { 20 }
134+ height = { 20 }
118135 className = "mr-2 cursor-pointer"
119136 onClick = { ( ) => setIsTooltipOpen ( ! isTooltipOpen ) }
120137 />
@@ -202,16 +219,21 @@ export default function ArtCreatePage() {
202219
203220 { /* Bottom Button () */ }
204221 < div className = "border-border-primary fixed right-0 bottom-4 left-0 h-24.5 border-t bg-white px-5 py-4" >
222+ { submitErrorMessage && (
223+ < p role = "alert" className = "text-caption text-error-default mb-2" >
224+ { submitErrorMessage }
225+ </ p >
226+ ) }
205227 < button
206- disabled = { ! isFormValid }
228+ disabled = { ! isFormValid || isSubmitting }
207229 onClick = { handleSubmit }
208230 className = { `text-body-1 h-12.5 w-full rounded-lg font-medium transition-colors ${
209- isFormValid
231+ isFormValid && ! isSubmitting
210232 ? "bg-object-primary text-text-invert cursor-pointer"
211233 : "bg-object-disabled text-text-disabled cursor-not-allowed"
212234 } `}
213235 >
214- 추가하기
236+ { isSubmitting ? "등록 중..." : " 추가하기" }
215237 </ button >
216238 </ div >
217239 </ main >
0 commit comments