@@ -7,15 +7,23 @@ import { useNavigate } from "react-router-dom";
77import { useTimetable } from "@/contexts/TimetableContext" ;
88import { useEffect , useState } from "react" ;
99import { RiPencilFill } from "react-icons/ri" ;
10- import { FaCamera } from "react-icons/fa6" ;
10+ import { FaCamera , FaStar } from "react-icons/fa6" ;
1111import { IoMdDoneAll } from "react-icons/io" ;
12+ import { useUserData } from "@/contexts/UserDataContext" ;
13+ import Onboarding from "./auth/OnBoarding/Onboarding" ;
14+ import Modal from "@/widgets/Modal" ;
15+ import Loading from "@/widgets/Loading" ;
16+ import defaultProfile from "/assets/defaultProfile.png" ;
1217
13- const ProfileCard = ( ) => {
18+ const ProfileCard = ( { onClickInterest } : { onClickInterest : ( ) => void } ) => {
1419 const { user, updateUsername, setProfileImg } = useAuth ( ) ;
20+ const { interestCategories } = useUserData ( ) ;
1521 const { timetables } = useTimetable ( ) ;
1622 const [ profilePreviewUrl , setProfilePreviewUrl ] = useState < string > (
17- user ? user . profileImageUrl : "/assets/defaultProfile.png" ,
18- ) ;
23+ ( user ?. profileImageUrl && user . profileImageUrl !== "" )
24+ ? user . profileImageUrl
25+ : defaultProfile
26+ ) ;
1927 const [ imgFile , setImgFile ] = useState < File | null > ( null ) ;
2028 const [ , setIsDefaultProfile ] = useState < boolean > ( false ) ;
2129 const [ username , setUsername ] = useState < string > (
@@ -25,7 +33,7 @@ const ProfileCard = () => {
2533 const navigate = useNavigate ( ) ;
2634
2735 const handleImageError = ( ) => {
28- setProfilePreviewUrl ( "/assets/ defaultProfile.png" ) ;
36+ setProfilePreviewUrl ( defaultProfile ) ;
2937 } ;
3038
3139 const handleImageChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
@@ -49,6 +57,13 @@ const ProfileCard = () => {
4957 setImgFile ( null ) ;
5058 } ;
5159
60+ useEffect ( ( ) => {
61+ if ( user ?. profileImageUrl && user . profileImageUrl . trim ( ) !== "" ) {
62+ setProfilePreviewUrl ( user . profileImageUrl ) ;
63+ } else {
64+ setProfilePreviewUrl ( defaultProfile ) ;
65+ }
66+ } , [ user ?. profileImageUrl ] ) ;
5267 // profile image preview url cleanup (cleanup callback is executed before next effect / component unmount)
5368 useEffect ( ( ) => {
5469 return ( ) => {
@@ -63,8 +78,8 @@ const ProfileCard = () => {
6378 < div className = { styles . profileRow } >
6479 < div className = { styles . profileImgWrapper } >
6580 < img
66- src = { profilePreviewUrl }
6781 alt = "profile img"
82+ src = { profilePreviewUrl }
6883 onError = { handleImageError }
6984 />
7085 { isEditmode && (
@@ -121,6 +136,26 @@ const ProfileCard = () => {
121136 />
122137 ) }
123138 </ div >
139+ < button className = { styles . preferenceCol } type = 'button' onClick = { onClickInterest } >
140+ < div className = { styles . preferenceHeader } >
141+ < FaStar size = { 24 } color = "#828282" style = { { marginRight : 12 } } />
142+ < span > 행사 보기 우선순위</ span >
143+ </ div >
144+ { ( interestCategories && interestCategories . length > 0 ) ? (
145+ < div >
146+ < ul className = { styles . preferenceChips } >
147+ { interestCategories . map ( ( cat , idx ) => (
148+ < li className = { `${ styles . preferenceChip } ${ cat . groupId === 3 && styles . category } ${ cat . groupId === 2 && styles . organization } ` } key = { cat . id } >
149+ { `${ idx + 1 } 순위: ${ cat . name } ` }
150+ </ li >
151+ ) ) }
152+ </ ul >
153+ </ div >
154+ ) : (
155+ < span className = { styles . notYetText } > 클릭해서 우선순위로 확인할 행사를 설정해보세요!</ span >
156+ )
157+ }
158+ </ button >
124159 < button
125160 type = "button"
126161 className = { styles . timeTableBtn }
@@ -146,21 +181,42 @@ const ProfileCard = () => {
146181} ;
147182
148183const MyPage = ( ) => {
149- const { user } = useAuth ( ) ;
184+ const { user, isLoading } = useAuth ( ) ;
185+ const [ isEditingInterest , setIsEditingInterest ] = useState < boolean > ( false ) ;
186+ const navigate = useNavigate ( ) ;
150187
151188 return (
152189 < div className = { styles . main } >
153190 < Navigationbar />
154- { user ? (
155- < div className = { styles . mypageContainer } >
156- < ProfileCard />
157- < div className = { styles . widgetsWrapper } >
158- < BookmarkWidget />
159- < MemoWidget />
160- </ div >
161- </ div >
191+ { isLoading ?
192+ (
193+ < Loading />
194+ )
195+ : (
196+ isEditingInterest ? (
197+ < Onboarding isEditing = { true } onFinishEdit = { ( ) => setIsEditingInterest ( false ) } />
162198 ) : (
163- < div className = { styles . notFound } > { /* Login modal */ } </ div >
199+ user ? (
200+ < div className = { styles . mypageContainer } >
201+ < ProfileCard onClickInterest = { ( ) => setIsEditingInterest ( ( ) => true ) } />
202+ < div className = { styles . widgetsWrapper } >
203+ < BookmarkWidget />
204+ < MemoWidget />
205+ </ div >
206+ </ div >
207+ ) : (
208+ < div className = { styles . notFound } >
209+ < Modal
210+ content = "마이페이지 이용을 위해서는 로그인을 해주세요."
211+ leftText = "로그인"
212+ rightText = "회원가입"
213+ onLeftClick = { ( ) => navigate ( '/auth/login' ) }
214+ onRightClick = { ( ) => navigate ( '/auth/signup' ) }
215+ onClose = { null }
216+ />
217+ </ div >
218+ )
219+ )
164220 ) }
165221 </ div >
166222 ) ;
0 commit comments