11import { useState } from "react" ;
2+ import { changePassword } from "@/api/changepassword" ;
3+ import MypageModal from "../modal/MypageModal" ;
24import Input from "../input/Input" ;
5+ import Image from "next/image" ;
36
47export default function ChangePassword ( ) {
58 const [ password , setPassword ] = useState ( "" ) ;
69 const [ newPassword , setNewPassword ] = useState ( "" ) ;
710 const [ checkNewpassword , setCheckNewPassword ] = useState ( "" ) ;
8- const [ isPasswordMismatch ] = useState ( false ) ;
9-
11+ const [ isSubmitting , setIsSubmitting ] = useState ( false ) ;
12+ const [ errorMessage , setErrorMessage ] = useState ( "" ) ;
13+ const [ successMessage , setSuccessMessage ] = useState ( "" ) ;
1014 const [ showCheckNewPassword , setShowCheckNewPassword ] = useState ( false ) ;
15+ const [ showSuccessModal , setShowSuccessModal ] = useState ( false ) ;
16+ const [ showErrorModal , setShowErrorModal ] = useState ( false ) ;
1117
1218 const toggleCheckNewPasswordVisibility = ( ) =>
1319 setShowCheckNewPassword ( ! showCheckNewPassword ) ;
14-
20+ const isPasswordMismatch =
21+ newPassword && checkNewpassword && newPassword !== checkNewpassword ;
1522 const isDisabled =
1623 ! password ||
1724 ! newPassword ||
1825 ! checkNewpassword ||
1926 isPasswordMismatch ||
2027 password . length < 8 ;
2128
29+ const handleChangePassword = async ( ) => {
30+ if ( isDisabled ) return ;
31+
32+ setIsSubmitting ( true ) ;
33+ setErrorMessage ( "" ) ;
34+ setSuccessMessage ( "" ) ;
35+
36+ const result = await changePassword ( { password, newPassword } ) ;
37+
38+ if ( ! result . success ) {
39+ const msg =
40+ result . status === 400
41+ ? result . message || "현재 비밀번호가 올바르지 않습니다."
42+ : "비밀번호 변경 중 오류가 발생했습니다." ;
43+
44+ setErrorMessage ( msg ) ;
45+ setShowErrorModal ( true ) ;
46+ setIsSubmitting ( false ) ;
47+ return ;
48+ }
49+
50+ setSuccessMessage ( "비밀번호가 성공적으로 변경되었습니다." ) ;
51+ setShowSuccessModal ( true ) ;
52+ setPassword ( "" ) ;
53+ setNewPassword ( "" ) ;
54+ setCheckNewPassword ( "" ) ;
55+ setIsSubmitting ( false ) ;
56+ } ;
57+
2258 return (
2359 < div className = "sm:w-[672px] sm:h-[466px] w-[284px] h-[454px] bg-white rounded-[16px] shadow-md p-[24px] flex flex-col" >
2460 < h2 className = "text-[18px] sm:text-[24px] font-bold mb-4" >
@@ -30,12 +66,12 @@ export default function ChangePassword() {
3066 < Input
3167 type = "password"
3268 name = "password"
33- label = "비밀번호"
69+ label = "현재 비밀번호"
3470 labelClassName = "font-16r"
35- placeholder = "비밀번호 입력"
71+ placeholder = "현재 비밀번호 입력"
72+ value = { password }
3673 onChange = { setPassword }
3774 pattern = ".{8,}"
38- invalidMessage = "8자 이상 입력해주세요."
3975 className = "max-w-[620px]"
4076 />
4177 < Input
@@ -44,6 +80,7 @@ export default function ChangePassword() {
4480 label = "새 비밀번호"
4581 labelClassName = "font-16r"
4682 placeholder = "새 비밀번호 입력"
83+ value = { newPassword }
4784 onChange = { setNewPassword }
4885 pattern = ".{8,}"
4986 invalidMessage = "8자 이상 입력해주세요."
@@ -60,26 +97,28 @@ export default function ChangePassword() {
6097 placeholder = "새 비밀번호 입력"
6198 onChange = { ( e ) => setCheckNewPassword ( e . target . value ) }
6299 className = { `mt-3 sm:w-[624px] sm:h-[50px] w-[236px] h-[50px] px-[16px] pr-12 rounded-[8px] transition-colors focus:outline-none
63- ${
64- checkNewpassword
65- ? checkNewpassword === newPassword
66- ? "border border-gray-300"
67- : "border border-[var(--color-red)]"
68- : "border border-gray-300 focus:border-purple-500"
69- } `}
100+ ${
101+ checkNewpassword
102+ ? checkNewpassword === newPassword
103+ ? "border border-gray-300"
104+ : "border border-[var(--color-red)]"
105+ : "border border-gray-300 focus:border-purple-500"
106+ } `}
70107 />
71108 < button
72109 type = "button"
73110 onClick = { toggleCheckNewPasswordVisibility }
74111 className = "absolute right-4 top-6 flex size-6 items-center justify-center"
75112 >
76- < img
113+ < Image
77114 src = {
78115 showCheckNewPassword
79116 ? "/svgs/eye-on.svg"
80117 : "/svgs/eye-off.svg"
81118 }
82119 alt = "비밀번호 표시 토글"
120+ width = { 20 }
121+ height = { 20 }
83122 className = " w-5 h-5"
84123 />
85124 </ button >
@@ -93,11 +132,29 @@ export default function ChangePassword() {
93132 </ div >
94133 </ div >
95134
135+ { errorMessage && (
136+ < p className = "text-red-500 text-sm mt-4" > { errorMessage } </ p >
137+ ) }
138+ { successMessage && (
139+ < p className = "text-green-600 text-sm mt-4" > { successMessage } </ p >
140+ ) }
141+ < MypageModal
142+ isOpen = { showSuccessModal }
143+ onClose = { ( ) => setShowSuccessModal ( false ) }
144+ message = "비밀번호 변경에 성공하였습니다."
145+ />
146+
147+ < MypageModal
148+ isOpen = { showErrorModal }
149+ onClose = { ( ) => setShowErrorModal ( false ) }
150+ message = "비밀번호 변경에 실패하였습니다."
151+ />
96152 < button
97153 className = { `mt-2.5 cursor-pointer w-full sm:w-[624px] h-[54px]
98154 rounded-[8px] text-lg font-medium
99155 ${ isDisabled ? "bg-gray-300 cursor-not-allowed" : "bg-[#5A3FFF] text-white" } ` }
100- disabled = { isDisabled }
156+ onClick = { ( ) => handleChangePassword ( ) }
157+ disabled = { isDisabled || isSubmitting }
101158 >
102159 변경
103160 </ button >
0 commit comments