"use client"; import React, { useState, useEffect } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Send, Mail, Eye, Plus, X, Loader2, CheckCircle } from "lucide-react"; import { MailAccount, MailTemplate, getMailAccounts, getMailTemplates, sendMail, extractTemplateVariables, renderTemplateToHtml, } from "@/lib/api/mail"; export default function MailSendPage() { const [accounts, setAccounts] = useState([]); const [templates, setTemplates] = useState([]); const [loading, setLoading] = useState(false); // 폼 상태 const [selectedAccountId, setSelectedAccountId] = useState(""); const [selectedTemplateId, setSelectedTemplateId] = useState(""); const [subject, setSubject] = useState(""); const [recipients, setRecipients] = useState([""]); const [variables, setVariables] = useState>({}); // UI 상태 const [isSending, setIsSending] = useState(false); const [showPreview, setShowPreview] = useState(false); const [sendResult, setSendResult] = useState<{ success: boolean; message: string; } | null>(null); useEffect(() => { loadData(); }, []); const loadData = async () => { setLoading(true); try { const [accountsData, templatesData] = await Promise.all([ getMailAccounts(), getMailTemplates(), ]); setAccounts(Array.isArray(accountsData) ? accountsData : []); setTemplates(Array.isArray(templatesData) ? templatesData : []); // 기본값 설정 if (accountsData.length > 0 && !selectedAccountId) { setSelectedAccountId(accountsData[0].id); } } catch (error) { console.error('데이터 로드 실패:', error); } finally { setLoading(false); } }; const selectedTemplate = templates.find((t) => t.id === selectedTemplateId); const templateVariables = selectedTemplate ? extractTemplateVariables(selectedTemplate) : []; // 템플릿 선택 시 제목 자동 입력 및 변수 초기화 useEffect(() => { if (selectedTemplate) { setSubject(selectedTemplate.subject); const initialVars: Record = {}; templateVariables.forEach((varName) => { initialVars[varName] = ""; }); setVariables(initialVars); } }, [selectedTemplateId]); const addRecipient = () => { setRecipients([...recipients, ""]); }; const removeRecipient = (index: number) => { setRecipients(recipients.filter((_, i) => i !== index)); }; const updateRecipient = (index: number, value: string) => { const newRecipients = [...recipients]; newRecipients[index] = value; setRecipients(newRecipients); }; const handleSend = async () => { // 유효성 검증 const validRecipients = recipients.filter((email) => email.trim() !== ""); if (validRecipients.length === 0) { alert("수신자 이메일을 입력하세요."); return; } if (!selectedAccountId) { alert("발송 계정을 선택하세요."); return; } if (!subject.trim()) { alert("메일 제목을 입력하세요."); return; } if (!selectedTemplateId) { alert("템플릿을 선택하세요."); return; } setIsSending(true); setSendResult(null); try { const result = await sendMail({ accountId: selectedAccountId, templateId: selectedTemplateId, to: validRecipients, subject, variables, }); setSendResult({ success: true, message: `${result.accepted?.length || 0}개 발송 성공`, }); // 성공 후 초기화 setRecipients([""]); setVariables({}); } catch (error) { setSendResult({ success: false, message: error instanceof Error ? error.message : "발송 실패", }); } finally { setIsSending(false); } }; const previewHtml = selectedTemplate ? renderTemplateToHtml(selectedTemplate, variables) : ""; if (loading) { return (
); } return (
{/* 페이지 제목 */}

메일 발송

템플릿을 선택하여 메일을 발송합니다

{/* 메인 폼 */}
{/* 왼쪽: 발송 설정 */}
발송 설정 {/* 발송 계정 선택 */}
{/* 템플릿 선택 */}
{/* 메일 제목 */}
setSubject(e.target.value)} placeholder="예: 환영합니다!" className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500" />
{/* 수신자 */}
{recipients.map((email, index) => (
updateRecipient(index, e.target.value)} placeholder="example@email.com" className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500" /> {recipients.length > 1 && ( )}
))}
{/* 템플릿 변수 */} {templateVariables.length > 0 && (
{templateVariables.map((varName) => (
setVariables({ ...variables, [varName]: e.target.value }) } placeholder={`{${varName}}`} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-orange-500" />
))}
)}
{/* 발송 버튼 */}
{/* 발송 결과 */} {sendResult && (
{sendResult.success ? ( ) : ( )}

{sendResult.message}

)}
{/* 오른쪽: 미리보기 */}
미리보기 {showPreview && previewHtml ? (
제목: {subject}
) : (

템플릿을 선택하고
미리보기 버튼을 클릭하세요

)}
); }