From cdca23e31798786f8e8f1c070b2bc3fe2f4dc31e Mon Sep 17 00:00:00 2001 From: caadiq Date: Sat, 10 Jan 2026 09:06:26 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20PC=20public=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EA=B3=B5=ED=86=B5=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EB=B0=8F=20=EC=9C=A0=ED=8B=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - LightboxIndicator 공통 컴포넌트 생성 및 AlbumDetail, AlbumGallery에 적용 - formatDate를 utils/date에서 import하도록 변경 (Album, Members, AlbumDetail) - 중복 코드 약 100줄 제거 --- .../components/common/LightboxIndicator.jsx | 42 ++++++++++++++++ frontend/src/pages/pc/public/Album.jsx | 10 +--- frontend/src/pages/pc/public/AlbumDetail.jsx | 49 ++----------------- frontend/src/pages/pc/public/AlbumGallery.jsx | 40 ++------------- frontend/src/pages/pc/public/Members.jsx | 12 ++--- 5 files changed, 55 insertions(+), 98 deletions(-) create mode 100644 frontend/src/components/common/LightboxIndicator.jsx diff --git a/frontend/src/components/common/LightboxIndicator.jsx b/frontend/src/components/common/LightboxIndicator.jsx new file mode 100644 index 0000000..d317282 --- /dev/null +++ b/frontend/src/components/common/LightboxIndicator.jsx @@ -0,0 +1,42 @@ +import { memo } from 'react'; + +/** + * 라이트박스 인디케이터 컴포넌트 + * 이미지 갤러리에서 현재 위치를 표시하는 슬라이딩 점 인디케이터 + * CSS transition 사용으로 GPU 가속 + */ +const LightboxIndicator = memo(function LightboxIndicator({ count, currentIndex, goToIndex }) { + const translateX = -(currentIndex * 18) + 100 - 6; + + return ( +
+ {/* 양옆 페이드 그라데이션 */} +
+ {/* 슬라이딩 컨테이너 - CSS transition으로 GPU 가속 */} +
+ {Array.from({ length: count }).map((_, i) => ( +
+
+ ); +}); + +export default LightboxIndicator; diff --git a/frontend/src/pages/pc/public/Album.jsx b/frontend/src/pages/pc/public/Album.jsx index 9ac000f..e2ac260 100644 --- a/frontend/src/pages/pc/public/Album.jsx +++ b/frontend/src/pages/pc/public/Album.jsx @@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { motion } from 'framer-motion'; import { Calendar, Music } from 'lucide-react'; import { getAlbums } from '../../../api/public/albums'; +import { formatDate } from '../../../utils/date'; function Album() { const navigate = useNavigate(); @@ -21,13 +22,6 @@ function Album() { }); }, []); - // 날짜 포맷팅 - const formatDate = (dateStr) => { - if (!dateStr) return ''; - const date = new Date(dateStr); - return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, '0')}.${String(date.getDate()).padStart(2, '0')}`; - }; - // 타이틀곡 찾기 const getTitleTrack = (tracks) => { if (!tracks || tracks.length === 0) return ''; @@ -149,7 +143,7 @@ function Album() {

- {formatDate(album.release_date)} + {formatDate(album.release_date, 'YYYY.MM.DD')}
diff --git a/frontend/src/pages/pc/public/AlbumDetail.jsx b/frontend/src/pages/pc/public/AlbumDetail.jsx index 1acad0a..e884dd3 100644 --- a/frontend/src/pages/pc/public/AlbumDetail.jsx +++ b/frontend/src/pages/pc/public/AlbumDetail.jsx @@ -3,41 +3,9 @@ import { useParams, useNavigate } from 'react-router-dom'; import { motion, AnimatePresence } from 'framer-motion'; import { Calendar, Music2, Clock, X, ChevronLeft, ChevronRight, Download, MoreVertical, FileText } from 'lucide-react'; import { getAlbumByName } from '../../../api/public/albums'; +import { formatDate } from '../../../utils/date'; +import LightboxIndicator from '../../../components/common/LightboxIndicator'; -// 인디케이터 컴포넌트 - CSS transition 사용으로 JS 블로킹에 영향받지 않음 -const LightboxIndicator = memo(function LightboxIndicator({ count, currentIndex, setLightbox }) { - const translateX = -(currentIndex * 18) + 100 - 6; - - return ( -
- {/* 양옆 페이드 그라데이션 */} -
- {/* 슬라이딩 컨테이너 - CSS transition으로 GPU 가속 */} -
- {Array.from({ length: count }).map((_, i) => ( -
-
- ); -}); function AlbumDetail() { const { name } = useParams(); const navigate = useNavigate(); @@ -171,13 +139,6 @@ function AlbumDetail() { // URL 헬퍼 함수는 더 이상 필요 없음 - API에서 직접 제공 - // 날짜 포맷팅 - const formatDate = (dateStr) => { - if (!dateStr) return ''; - const date = new Date(dateStr); - return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, '0')}.${String(date.getDate()).padStart(2, '0')}`; - }; - // 총 재생 시간 계산 const getTotalDuration = () => { if (!album?.tracks) return ''; @@ -317,7 +278,7 @@ function AlbumDetail() {
- {formatDate(album.release_date)} + {formatDate(album.release_date, 'YYYY.MM.DD')}
@@ -568,12 +529,12 @@ function AlbumDetail() { )} - {/* 인디케이터 - memo 컴포넌트로 분리 */} + {/* 인디케이터 - 공통 컴포넌트 사용 */} {lightbox.images.length > 1 && ( setLightbox(prev => ({ ...prev, index: i }))} /> )}
diff --git a/frontend/src/pages/pc/public/AlbumGallery.jsx b/frontend/src/pages/pc/public/AlbumGallery.jsx index 41df695..f101f8f 100644 --- a/frontend/src/pages/pc/public/AlbumGallery.jsx +++ b/frontend/src/pages/pc/public/AlbumGallery.jsx @@ -5,41 +5,7 @@ import { X, ChevronLeft, ChevronRight, Download } from 'lucide-react'; import { RowsPhotoAlbum } from 'react-photo-album'; import 'react-photo-album/rows.css'; import { getAlbumByName } from '../../../api/public/albums'; - -// 인디케이터 컴포넌트 - CSS transition 사용으로 JS 블로킹에 영향받지 않음 -const LightboxIndicator = memo(function LightboxIndicator({ count, currentIndex, setLightbox }) { - const translateX = -(currentIndex * 18) + 100 - 6; - - return ( -
- {/* 양옆 페이드 그라데이션 */} -
- {/* 슬라이딩 컨테이너 - CSS transition으로 GPU 가속 */} -
- {Array.from({ length: count }).map((_, i) => ( -
-
- ); -}); +import LightboxIndicator from '../../../components/common/LightboxIndicator'; // CSS로 호버 효과 추가 + overflow 문제 수정 + 로드 애니메이션 const galleryStyles = ` @@ -392,11 +358,11 @@ function AlbumGallery() { )} - {/* 하단 점 인디케이터 - memo 컴포넌트로 분리 */} + {/* 하단 점 인디케이터 - 공통 컴포넌트 사용 */} setLightbox(prev => ({ ...prev, index: i }))} />
diff --git a/frontend/src/pages/pc/public/Members.jsx b/frontend/src/pages/pc/public/Members.jsx index 80bb09c..e529ab3 100644 --- a/frontend/src/pages/pc/public/Members.jsx +++ b/frontend/src/pages/pc/public/Members.jsx @@ -2,6 +2,7 @@ import { useState, useEffect } from 'react'; import { motion } from 'framer-motion'; import { Instagram, Calendar } from 'lucide-react'; import { getMembers } from '../../../api/public/members'; +import { formatDate } from '../../../utils/date'; function Members() { const [members, setMembers] = useState([]); @@ -19,13 +20,6 @@ function Members() { }); }, []); - // 날짜 포맷팅 함수 - const formatDate = (dateStr) => { - if (!dateStr) return ''; - const date = new Date(dateStr); - return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, '0')}.${String(date.getDate()).padStart(2, '0')}`; - }; - if (loading) { return (
@@ -83,7 +77,7 @@ function Members() {
- {formatDate(member.birth_date)} + {formatDate(member.birth_date, 'YYYY.MM.DD')}
{/* 인스타그램 링크 */} @@ -142,7 +136,7 @@ function Members() {
- {formatDate(member.birth_date)} + {formatDate(member.birth_date, 'YYYY.MM.DD')}