import { motion, AnimatePresence } from 'framer-motion'; import { useState, useMemo, useRef, useEffect } from 'react'; import { Instagram, Calendar } from 'lucide-react'; import { useMembers } from '@/hooks'; /** * 멤버 카드 컴포넌트 (외부 정의로 리렌더링 방지) */ const MemberCard = ({ member, index, onClick, shouldAnimate }) => ( {member.image_medium || member.image_url ? ( {member.name} ) : (
{member.name[0]}
)}

{member.name}

); /** * Mobile 멤버 페이지 - 그리드 레이아웃 */ function MobileMembers() { const [selectedMember, setSelectedMember] = useState(null); const [isDragging, setIsDragging] = useState(false); const hasAnimated = useRef(false); // 멤버 데이터 로드 const { data: allMembers = [] } = useMembers(); // 초기 애니메이션 완료 추적 useEffect(() => { if (allMembers.length > 0 && !hasAnimated.current) { const timer = setTimeout(() => { hasAnimated.current = true; }, allMembers.length * 50 + 300); return () => clearTimeout(timer); } }, [allMembers.length]); // 현재/전 멤버 분리 const currentMembers = useMemo( () => allMembers.filter((m) => !m.is_former), [allMembers] ); const formerMembers = useMemo( () => allMembers.filter((m) => m.is_former), [allMembers] ); // 나이 계산 const calculateAge = (birthDate) => { if (!birthDate) return null; const birth = new Date(birthDate); const today = new Date(); let age = today.getFullYear() - birth.getFullYear(); const monthDiff = today.getMonth() - birth.getMonth(); if ( monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate()) ) { age--; } return age; }; // 드래그 종료 시 닫기 판단 const handleDragEnd = (_, info) => { if (info.offset.y > 100 || info.velocity.y > 500) { setSelectedMember(null); } }; if (allMembers.length === 0) { return (

멤버 정보가 없습니다

); } const shouldAnimate = !hasAnimated.current; return (
{/* 현재 멤버 */}
{currentMembers.map((member, index) => ( setSelectedMember(member)} shouldAnimate={shouldAnimate} /> ))}
{/* 전 멤버 섹션 */} {formerMembers.length > 0 && ( <>
전 멤버
{formerMembers.map((member, index) => ( setSelectedMember(member)} shouldAnimate={shouldAnimate} /> ))}
)} {/* 선택된 멤버 모달 */} {selectedMember && ( 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" onClick={(e) => e.stopPropagation()} > {/* 드래그 핸들 */}
{/* 이미지 */}
{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.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 )}
)}
); } export default MobileMembers;