From 76e0c2ee72b70dd21abc35da3fc88f1e4fbf1819 Mon Sep 17 00:00:00 2001 From: caadiq Date: Thu, 22 Jan 2026 09:23:24 +0900 Subject: [PATCH] =?UTF-8?q?feat(frontend-temp):=20Phase=2010=20-=20?= =?UTF-8?q?=EC=95=A8=EB=B2=94=20=EB=AA=A9=EB=A1=9D=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PC 앨범 페이지: - 앨범 목록 그리드 (4열) - 앨범 타입별 통계 (정규/미니/싱글/총) - 호버 시 트랙 수 표시 - 타이틀곡 및 발매일 표시 Mobile 앨범 페이지: - 앨범 목록 그리드 (2열) - 앨범 타입 및 발매년도 표시 Note: 앨범 상세 페이지(AlbumDetail, AlbumGallery)는 추후 구현 예정 Co-Authored-By: Claude Opus 4.5 --- frontend-temp/src/App.jsx | 18 ++- frontend-temp/src/pages/album/MobileAlbum.jsx | 59 +++++++ frontend-temp/src/pages/album/PCAlbum.jsx | 146 ++++++++++++++++++ frontend-temp/src/pages/album/index.js | 2 + 4 files changed, 221 insertions(+), 4 deletions(-) create mode 100644 frontend-temp/src/pages/album/MobileAlbum.jsx create mode 100644 frontend-temp/src/pages/album/PCAlbum.jsx create mode 100644 frontend-temp/src/pages/album/index.js diff --git a/frontend-temp/src/App.jsx b/frontend-temp/src/App.jsx index a9ef215..4e5ffcb 100644 --- a/frontend-temp/src/App.jsx +++ b/frontend-temp/src/App.jsx @@ -15,6 +15,7 @@ import { Layout as MobileLayout } from '@/components/mobile'; import { PCHome, MobileHome } from '@/pages/home'; import { PCMembers, MobileMembers } from '@/pages/members'; import { PCSchedule, MobileSchedule } from '@/pages/schedule'; +import { PCAlbum, MobileAlbum } from '@/pages/album'; /** * PC 환경에서 body에 클래스 추가하는 래퍼 @@ -52,8 +53,9 @@ function App() { } /> } /> } /> - {/* 추가 페이지는 Phase 10-11에서 구현 */} - {/* } /> */} + } /> + {/* 추가 페이지는 Phase 11에서 구현 */} + {/* } /> */} {/* } /> */} @@ -90,8 +92,16 @@ function App() { } /> - {/* 추가 페이지는 Phase 10-11에서 구현 */} - {/* } /> */} + + + + } + /> + {/* 추가 페이지는 Phase 11에서 구현 */} + {/* } /> */} diff --git a/frontend-temp/src/pages/album/MobileAlbum.jsx b/frontend-temp/src/pages/album/MobileAlbum.jsx new file mode 100644 index 0000000..cf12638 --- /dev/null +++ b/frontend-temp/src/pages/album/MobileAlbum.jsx @@ -0,0 +1,59 @@ +import { motion } from 'framer-motion'; +import { useQuery } from '@tanstack/react-query'; +import { useNavigate } from 'react-router-dom'; +import { getAlbums } from '@/api/albums'; + +/** + * Mobile 앨범 목록 페이지 + */ +function MobileAlbum() { + const navigate = useNavigate(); + + const { data: albums = [], isLoading: loading } = useQuery({ + queryKey: ['albums'], + queryFn: getAlbums, + }); + + if (loading) { + return ( +
+
+
+ ); + } + + return ( +
+
+ {albums.map((album, index) => ( + navigate(`/album/${encodeURIComponent(album.title)}`)} + className="bg-white rounded-2xl overflow-hidden shadow-md" + > +
+ {album.cover_thumb_url && ( + {album.title} + )} +
+
+

{album.title}

+

+ {album.album_type_short} · {album.release_date?.slice(0, 4)} +

+
+
+ ))} +
+
+ ); +} + +export default MobileAlbum; diff --git a/frontend-temp/src/pages/album/PCAlbum.jsx b/frontend-temp/src/pages/album/PCAlbum.jsx new file mode 100644 index 0000000..72df0b3 --- /dev/null +++ b/frontend-temp/src/pages/album/PCAlbum.jsx @@ -0,0 +1,146 @@ +import { useQuery } from '@tanstack/react-query'; +import { useNavigate } from 'react-router-dom'; +import { motion } from 'framer-motion'; +import { Calendar, Music } from 'lucide-react'; +import { getAlbums } from '@/api/albums'; +import { formatDate } from '@/utils'; + +/** + * PC 앨범 목록 페이지 + */ +function PCAlbum() { + const navigate = useNavigate(); + + const { data: albums = [], isLoading: loading } = useQuery({ + queryKey: ['albums'], + queryFn: getAlbums, + }); + + // 타이틀곡 찾기 + const getTitleTrack = (tracks) => { + if (!tracks || tracks.length === 0) return ''; + const titleTrack = tracks.find((t) => t.is_title_track); + return titleTrack ? titleTrack.title : tracks[0].title; + }; + + // 앨범 타입별 개수 계산 + const getAlbumType = (album) => album.album_type_short || album.album_type; + const albumStats = { + 정규: albums.filter((a) => getAlbumType(a) === '정규').length, + 미니: albums.filter((a) => getAlbumType(a) === '미니').length, + 싱글: albums.filter((a) => getAlbumType(a) === '싱글').length, + 총: albums.length, + }; + + // 앨범 클릭 + const handleAlbumClick = (albumTitle) => { + navigate(`/album/${encodeURIComponent(albumTitle)}`); + }; + + if (loading) { + return ( +
+
+
+ ); + } + + return ( +
+
+ {/* 헤더 */} +
+ + 앨범 + + + 프로미스나인의 음악을 만나보세요 + +
+ + {/* 통계 */} + +
+

{albumStats.정규}

+

정규 앨범

+
+
+

{albumStats.미니}

+

미니 앨범

+
+
+

{albumStats.싱글}

+

싱글 앨범

+
+
+

{albumStats.총}

+

총 앨범

+
+
+ + {/* 앨범 그리드 */} +
+ {albums.map((album, index) => ( + handleAlbumClick(album.title)} + > + {/* 앨범 커버 */} +
+ {album.title} + + {/* 호버 오버레이 */} +
+
+ +

{album.tracks?.length || 0}곡 수록

+
+
+
+ + {/* 앨범 정보 */} +
+
+

{album.title}

+ + {album.album_type_short || album.album_type} + +
+

{getTitleTrack(album.tracks)}

+
+ + {formatDate(album.release_date, 'YYYY.MM.DD')} +
+
+
+ ))} +
+
+
+ ); +} + +export default PCAlbum; diff --git a/frontend-temp/src/pages/album/index.js b/frontend-temp/src/pages/album/index.js new file mode 100644 index 0000000..1b4df39 --- /dev/null +++ b/frontend-temp/src/pages/album/index.js @@ -0,0 +1,2 @@ +export { default as PCAlbum } from './PCAlbum'; +export { default as MobileAlbum } from './MobileAlbum';