@@ -2,14 +2,18 @@ import { useEffect, useState, useRef } from 'react';
22import getProfileImages from '../../api/getProfileImages.js' ;
33import uploadImage from '../../api/postUpload.js' ;
44import DEFAULT_PROFILE_IMAGE from '../../constants/image.js' ;
5+ import UploadProgressBar from '../common/UploadProgressBar.jsx' ;
56import styles from './UserProfileSelector.module.scss' ;
67
78export default function UserProfileSelector ( {
89 value = DEFAULT_PROFILE_IMAGE ,
910 onSelect,
11+ isUploading,
12+ setIsUploading,
1013} ) {
1114 const [ profileImages , setProfileImages ] = useState ( [ ] ) ;
1215 const [ loadedImages , setLoadedImages ] = useState ( { } ) ;
16+ const [ uploadProgress , setUploadProgress ] = useState ( 0 ) ;
1317 const fileInput = useRef ( null ) ;
1418
1519 useEffect ( ( ) => {
@@ -28,11 +32,21 @@ export default function UserProfileSelector({
2832 const file = e . target . files [ 0 ] ;
2933 if ( ! file ) return ;
3034
35+ e . target . value = null ;
36+
37+ setIsUploading ( true ) ;
38+
3139 try {
32- const uploadedUrl = await uploadImage ( file ) ;
40+ const uploadedUrl = await uploadImage ( file , ( percent ) => {
41+ setUploadProgress ( percent ) ;
42+ } ) ;
43+
3344 onSelect ?. ( uploadedUrl ) ;
3445 } catch ( error ) {
3546 alert ( '이미지 업로드 실패했습니다.' ) ;
47+ } finally {
48+ setIsUploading ( false ) ;
49+ setUploadProgress ( 0 ) ;
3650 }
3751 } ;
3852
@@ -44,12 +58,17 @@ export default function UserProfileSelector({
4458 < div className = { styles [ 'profile-select' ] } >
4559 < h2 className = { styles [ 'profile-select__title' ] } > 프로필 이미지</ h2 >
4660 < div className = { styles [ 'profile-select__content' ] } >
47- < img
48- src = { value }
49- alt = "선택된 프로필 및 업로드 이미지"
50- className = { styles [ 'profile-select__selected-image' ] }
51- onClick = { triggerFileSeletor }
52- />
61+ < div className = { styles [ 'profile-select__selected-wrapper' ] } >
62+ < img
63+ src = { value }
64+ alt = "선택된 프로필 및 업로드 이미지"
65+ className = { styles [ 'profile-select__selected-image' ] }
66+ onClick = { triggerFileSeletor }
67+ />
68+
69+ { isUploading && < UploadProgressBar progress = { uploadProgress } /> }
70+ </ div >
71+
5372 < input
5473 type = "file"
5574 accept = "image/*"
@@ -69,8 +88,11 @@ export default function UserProfileSelector({
6988 alt = { `profile-${ idx } ` }
7089 className = { `${ styles [ 'profile-select__image' ] } ${
7190 value === url ? styles [ 'profile-select__image--selected' ] : ''
72- } ${ ! loadedImages [ url ] ? styles [ 'profile-select__image--loading' ] : '' } `}
73- onClick = { ( ) => onSelect ?. ( url ) }
91+ } ${ ! loadedImages [ url ] ? styles [ 'profile-select__image--loading' ] : '' }
92+ ${ isUploading ? styles [ 'profile-select__image--disabled' ] : '' } ` }
93+ onClick = { ( ) => {
94+ if ( ! isUploading ) onSelect ?. ( url ) ;
95+ } }
7496 onLoad = { ( ) => handleImageLoad ( url ) }
7597 />
7698 ) ) }
0 commit comments