1- import { useState } from 'react' ;
1+ import { useEffect , useState } from 'react' ;
22import useConfirm from '../../hooks/useConfirm' ;
3- import { useNavigate } from 'react-router-dom' ;
4- import { Trophy , BarChart3 } from 'lucide-react' ;
3+ import { useNavigate } from 'react-router-dom' ;
4+ import { BarChart3 , Trophy } from 'lucide-react' ;
55import styles from './mypage.module.scss'
6+ import axios from "axios" ;
7+ import NicknameForm from "../login/NicknameForm" ;
8+ import { useApiQuery } from "../../hooks/useApiQuery" ;
9+ import { useApiMutation } from "../../hooks/useApiMutation" ;
610
7- const userStats = {
8- nickname : '빵야빵야' ,
9- totalGames : 50 ,
10- wins : 30 ,
11- losses : 20 ,
12- score : 70 ,
13- currentRank : 3 ,
11+ const userRequest = async ( ) => {
12+ const response = await axios . get ( `/user/me` ) ;
13+ return response . data ;
14+ } ;
15+
16+ const userDeleteRequest = async ( ) => {
17+ await axios . delete ( `/user/me` ) ;
18+ } ;
19+
20+ const userEditRequest = async ( nickname ) => {
21+ const params = {
22+ nickname
23+ } ;
24+ await axios . put ( '/user/me' , params ) ;
1425} ;
1526
1627const MyPage = ( ) => {
1728 const [ nickname , setNickname ] = useState ( '빵야빵야' ) ;
29+ const [ error , setError ] = useState ( {
30+ nickname : "" ,
31+ } ) ;
32+ const [ inputStatus , setInputStatus ] = useState ( {
33+ nickname : false ,
34+ } ) ;
1835 const { openConfirm } = useConfirm ( ) ;
1936 const navigate = useNavigate ( ) ;
37+ const { data } = useApiQuery (
38+ [ '/user/me' ] ,
39+ ( ) => userRequest ( )
40+ ) ;
41+ const { mutate : userDeleteMutate } = useApiMutation ( userDeleteRequest , {
42+ onSuccess : ( ) => {
43+ // 회원가입 완료 후 방 목록으로 이동
44+ navigate ( "/login" ) ;
45+ } ,
46+ } ) ;
2047
21- const handleDuplicateCheck = ( ) => {
22- openConfirm ( {
23- title : '중복 확인' ,
24- html : < div > 사용 가능한 닉네임입니다.</ div > ,
25- confirmButtonText : '확인' ,
26- } ) ;
27- } ;
48+ const { mutate : userEditMutate } = useApiMutation ( userEditRequest , {
49+ onSuccess : ( ) => {
50+ openConfirm ( {
51+ title : '프로필 수정' ,
52+ html : < div > 저장되었습니다.</ div > ,
53+ confirmButtonText : '확인' ,
54+ } ) ;
55+ } ,
56+ } ) ;
2857
29- const handleSaveClick = ( ) => {
30- openConfirm ( {
31- title : '프로필 수정' ,
32- html : < div > 저장되었습니다.</ div > ,
33- confirmButtonText : '확인' ,
34- } ) ;
58+ useEffect ( ( ) => {
59+ if ( data ) {
60+ setNickname ( data . nickname )
61+ }
62+ } , [ data ] )
63+
64+ const handleSaveClick = ( e ) => {
65+ e . preventDefault ( ) ;
66+ userEditMutate ( nickname ) ;
3567 } ;
3668
3769 const handleExitClick = ( ) => {
@@ -45,7 +77,7 @@ const MyPage = () => {
4577 </ div >
4678 ) ,
4779 confirmButtonText : '탈퇴' ,
48- callback : ( ) => navigate ( '/login' ) ,
80+ callback : ( ) => userDeleteMutate ( ) ,
4981 } ) ;
5082 } ;
5183
@@ -59,34 +91,14 @@ const MyPage = () => {
5991 < span className = { styles . headerText } > 프로필 정보</ span >
6092 </ div >
6193 < div className = { styles . form } >
62- < form >
63- { /* 닉네임 섹션 */ }
64- < div className = { styles . inputRow } >
65- < label className = { styles . label } > 닉네임</ label >
66- < input
67- type = 'text'
68- value = { nickname }
69- onChange = { ( e ) => setNickname ( e . target . value ) }
70- className = { styles . input }
71- onFocus = { ( e ) => ( e . target . style . borderColor = '#dc2626' ) }
72- onBlur = { ( e ) =>
73- ( e . target . style . borderColor = 'rgba(220, 38, 38, 0.5)' )
74- }
75- />
76- < button
77- type = 'button'
78- onClick = { handleDuplicateCheck }
79- className = { styles . button }
80- onMouseOver = { ( e ) =>
81- ( e . target . style . backgroundColor = '#b91c1c' )
82- }
83- onMouseOut = { ( e ) =>
84- ( e . target . style . backgroundColor = '#dc2626' )
85- }
86- >
87- 중복 체크
88- </ button >
89- </ div >
94+ < form className = { styles . nicknameForm } onSubmit = { handleSaveClick } >
95+ < NicknameForm
96+ nickname = { nickname }
97+ setNickname = { setNickname }
98+ error = { error }
99+ setError = { setError }
100+ setInputStatus = { setInputStatus }
101+ />
90102
91103 { /* 게임 통계 섹션 */ }
92104 < div className = { styles . statsCard } >
@@ -98,18 +110,18 @@ const MyPage = () => {
98110 < div className = { styles . statsRow } >
99111 < label className = { styles . label } > 전적</ label >
100112 < span style = { { color : '#374151' , fontWeight : '600' } } >
101- { userStats . totalGames } 전 { userStats . wins } 승{ ' ' }
102- { userStats . losses } 패
113+ { data ? .totalGames } 전 { data ?. winningGames } 승{ ' ' }
114+ { data ? ( data . totalGames - data . winningGames ) : '' } 패
103115 </ span >
104116 </ div >
105117 < div className = { styles . statsRow } >
106118 < label className = { styles . label } > 점수</ label >
107- < span className = { styles . score } > { userStats . score } 점</ span >
119+ < span className = { styles . score } > { data ? .score } 점</ span >
108120 </ div >
109121 < div className = { styles . statsRow } >
110122 < label className = { styles . label } > 현재 랭킹</ label >
111123 < span className = { styles . rankBadge } >
112- { userStats . currentRank } 위
124+ { data ?. rank } 위
113125 </ span >
114126 </ div >
115127 </ div >
@@ -118,17 +130,9 @@ const MyPage = () => {
118130 { /* 버튼 영역 */ }
119131 < div className = { styles . buttonGroup } >
120132 < button
121- type = 'button'
122- onClick = { handleSaveClick }
133+ type = 'submit'
123134 className = { styles . saveButton }
124- onMouseOver = { ( e ) => {
125- e . target . style . backgroundColor = '#dc2626' ;
126- e . target . style . color = 'white' ;
127- } }
128- onMouseOut = { ( e ) => {
129- e . target . style . backgroundColor = 'transparent' ;
130- e . target . style . color = '#dc2626' ;
131- } }
135+ disabled = { ! inputStatus . nickname }
132136 >
133137 변경사항 저장
134138 </ button >
0 commit comments