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) => (
+ goToIndex(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) => (
- setLightbox(prev => ({ ...prev, index: 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) => (
- setLightbox(prev => ({ ...prev, index: 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')}