'use client'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import Link from 'next/link'; import { createClient } from '@/lib/supabase/client'; import type { User } from '@supabase/supabase-js'; import TelegramGuideModal from '@/app/components/TelegramGuideModal'; function buildSajuResultUrl(rec: SajuRecord) { const { birth_year, birth_month, birth_day, birth_hour, gender } = rec.saju_data; if (!birth_year || !birth_month || !birth_day) return '/saju/input'; let url = `/saju/result?year=${birth_year}&month=${birth_month}&day=${birth_day}&gender=${gender}&calendarType=solar`; if (birth_hour != null) url += `&hour=${birth_hour}`; return url; } type Tab = 'profile' | 'saju' | 'payments' | 'orders'; type TelegramLinkState = 'idle' | 'generating' | 'waiting' | 'disconnecting'; interface SajuRecord { id: number; created_at: string; saju_data: { birth_year: number; birth_month: number; birth_day: number; birth_hour?: number; gender: string; }; interpretation: string | null; is_paid: boolean; } interface Payment { id: string; created_at: string; amount: number; status: string; product_name: string; } interface Order { id: string; created_at: string; service: string; message: string; status: string; } export default function MyPage() { const router = useRouter(); const supabase = createClient(); const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [tab, setTab] = useState('profile'); const [sajuRecords, setSajuRecords] = useState([]); const [payments, setPayments] = useState([]); const [orders, setOrders] = useState([]); // 텔레그램 연동 상태 const [telegramChatId, setTelegramChatId] = useState(null); const [telegramLinkState, setTelegramLinkState] = useState('idle'); const [telegramDeepLink, setTelegramDeepLink] = useState(''); const [telegramLinkExpiry, setTelegramLinkExpiry] = useState(''); const [showTelegramGuide, setShowTelegramGuide] = useState(false); useEffect(() => { async function init() { const { data: { user } } = await supabase.auth.getUser(); if (!user) { router.push('/login'); return; } setUser(user); // 사주 기록 조회 (테이블 있을 때 동작) const { data: saju } = await supabase .from('saju_records') .select('*') .eq('user_id', user.id) .order('created_at', { ascending: false }) .limit(20); setSajuRecords(saju || []); // 결제 내역 조회 const { data: pay } = await supabase .from('payments') .select('*') .eq('user_id', user.id) .order('created_at', { ascending: false }) .limit(20); setPayments(pay || []); // 의뢰 내역 조회 const { data: ord } = await supabase .from('contact_requests') .select('*') .eq('user_id', user.id) .order('created_at', { ascending: false }) .limit(20); setOrders(ord || []); // 텔레그램 chat_id 조회 const { data: profile } = await supabase .from('profiles') .select('telegram_chat_id') .eq('id', user.id) .maybeSingle(); setTelegramChatId(profile?.telegram_chat_id ?? null); setLoading(false); } init(); }, []); const handleLogout = async () => { await supabase.auth.signOut(); router.push('/'); router.refresh(); }; // ── 텔레그램 연결 ── const handleTelegramConnect = async () => { setTelegramLinkState('generating'); try { const res = await fetch('/api/telegram/connect', { method: 'POST' }); if (!res.ok) throw new Error('API_ERROR'); const data = await res.json(); setTelegramDeepLink(data.deepLink); setTelegramLinkExpiry(new Date(data.expiresAt).toLocaleTimeString('ko-KR', { hour: '2-digit', minute: '2-digit' })); setTelegramLinkState('waiting'); // 15분 후 자동으로 idle 복귀 setTimeout(() => setTelegramLinkState('idle'), 15 * 60 * 1000); } catch { setTelegramLinkState('idle'); alert('연결 코드 발급 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요.'); } }; // 연결 후 상태 새로고침 (버튼 클릭 시) const handleTelegramRefresh = async () => { const { data: profile } = await supabase .from('profiles') .select('telegram_chat_id') .eq('id', user!.id) .maybeSingle(); const chatId = profile?.telegram_chat_id ?? null; setTelegramChatId(chatId); if (chatId) setTelegramLinkState('idle'); }; // ── 텔레그램 연결 해제 ── const handleTelegramDisconnect = async () => { if (!confirm('텔레그램 연결을 해제하시겠습니까?')) return; setTelegramLinkState('disconnecting'); try { await fetch('/api/telegram/connect', { method: 'DELETE' }); setTelegramChatId(null); setTelegramDeepLink(''); } catch { alert('연결 해제 중 오류가 발생했습니다.'); } setTelegramLinkState('idle'); }; if (loading) { return (
); } if (!user) return null; const tabs: { key: Tab; label: string; count?: number }[] = [ { key: 'profile', label: '내 정보' }, { key: 'saju', label: '사주 기록', count: sajuRecords.length }, { key: 'payments', label: '결제 내역', count: payments.length }, { key: 'orders', label: '의뢰 내역', count: orders.length }, ]; return (
{/* 텔레그램 가이드 모달 */} {showTelegramGuide && ( setShowTelegramGuide(false)} /> )} {/* 헤더 */}
{user.email?.[0].toUpperCase()}
{user.email}
가입일: {new Date(user.created_at).toLocaleDateString('ko-KR')}
{/* 탭 */}
{tabs.map((t) => ( ))}
{/* 탭 콘텐츠 */} {/* 내 정보 */} {tab === 'profile' && (

계정 정보

이메일 {user.email}
로그인 방법 {user.app_metadata?.provider === 'google' ? 'Google' : '이메일'}
가입일 {new Date(user.created_at).toLocaleDateString('ko-KR', { year: 'numeric', month: 'long', day: 'numeric' })}
{/* 텔레그램 연동 카드 */}

텔레그램 알림 연동 플래티넘 · 다이아 전용

{telegramChatId ? ( /* ── 연결됨 ── */
연결됨
Chat ID: {telegramChatId}
) : telegramLinkState === 'waiting' ? ( /* ── 연결 대기 중 ── */

📱 아래 순서로 진행하세요

  1. 아래 버튼을 클릭해 텔레그램 봇을 엽니다
  2. 텔레그램에서 시작 버튼을 누릅니다
  3. 봇이 "연결 완료" 메시지를 보내면 새로고침을 눌러주세요

⏱ 유효시간: {telegramLinkExpiry}까지

텔레그램 봇 열기
) : ( /* ── 미연결 ── */
연결 안 됨
텔레그램으로 번호를 바로 받아보세요
)}

빠른 메뉴

사주 분석
새 사주 보기
로또 번호 추천
구독자 전용
외주 의뢰
프로젝트 문의
)} {/* 사주 기록 */} {tab === 'saju' && (
{sajuRecords.length === 0 ? ( ) : (
{sajuRecords.map((rec) => (
{new Date(rec.created_at).toLocaleDateString('ko-KR')}
{rec.saju_data?.birth_year ?? '?'}년{' '} {rec.saju_data?.birth_month ?? '?'}월{' '} {rec.saju_data?.birth_day ?? '?'}일생
{rec.saju_data?.gender === 'male' ? '남성' : '여성'} {rec.saju_data?.birth_hour != null ? ` · ${rec.saju_data.birth_hour}시생` : ''}
{rec.is_paid ? '유료' : '무료'}
{rec.interpretation && (

{rec.interpretation.replace(/[#*]/g, '').substring(0, 80)}...

)} {rec.is_paid && rec.interpretation ? 'AI 해석 다시 보기 →' : '결과 보기 →'}
))}
)}
)} {/* 결제 내역 */} {tab === 'payments' && (
{payments.length === 0 ? ( ) : (
{payments.map((p, i) => ( ))}
서비스 금액 상태 일시
{p.product_name} ₩{p.amount?.toLocaleString()} {p.status === 'paid' ? '결제완료' : p.status} {new Date(p.created_at).toLocaleDateString('ko-KR')}
)}
)} {/* 의뢰 내역 */} {tab === 'orders' && (
{orders.length === 0 ? ( ) : (
{orders.map((o) => (
{o.service}
{o.status === 'completed' ? '완료' : o.status === 'in_progress' ? '진행중' : '대기중'}

{o.message}

{new Date(o.created_at).toLocaleDateString('ko-KR')}
))}
)}
)}
); } function EmptyState({ icon, title, desc, linkHref, linkLabel, }: { icon: string; title: string; desc: string; linkHref: string; linkLabel: string; }) { return (
{icon}
{title}
{desc}
{linkLabel} →
); }