import React, { useState, useEffect, useMemo, useRef } from 'react'; import { Heart, X, MessageCircle, ChevronLeft, Trash2, Zap, Flame, Info } from 'lucide-react'; // --- DATA: 20 Conversation Topics --- const TOPICS_DATA = [ { id: 1, title: "연애에서 연락 빈도 중요한가?", prompts: ["연락 자주 vs 적당히 뭐가 좋아?", "하루 연락 안 되면 불안함?", "연락 스타일 때문에 싸운 적 있어?"], related: ["연애 초반 vs 후반 차이", "집착 vs 관심의 기준", "연락 끊기는 순간"] }, { id: 2, title: "깻잎 논쟁, 어떻게 생각해?", prompts: ["내 친구 깻잎 떼줘도 돼?", "반대로 내 깻잎을 친구가?", "질투의 기준은 어디까지?"], related: ["새우 까주기 논쟁", "패딩 지퍼 논쟁", "남녀 사이 친구 가능?"] }, { id: 3, title: "첫인상 vs 오래 본 성격", prompts: ["첫눈에 반한 적 있어?", "성격 보고 좋아진 케이스?", "첫인상이 바뀐 경험은?"], related: ["외모 관리의 중요성", "금사빠의 특징", "이상형의 조건"] }, { id: 4, title: "결혼 전 동거, 필수일까?", prompts: ["장단점이 뭐라고 생각해?", "가족이 반대한다면?", "생활 패턴 맞추는 팁?"], related: ["결혼의 현실", "가사 분담 기준", "경제권 관리"] }, { id: 5, title: "전 애인과 친구 가능?", prompts: ["헤어지고 연락해본 적?", "친구로 지내는 사람 이해돼?", "환승 이별에 대한 생각은?"], related: ["이별 극복 방법", "미련의 정의", "새 연인에게 예의"] }, { id: 6, title: "나의 인생 영화 TOP 3", prompts: ["가장 많이 본 영화는?", "영화관 vs 넷플릭스?", "인생 캐릭터가 있다면?"], related: ["장르 취향", "영화관 간식", "반전 영화 추천"] }, { id: 7, title: "MBTI, 맹신하는 편이야?", prompts: ["본인 MBTI 만족해?", "안 맞는 유형이 있어?", "과몰입러에 대한 생각은?"], related: ["성격 테스트", "T와 F의 대화법", "E와 I의 에너지"] }, { id: 8, title: "로또 1등 되면 뭐 할 거야?", prompts: ["주변에 말할 거야?", "가장 먼저 사고 싶은 건?", "회사는 바로 그만둘까?"], related: ["경제적 자유", "돈과 행복의 관계", "버킷 리스트"] }, { id: 9, title: "가장 가고 싶은 여행지는?", prompts: ["휴양 vs 관광?", "혼자 여행 vs 같이?", "여행지 최악의 파트너는?"], related: ["비행기 꿀팁", "현지 맛집 찾기", "여행 사진 찍기"] }, { id: 10, title: "SNS는 인생의 낭비일까?", prompts: ["하루 사용 시간은?", "보여주기식 삶에 대해?", "디지털 디톡스 해봤어?"], related: ["알고리즘의 무서움", "인플루언서", "스마트폰 중독"] }, { id: 11, title: "커리어 vs 워라밸", prompts: ["연봉 1억 야근 vs 3천 칼퇴?", "성공의 기준이 뭐야?", "번아웃 온 적 있어?"], related: ["직장 동료 관계", "자기계발", "퇴사 고민"] }, { id: 12, title: "나만의 스트레스 해소법", prompts: ["매운 음식 vs 잠?", "운동이 도움이 돼?", "누구에게 털어놓는 편?"], related: ["멘탈 관리", "취미 생활", "명상의 효과"] }, { id: 13, title: "부먹 vs 찍먹", prompts: ["탕수육 소스 취향은?", "민초는 호? 불호?", "라면 물 조절 부심 있어?"], related: ["음식 취향", "맛집 웨이팅", "요리 실력"] }, { id: 14, title: "가장 후회되는 순간", prompts: ["과거로 돌아간다면?", "실수를 대하는 자세?", "그때로 가면 바꿀 거야?"], related: ["인생의 교훈", "선택과 집중", "성장의 기록"] }, { id: 15, title: "동물로 태어난다면?", prompts: ["강아지 vs 고양이?", "자유로운 새가 좋아?", "집에서 키우고 싶은 동물?"], related: ["반려동물", "자연의 신비", "동물 소통"] }, { id: 16, title: "연애 중 거짓말의 허용치", prompts: ["하얀 거짓말 괜찮아?", "들켰을 때 반응은?", "비밀번호 공유해야 해?"], related: ["신뢰의 중요성", "질투와 구속", "솔직함의 미덕"] }, { id: 17, title: "나의 10년 뒤 모습은?", prompts: ["어디서 살고 있을까?", "어떤 일을 하고 있을까?", "지금의 나에게 한마디?"], related: ["노후 준비", "꿈과 현실", "미래 기술"] }, { id: 18, title: "초능력 하나만 갖는다면?", prompts: ["순간이동 vs 시간여행?", "투명인간 되면 뭐 해?", "독심술은 축복일까?"], related: ["히어로 영화", "상상력", "불사의 삶"] }, { id: 19, title: "무인도에 가져갈 세 가지", prompts: ["물건 vs 사람?", "살아남을 자신 있어?", "가장 먼저 할 일은?"], related: ["생존 본능", "고립된 상황", "필수템"] }, { id: 20, title: "가장 좋아하는 계절", prompts: ["여름 바다 vs 겨울 산?", "봄 타는 편이야?", "눈 오는 날 설레?"], related: ["날씨와 기분", "계절 음식", "옷차림"] } ]; export default function App() { const [currentPage, setCurrentPage] = useState('home'); const [currentIndex, setCurrentIndex] = useState(0); const [likedTopics, setLikedTopics] = useState([]); const [selectedTopic, setSelectedTopic] = useState(null); const [swipeState, setSwipeState] = useState({ x: 0, opacity: 1, rotation: 0 }); const [isDragging, setIsDragging] = useState(false); const startPos = useRef({ x: 0, y: 0 }); useEffect(() => { const saved = localStorage.getItem('slide_liked_topics'); if (saved) setLikedTopics(JSON.parse(saved)); }, []); const saveToLocal = (newLiked) => { localStorage.setItem('slide_liked_topics', JSON.stringify(newLiked)); }; const handleSwipe = (direction) => { if (currentIndex >= TOPICS_DATA.length) return; if (direction === 'right') { const topic = TOPICS_DATA[currentIndex]; if (!likedTopics.find(t => t.id === topic.id)) { const newLiked = [...likedTopics, topic]; setLikedTopics(newLiked); saveToLocal(newLiked); } } setSwipeState({ x: direction === 'right' ? 600 : -600, opacity: 0, rotation: direction === 'right' ? 30 : -30 }); setTimeout(() => { setCurrentIndex(prev => prev + 1); setSwipeState({ x: 0, opacity: 1, rotation: 0 }); }, 300); }; const onStart = (clientX) => { setIsDragging(true); startPos.current = { x: clientX }; }; const onMove = (clientX) => { if (!isDragging) return; const deltaX = clientX - startPos.current.x; const rotation = deltaX / 20; setSwipeState({ x: deltaX, opacity: 1, rotation }); }; const onEnd = () => { if (!isDragging) return; setIsDragging(false); if (Math.abs(swipeState.x) > 120) { handleSwipe(swipeState.x > 0 ? 'right' : 'left'); } else { setSwipeState({ x: 0, opacity: 1, rotation: 0 }); } }; const handleTouchStart = (e) => onStart(e.touches[0].clientX); const handleTouchMove = (e) => onMove(e.touches[0].clientX); const handleTouchEnd = () => onEnd(); const handleMouseDown = (e) => onStart(e.clientX); const handleMouseMove = (e) => onMove(e.clientX); const handleMouseUp = () => onEnd(); const handleMouseLeave = () => { if (isDragging) onEnd(); }; // 상세 페이지 열기 const openDetail = (topic) => { setSelectedTopic(topic); // currentPage는 변경하지 않고 selectedTopic의 존재 유무로 모달/전체화면 오버레이 처리 }; // 상세 페이지 닫기 (이 부분이 핵심 수정 사항입니다) const closeDetail = () => { setSelectedTopic(null); }; const removeLiked = (id, e) => { e.stopPropagation(); const updated = likedTopics.filter(t => t.id !== id); setLikedTopics(updated); saveToLocal(updated); }; const renderHome = () => { const activeTopic = TOPICS_DATA[currentIndex]; const nextTopic = TOPICS_DATA[currentIndex + 1]; if (currentIndex >= TOPICS_DATA.length) { return (

새로운 주제를 준비 중입니다

지금까지 모든 주제를 확인하셨어요!

); } return (
{nextTopic && (
Next...
)}
50 ? '#22c55e' : swipeState.x < -50 ? '#ef4444' : '#27272a' }} onTouchStart={handleTouchStart} onTouchMove={handleTouchMove} onTouchEnd={handleTouchEnd} onMouseDown={handleMouseDown} onMouseMove={handleMouseMove} onMouseUp={handleMouseUp} onMouseLeave={handleMouseLeave} > {swipeState.x > 50 && (
LIKE
)} {swipeState.x < -50 && (
SKIP
)}

{activeTopic.title}

Swipe or Drag to decide

); }; const renderLiked = () => { return (

Liked Topics

저장된 대화 주제들

{likedTopics.length === 0 ? (

아직 좋아요한 주제가 없어요!

) : (
{likedTopics.map((topic) => (
openDetail(topic)} className="bg-zinc-900 p-5 rounded-2xl border border-zinc-800 flex items-center justify-between group active:bg-zinc-800 transition-colors cursor-pointer" >

{topic.title}

{topic.prompts.length} prompts

))}
)}
); }; const renderDetail = () => { if (!selectedTopic) return null; return (
{/* Back 버튼 터치 영역 확장 및 명확한 액션 부여 */}

{selectedTopic.title}

Conversation Starters

{selectedTopic.prompts.map((p, i) => (
0{i+1}

{p}

))}

Related Topics

{selectedTopic.related.map((r, i) => ( #{r} ))}
); }; return (
SLIDE
{likedTopics.length}
{currentPage === 'home' && renderHome()} {currentPage === 'liked' && renderLiked()} {/* 상세 페이지는 메인 레이아웃 위에 덮어씌움 */} {renderDetail()}