'use client'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; interface Contact { id: string; email: string; name: string | null; service: string; message: string; status: 'pending' | 'in_progress' | 'completed'; created_at: string; } const STATUS_LABELS: Record = { pending: { label: '미처리', color: 'bg-yellow-900/40 text-yellow-400' }, in_progress: { label: '처리중', color: 'bg-blue-900/40 text-blue-400' }, completed: { label: '완료', color: 'bg-green-900/40 text-green-400' }, }; const SERVICE_LABELS: Record = { lotto: '로또 추천', stock: '주식 자동매매', automation: '업무 자동화', prompt: '프롬프트 엔지니어링', freelance: '외주 개발', saju: 'AI 사주', general: '일반 문의', }; export default function AdminContactsPage() { const router = useRouter(); const [contacts, setContacts] = useState([]); const [loading, setLoading] = useState(true); const [selected, setSelected] = useState(null); const [updating, setUpdating] = useState(null); const [filterStatus, setFilterStatus] = useState('all'); const [creatingQuote, setCreatingQuote] = useState(false); async function createQuote(contact: Contact) { setCreatingQuote(true); try { const title = `${SERVICE_LABELS[contact.service] ?? contact.service ?? '외주 문의'} — ${contact.name ?? ''}`.trim(); const res = await fetch('/api/admin/quotes', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title, contact_request_id: contact.id, client_name: contact.name ?? '', client_email: contact.email, }), }); const d = await res.json(); if (res.ok && d.quote?.id) { router.push('/admin/quotes/' + d.quote.id); } else { alert(d.error || '견적서 생성에 실패했습니다'); } } catch (e) { console.error(e); alert('견적서 생성 중 오류가 발생했습니다'); } finally { setCreatingQuote(false); } } useEffect(() => { fetch('/api/admin/contacts') .then((r) => r.json()) .then((d) => setContacts(d.contacts ?? [])) .catch(console.error) .finally(() => setLoading(false)); }, []); async function updateStatus(id: string, status: string) { setUpdating(id); try { const res = await fetch('/api/admin/contacts', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, status }), }); if (res.ok) { setContacts((prev) => prev.map((c) => (c.id === id ? { ...c, status: status as Contact['status'] } : c)) ); if (selected?.id === id) { setSelected((prev) => prev ? { ...prev, status: status as Contact['status'] } : null); } } } catch (e) { console.error(e); } finally { setUpdating(null); } } const filtered = contacts.filter((c) => filterStatus === 'all' || c.status === filterStatus); const pendingCount = contacts.filter((c) => c.status === 'pending').length; return (

문의 내역

고객 문의 및 외주 의뢰 관리

{pendingCount > 0 && ( 미처리 {pendingCount}건 )}
{/* 필터 탭 */}
{[['all', '전체'], ['pending', '미처리'], ['in_progress', '처리중'], ['completed', '완료']].map(([val, label]) => ( ))}
{loading ? (
) : (
{/* 목록 */}
{filtered.length === 0 ? (
문의 내역이 없습니다
) : ( filtered.map((contact) => ( )) )}
{/* 상세 패널 */} {selected && (

문의 상세

이름
{selected.name ?? '-'}
이메일
{selected.email}
서비스
{SERVICE_LABELS[selected.service] ?? selected.service}
접수일
{new Date(selected.created_at).toLocaleString('ko-KR')}
내용
{selected.message}
{/* 상태 변경 */}

상태 변경

{(['pending', 'in_progress', 'completed'] as const).map((s) => ( ))}
{/* 이메일 바로 보내기 링크 */} 이메일 답장하기 {/* 견적서 작성 */}
)}
)}
); }