diff --git a/frontend/src/api/public/albums.js b/frontend/src/api/public/albums.js index b0b3280..663b822 100644 --- a/frontend/src/api/public/albums.js +++ b/frontend/src/api/public/albums.js @@ -8,11 +8,16 @@ export async function getAlbums() { return fetchApi("/api/albums"); } -// 앨범 상세 조회 +// 앨범 상세 조회 (ID) export async function getAlbum(id) { return fetchApi(`/api/albums/${id}`); } +// 앨범 상세 조회 (이름) +export async function getAlbumByName(name) { + return fetchApi(`/api/albums/by-name/${name}`); +} + // 앨범 사진 조회 export async function getAlbumPhotos(albumId) { return fetchApi(`/api/albums/${albumId}/photos`); diff --git a/frontend/src/pages/mobile/public/Home.jsx b/frontend/src/pages/mobile/public/Home.jsx index 9dfc241..72b06c4 100644 --- a/frontend/src/pages/mobile/public/Home.jsx +++ b/frontend/src/pages/mobile/public/Home.jsx @@ -3,6 +3,9 @@ import { ChevronRight, Clock, Tag } from 'lucide-react'; import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { getTodayKST } from '../../../utils/date'; +import { getMembers } from '../../../api/public/members'; +import { getAlbums } from '../../../api/public/albums'; +import { getUpcomingSchedules } from '../../../api/public/schedules'; // 모바일 홈 페이지 function MobileHome() { @@ -14,21 +17,17 @@ function MobileHome() { // 데이터 로드 useEffect(() => { // 멤버 로드 - fetch('/api/members') - .then(res => res.json()) + getMembers() .then(data => setMembers(data.filter(m => !m.is_former))) .catch(console.error); - // 앨범 로드 (최신 4개) - fetch('/api/albums') - .then(res => res.json()) + // 앨범 로드 (최신 2개) + getAlbums() .then(data => setAlbums(data.slice(0, 2))) .catch(console.error); // 다가오는 일정 로드 - const today = getTodayKST(); - fetch(`/api/schedules?startDate=${today}&limit=3`) - .then(res => res.json()) + getUpcomingSchedules(3) .then(data => setSchedules(data)) .catch(console.error); }, []); diff --git a/frontend/src/pages/pc/public/Album.jsx b/frontend/src/pages/pc/public/Album.jsx index fbc367c..9ac000f 100644 --- a/frontend/src/pages/pc/public/Album.jsx +++ b/frontend/src/pages/pc/public/Album.jsx @@ -2,6 +2,7 @@ import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { motion } from 'framer-motion'; import { Calendar, Music } from 'lucide-react'; +import { getAlbums } from '../../../api/public/albums'; function Album() { const navigate = useNavigate(); @@ -9,8 +10,7 @@ function Album() { const [loading, setLoading] = useState(true); useEffect(() => { - fetch('/api/albums') - .then(res => res.json()) + getAlbums() .then(data => { setAlbums(data); setLoading(false); diff --git a/frontend/src/pages/pc/public/AlbumDetail.jsx b/frontend/src/pages/pc/public/AlbumDetail.jsx index fbc09b2..1acad0a 100644 --- a/frontend/src/pages/pc/public/AlbumDetail.jsx +++ b/frontend/src/pages/pc/public/AlbumDetail.jsx @@ -2,6 +2,7 @@ import { useState, useEffect, useCallback, memo } from 'react'; 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'; // 인디케이터 컴포넌트 - CSS transition 사용으로 JS 블로킹에 영향받지 않음 const LightboxIndicator = memo(function LightboxIndicator({ count, currentIndex, setLightbox }) { @@ -157,8 +158,7 @@ function AlbumDetail() { }, [lightbox.open, lightbox.index, lightbox.images, preloadedImages]); useEffect(() => { - fetch(`/api/albums/by-name/${name}`) - .then(res => res.json()) + getAlbumByName(name) .then(data => { setAlbum(data); setLoading(false); diff --git a/frontend/src/pages/pc/public/AlbumGallery.jsx b/frontend/src/pages/pc/public/AlbumGallery.jsx index 6eb74f3..41df695 100644 --- a/frontend/src/pages/pc/public/AlbumGallery.jsx +++ b/frontend/src/pages/pc/public/AlbumGallery.jsx @@ -4,6 +4,7 @@ import { motion, AnimatePresence } from 'framer-motion'; 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 }) { @@ -82,8 +83,7 @@ function AlbumGallery() { const [preloadedImages] = useState(() => new Set()); // 프리로드된 이미지 URL 추적 useEffect(() => { - fetch(`/api/albums/by-name/${name}`) - .then(res => res.json()) + getAlbumByName(name) .then(data => { setAlbum(data); const allPhotos = []; diff --git a/frontend/src/pages/pc/public/Members.jsx b/frontend/src/pages/pc/public/Members.jsx index f3c3627..80bb09c 100644 --- a/frontend/src/pages/pc/public/Members.jsx +++ b/frontend/src/pages/pc/public/Members.jsx @@ -1,14 +1,14 @@ import { useState, useEffect } from 'react'; import { motion } from 'framer-motion'; import { Instagram, Calendar } from 'lucide-react'; +import { getMembers } from '../../../api/public/members'; function Members() { const [members, setMembers] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { - fetch('/api/members') - .then(res => res.json()) + getMembers() .then(data => { setMembers(data); setLoading(false);