diff --git a/src/pages/Dashboard/AssetManagementContent.tsx b/src/pages/Dashboard/AssetManagementContent.tsx index 6ce9388..a1db487 100755 --- a/src/pages/Dashboard/AssetManagementContent.tsx +++ b/src/pages/Dashboard/AssetManagementContent.tsx @@ -26,6 +26,7 @@ const AssetManagementContent: React.FC = ({ const { t } = useTranslation(); const fileInputRef = useRef(null); const [isUploading, setIsUploading] = useState(false); + const [uploadProgress, setUploadProgress] = useState(0); const [uploadError, setUploadError] = useState(null); const [videoRatio, setVideoRatio] = useState('vertical'); const [displayCount, setDisplayCount] = useState(IMAGES_PER_PAGE); @@ -50,8 +51,16 @@ const AssetManagementContent: React.FC = ({ if (imageList.length === 0) return; setIsUploading(true); + setUploadProgress(0); setUploadError(null); + const interval = setInterval(() => { + setUploadProgress(prev => { + if (prev >= 99) return prev; + return prev + (prev < 50 ? 0.6 : prev < 80 ? 0.3 : prev < 90 ? 0.15 : 0.11); + }); + }, 300); + try { const urlImages: ImageUrlItem[] = imageList .filter((item: ImageItem): item is ImageItem & { type: 'url' } => item.type === 'url') @@ -63,13 +72,17 @@ const AssetManagementContent: React.FC = ({ if (urlImages.length > 0 || fileImages.length > 0) { const response = await uploadImages(urlImages, fileImages); + clearInterval(interval); + setUploadProgress(100); onNext(response.task_id); } } catch (error) { + clearInterval(interval); console.error('Image upload failed:', error); setUploadError(error instanceof Error ? error.message : t('assetManagement.uploadFailed')); } finally { setIsUploading(false); + setUploadProgress(0); } }; @@ -104,6 +117,29 @@ const AssetManagementContent: React.FC = ({ return (
+ {isUploading && ( +
+
+
+
+
+
+
+
+

{t('assetManagement.uploading')}

+
+
+
+
+ {Math.floor(uploadProgress)}% +
+
+
+ )} + {/* Fixed Header - 뒤로가기 버튼 */}
{onBack && ( diff --git a/src/styles/landing.css b/src/styles/landing.css index 7f07141..41e77e2 100644 --- a/src/styles/landing.css +++ b/src/styles/landing.css @@ -1543,7 +1543,7 @@ } .loading-progress-text { - font-size: 13px; + font-size: 14px; color: rgba(255, 255, 255, 0.5); font-variant-numeric: tabular-nums; } diff --git a/src/styles/studio-assets.css b/src/styles/studio-assets.css index 62aad40..3f8e91f 100644 --- a/src/styles/studio-assets.css +++ b/src/styles/studio-assets.css @@ -814,6 +814,25 @@ position: relative; } +/* Upload Loading Overlay */ +.asset-upload-overlay { + position: fixed; + inset: 0; + z-index: 1000; + background: rgba(0, 25, 26, 0.85); + display: flex; + align-items: center; + justify-content: center; +} + +.asset-upload-overlay-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 0; +} + + /* Fixed Header - 뒤로가기 */ .asset-sticky-header { position: fixed;