'use client'; import { useEffect, useState } from 'react'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; interface Quote { id: string; title: string; client_name: string; client_email: string; status: 'draft' | 'sent' | 'accepted' | 'rejected'; valid_until: string | null; public_token: string; items: { unitPrice: number; quantity: number; optional: boolean }[]; created_at: string; } const STATUS = { draft: { label: '초안', color: 'bg-slate-700 text-slate-300' }, sent: { label: '발송됨', color: 'bg-blue-900/50 text-blue-400' }, accepted: { label: '수락됨', color: 'bg-green-900/50 text-green-400' }, rejected: { label: '거절됨', color: 'bg-red-900/50 text-red-400' }, }; function calcTotal(items: Quote['items']) { return items.reduce((sum, i) => sum + i.unitPrice * i.quantity, 0); } export default function AdminQuotesPage() { const router = useRouter(); const [quotes, setQuotes] = useState([]); const [loading, setLoading] = useState(true); const [creating, setCreating] = useState(false); const [deleting, setDeleting] = useState(null); const [copied, setCopied] = useState(null); useEffect(() => { fetch('/api/admin/quotes') .then((r) => r.json()) .then((d) => setQuotes(d.quotes ?? [])) .finally(() => setLoading(false)); }, []); async function handleCreate() { setCreating(true); const res = await fetch('/api/admin/quotes', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title: '새 견적서' }), }); const d = await res.json(); if (d.quote?.id) router.push(`/admin/quotes/${d.quote.id}`); else setCreating(false); } async function handleDelete(id: string) { if (!confirm('이 견적서를 삭제할까요?')) return; setDeleting(id); await fetch(`/api/admin/quotes/${id}`, { method: 'DELETE' }); setQuotes((prev) => prev.filter((q) => q.id !== id)); setDeleting(null); } function copyLink(token: string, id: string) { const url = `${window.location.origin}/quote/${token}`; navigator.clipboard.writeText(url); setCopied(id); setTimeout(() => setCopied(null), 2000); } return (
{/* 헤더 */}

견적서 관리

고객에게 제시할 견적서를 작성하고 관리합니다

{/* 목록 */} {loading ? (
불러오는 중...
) : quotes.length === 0 ? (
📄

아직 견적서가 없습니다

위 버튼을 눌러 첫 번째 견적서를 작성해보세요

) : ( <> {/* PC 테이블 뷰 */}
{quotes.map((q) => { const st = STATUS[q.status] ?? STATUS.draft; const total = calcTotal(q.items ?? []); return ( ); })}
견적서명 고객 합계 상태 유효기간 작성일
{q.title}
{q.client_name || '—'}
{q.client_email || ''}
{total > 0 ? `${total.toLocaleString()}원` : '—'} {st.label} {q.valid_until ? q.valid_until.slice(0, 10) : '—'} {new Date(q.created_at).toLocaleDateString('ko-KR')}
{/* 모바일 카드 뷰 */}
{quotes.map((q) => { const st = STATUS[q.status] ?? STATUS.draft; const total = calcTotal(q.items ?? []); return (
{/* 제목 + 상태 */}
{q.title} {st.label}
{/* 고객 정보 */} {(q.client_name || q.client_email) && (
{q.client_name &&

{q.client_name}

} {q.client_email &&

{q.client_email}

}
)} {/* 상세 정보 */}

합계

{total > 0 ? `${total.toLocaleString()}원` : '—'}

유효기간

{q.valid_until ? q.valid_until.slice(0, 10) : '—'}

작성일

{new Date(q.created_at).toLocaleDateString('ko-KR')}

{/* 액션 버튼 */}
편집
); })}
)}
); }