diff --git a/frontend/src/pages/mobile/album/AlbumDetail.jsx b/frontend/src/pages/mobile/album/AlbumDetail.jsx index ca5ef95..78014e4 100644 --- a/frontend/src/pages/mobile/album/AlbumDetail.jsx +++ b/frontend/src/pages/mobile/album/AlbumDetail.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect, useCallback, useRef } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { useQuery } from '@tanstack/react-query'; import { motion, AnimatePresence } from 'framer-motion'; @@ -26,6 +26,7 @@ function MobileAlbumDetail() { const [lightbox, setLightbox] = useState({ open: false, images: [], index: 0, teasers: null, photos: null }); const [showAllTracks, setShowAllTracks] = useState(false); const [showDescriptionModal, setShowDescriptionModal] = useState(false); + const descriptionHistoryRef = useRef(false); // 앨범 데이터 로드 const { data: album, isLoading: loading } = useQuery({ @@ -50,12 +51,23 @@ function MobileAlbumDetail() { const openDescriptionModal = useCallback(() => { setShowDescriptionModal(true); window.history.pushState({ description: true }, ''); + descriptionHistoryRef.current = true; + }, []); + + // 앨범 소개 닫기 + const closeDescriptionModal = useCallback(() => { + setShowDescriptionModal(false); + if (descriptionHistoryRef.current) { + descriptionHistoryRef.current = false; + window.history.back(); + } }, []); // 뒤로가기 처리 (앨범 소개만 - 라이트박스는 MobileLightbox에서 처리) useEffect(() => { const handlePopState = () => { if (showDescriptionModal) { + descriptionHistoryRef.current = false; setShowDescriptionModal(false); } }; @@ -184,7 +196,12 @@ function MobileAlbumDetail() { {/* 티저 이미지 */} {album.teasers && album.teasers.length > 0 && ( - +

티저 이미지

{album.teasers.map((teaser, index) => ( @@ -222,6 +239,7 @@ function MobileAlbumDetail() {

수록곡

@@ -269,7 +287,7 @@ function MobileAlbumDetail() {

컨셉 포토

@@ -314,38 +332,26 @@ function MobileAlbumDetail() { initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} - className="fixed inset-0 bg-black/60 z-[60] flex items-end justify-center" - onClick={() => window.history.back()} + className="fixed inset-0 bg-black/60 z-[60] flex items-center justify-center p-6" + onClick={closeDescriptionModal} > { - if (info.offset.y > 100 || info.velocity.y > 300) { - window.history.back(); - } - }} - className="bg-white rounded-t-3xl w-full max-h-[80vh] overflow-hidden" + className="bg-white rounded-2xl w-full max-h-[70vh] overflow-hidden" onClick={(e) => e.stopPropagation()} > - {/* 드래그 핸들 */} -
-
-
{/* 헤더 */} -
+

앨범 소개

-
{/* 내용 */} -
+

{album.description}

diff --git a/frontend/src/pages/mobile/album/AlbumGallery.jsx b/frontend/src/pages/mobile/album/AlbumGallery.jsx index 1259413..2ca116e 100644 --- a/frontend/src/pages/mobile/album/AlbumGallery.jsx +++ b/frontend/src/pages/mobile/album/AlbumGallery.jsx @@ -1,7 +1,6 @@ import { useState, useCallback, useMemo } from 'react'; -import { useParams, useNavigate } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; import { useQuery } from '@tanstack/react-query'; -import { ChevronRight } from 'lucide-react'; import { motion } from 'framer-motion'; import { getAlbumByName } from '@/api'; import { MobileLightbox } from '@/components/common'; @@ -11,7 +10,6 @@ import { MobileLightbox } from '@/components/common'; */ function MobileAlbumGallery() { const { name } = useParams(); - const navigate = useNavigate(); const [selectedIndex, setSelectedIndex] = useState(null); // 앨범 데이터 로드 @@ -78,10 +76,7 @@ function MobileAlbumGallery() { <>
{/* 앨범 헤더 카드 */} -
navigate(-1)} - > +
{album?.cover_thumb_url && ( {album?.title}

{photos.length}장의 사진

-
{/* 2열 그리드 */} diff --git a/frontend/src/pages/mobile/members/Members.jsx b/frontend/src/pages/mobile/members/Members.jsx index 5ef254f..32a45cf 100644 --- a/frontend/src/pages/mobile/members/Members.jsx +++ b/frontend/src/pages/mobile/members/Members.jsx @@ -1,6 +1,6 @@ import { motion, AnimatePresence } from 'framer-motion'; import { useState, useMemo, useRef, useEffect } from 'react'; -import { Instagram, Calendar } from 'lucide-react'; +import { Calendar, X, Instagram } from 'lucide-react'; import { useMembers } from '@/hooks'; /** @@ -39,7 +39,6 @@ const MemberCard = ({ member, index, onClick, shouldAnimate }) => ( */ function MobileMembers() { const [selectedMember, setSelectedMember] = useState(null); - const [isDragging, setIsDragging] = useState(false); const hasAnimated = useRef(false); // 멤버 데이터 로드 @@ -81,13 +80,6 @@ function MobileMembers() { return age; }; - // 드래그 종료 시 닫기 판단 - const handleDragEnd = (_, info) => { - if (info.offset.y > 100 || info.velocity.y > 500) { - setSelectedMember(null); - } - }; - if (allMembers.length === 0) { return (
@@ -101,7 +93,7 @@ function MobileMembers() { return (
{/* 현재 멤버 */} -
+
{currentMembers.map((member, index) => ( 전 멤버
-
+
{formerMembers.map((member, index) => ( setSelectedMember(null)} > setIsDragging(true)} - onDragEnd={(e, info) => { - setIsDragging(false); - handleDragEnd(e, info); - }} - className="relative w-full bg-white rounded-t-3xl touch-none pb-10" + initial={{ opacity: 0, scale: 0.95 }} + animate={{ opacity: 1, scale: 1 }} + exit={{ opacity: 0, scale: 0.95 }} + transition={{ type: 'spring', damping: 25, stiffness: 300 }} + className="w-64 bg-white rounded-2xl overflow-hidden" onClick={(e) => e.stopPropagation()} > - {/* 드래그 핸들 */} -
-
+ {/* 이미지 */} +
+ {selectedMember.image_thumb || selectedMember.image_url ? ( + {selectedMember.name} + ) : ( +
+ {selectedMember.name[0]} +
+ )} + {/* 닫기 버튼 */} +
-
-
- {/* 이미지 */} -
- {selectedMember.image_thumb || selectedMember.image_url ? ( - {selectedMember.name} - ) : ( -
- {selectedMember.name[0]} -
+ {/* 정보 영역 */} +
+

{selectedMember.name}

+ {selectedMember.birth_date && ( +
+ + + {selectedMember.birth_date?.slice(0, 10).replaceAll('-', '.')} + + {calculateAge(selectedMember.birth_date) && ( + + ({calculateAge(selectedMember.birth_date)}세) + )}
- - {/* 정보 영역 */} -
-
-

{selectedMember.name}

- {selectedMember.birth_date && ( -
- - - {selectedMember.birth_date?.slice(0, 10).replaceAll('-', '.')} - - {calculateAge(selectedMember.birth_date) && ( - - ({calculateAge(selectedMember.birth_date)}세) - - )} -
- )} -
- {!selectedMember.is_former && selectedMember.instagram && ( - isDragging && e.preventDefault()} - className="inline-flex items-center gap-1.5 self-start px-4 py-2 bg-gradient-to-r from-[#833AB4] via-[#E1306C] to-[#F77737] rounded-full" - > - - Instagram - - )} -
-
+ )} + {!selectedMember.is_former && selectedMember.instagram && ( + + + Instagram + + )}