import { useState, useCallback, useMemo } from 'react'; import { useParams } from 'react-router-dom'; import { useQuery } from '@tanstack/react-query'; import { motion } from 'framer-motion'; import { getAlbumByName } from '@/api'; import { MobileLightbox } from '@/components/common'; /** * Mobile 앨범 갤러리 페이지 */ function MobileAlbumGallery() { const { name } = useParams(); const [selectedIndex, setSelectedIndex] = useState(null); // 앨범 데이터 로드 const { data: album, isLoading: loading } = useQuery({ queryKey: ['album', name], queryFn: () => getAlbumByName(name), enabled: !!name, }); // 앨범 데이터에서 사진 목록 추출 const photos = useMemo(() => { if (!album?.conceptPhotos) return []; const allPhotos = []; Object.entries(album.conceptPhotos).forEach(([concept, conceptPhotos]) => { conceptPhotos.forEach((p) => allPhotos.push({ ...p, concept: concept !== 'Default' ? concept : null, }) ); }); return allPhotos; }, [album]); // 라이트박스 열기 const openLightbox = useCallback((index) => { setSelectedIndex(index); window.history.pushState({ lightbox: true }, ''); }, []); // 사진을 2열로 균등 분배 (높이 기반) const distributePhotos = () => { const leftColumn = []; const rightColumn = []; let leftHeight = 0; let rightHeight = 0; photos.forEach((photo, index) => { const aspectRatio = photo.height && photo.width ? photo.height / photo.width : 1; if (leftHeight <= rightHeight) { leftColumn.push({ ...photo, originalIndex: index }); leftHeight += aspectRatio; } else { rightColumn.push({ ...photo, originalIndex: index }); rightHeight += aspectRatio; } }); return { leftColumn, rightColumn }; }; const { leftColumn, rightColumn } = distributePhotos(); if (loading) { return (
); } return ( <>
{/* 앨범 헤더 카드 */}
{album?.cover_thumb_url && ( {album.title} )}

컨셉 포토

{album?.title}

{photos.length}장의 사진

{/* 2열 그리드 */}
{leftColumn.map((photo) => ( openLightbox(photo.originalIndex)} className="cursor-pointer overflow-hidden rounded-xl bg-gray-100" > ))}
{rightColumn.map((photo) => ( openLightbox(photo.originalIndex)} className="cursor-pointer overflow-hidden rounded-xl bg-gray-100" > ))}
{/* 라이트박스 */} p.medium_url || p.original_url)} photos={photos} currentIndex={selectedIndex ?? 0} isOpen={selectedIndex !== null} onClose={() => setSelectedIndex(null)} onIndexChange={setSelectedIndex} showCounter={photos.length > 1} downloadPrefix={`fromis9_${album?.title || 'photo'}`} /> ); } export default MobileAlbumGallery;