305 lines
11 KiB
TypeScript
305 lines
11 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { X, Mail, Send } from 'lucide-react';
|
|
import { comms } from '@/communication';
|
|
|
|
interface MailTestDialogProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
}
|
|
|
|
export function MailTestDialog({ isOpen, onClose }: MailTestDialogProps) {
|
|
const [formData, setFormData] = useState({
|
|
cate: '테스트',
|
|
subject: '',
|
|
fromlist: '',
|
|
tolist: '',
|
|
cc: '',
|
|
bcc: '',
|
|
body: '',
|
|
});
|
|
const [processing, setProcessing] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const loadUserEmail = async () => {
|
|
try {
|
|
const response = await comms.checkLoginStatus();
|
|
if (response.Success && response.IsLoggedIn && response.User) {
|
|
const user = response.User as { Email?: string };
|
|
if (user.Email) {
|
|
setFormData(prev => ({ ...prev, fromlist: user.Email || '' }));
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('사용자 정보 로드 오류:', error);
|
|
}
|
|
};
|
|
|
|
if (isOpen) {
|
|
loadUserEmail();
|
|
}
|
|
}, [isOpen]);
|
|
|
|
useEffect(() => {
|
|
const handleEscape = (e: KeyboardEvent) => {
|
|
if (e.key === 'Escape' && isOpen) {
|
|
onClose();
|
|
}
|
|
};
|
|
|
|
if (isOpen) {
|
|
window.addEventListener('keydown', handleEscape);
|
|
return () => window.removeEventListener('keydown', handleEscape);
|
|
}
|
|
}, [isOpen, onClose]);
|
|
|
|
const handleSubmit = async (mode: 'queue' | 'direct' | 'outlook' = 'queue') => {
|
|
if (!formData.subject.trim()) {
|
|
alert('제목을 입력해주세요.');
|
|
return;
|
|
}
|
|
if (!formData.tolist.trim()) {
|
|
alert('수신자를 입력해주세요.');
|
|
return;
|
|
}
|
|
if (!formData.body.trim()) {
|
|
alert('내용을 입력해주세요.');
|
|
return;
|
|
}
|
|
|
|
setProcessing(true);
|
|
try {
|
|
let response;
|
|
if (mode === 'outlook') {
|
|
// Outlook 미리보기
|
|
response = await comms.sendMailOutlook(
|
|
formData.subject,
|
|
formData.tolist,
|
|
formData.cc,
|
|
formData.bcc,
|
|
formData.body
|
|
);
|
|
} else if (mode === 'direct') {
|
|
// 직접 발송
|
|
response = await comms.sendMailDirect(
|
|
formData.cate,
|
|
formData.subject,
|
|
formData.fromlist,
|
|
formData.tolist,
|
|
formData.cc,
|
|
formData.bcc,
|
|
formData.body
|
|
);
|
|
} else {
|
|
// 발송 대기열에 추가
|
|
response = await comms.addMailData(
|
|
formData.cate,
|
|
formData.subject,
|
|
formData.fromlist,
|
|
formData.tolist,
|
|
formData.cc,
|
|
formData.bcc,
|
|
formData.body
|
|
);
|
|
}
|
|
|
|
if (response.Success) {
|
|
alert(response.Message || '처리되었습니다.');
|
|
if (mode !== 'outlook') {
|
|
onClose();
|
|
// 폼 초기화
|
|
setFormData({
|
|
cate: '테스트',
|
|
subject: '',
|
|
fromlist: formData.fromlist, // 발신자는 유지
|
|
tolist: '',
|
|
cc: '',
|
|
bcc: '',
|
|
body: '',
|
|
});
|
|
}
|
|
} else {
|
|
alert(response.Message || '메일 처리에 실패했습니다.');
|
|
}
|
|
} catch (error) {
|
|
console.error('메일 처리 오류:', error);
|
|
alert('메일 처리 중 오류가 발생했습니다.');
|
|
} finally {
|
|
setProcessing(false);
|
|
}
|
|
};
|
|
|
|
if (!isOpen) return null;
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-[10000] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm">
|
|
<div className="relative w-full max-w-3xl glass-effect-solid rounded-2xl shadow-2xl overflow-hidden">
|
|
{/* Header */}
|
|
<div className="flex items-center justify-between px-6 py-4 border-b border-white/10">
|
|
<div className="flex items-center gap-3">
|
|
<Mail className="w-5 h-5 text-primary-400" />
|
|
<h2 className="text-lg font-semibold text-white">메일 테스트</h2>
|
|
</div>
|
|
<button
|
|
onClick={onClose}
|
|
className="p-2 rounded-lg text-white/60 hover:text-white hover:bg-white/10 transition-colors"
|
|
>
|
|
<X className="w-5 h-5" />
|
|
</button>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<div className="p-6 space-y-4 max-h-[70vh] overflow-y-auto">
|
|
{/* 분류 */}
|
|
<div>
|
|
<label className="block text-white/80 text-sm font-medium mb-2">분류</label>
|
|
<input
|
|
type="text"
|
|
value={formData.cate}
|
|
onChange={(e) => setFormData({ ...formData, cate: e.target.value })}
|
|
className="w-full px-3 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-primary-400"
|
|
/>
|
|
</div>
|
|
|
|
{/* 제목 */}
|
|
<div>
|
|
<label className="block text-white/80 text-sm font-medium mb-2">제목 *</label>
|
|
<input
|
|
type="text"
|
|
value={formData.subject}
|
|
onChange={(e) => setFormData({ ...formData, subject: e.target.value })}
|
|
placeholder="메일 제목을 입력하세요"
|
|
className="w-full px-3 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-primary-400"
|
|
/>
|
|
</div>
|
|
|
|
{/* 발신자 */}
|
|
<div>
|
|
<label className="block text-white/80 text-sm font-medium mb-2">발신자</label>
|
|
<input
|
|
type="text"
|
|
value={formData.fromlist}
|
|
onChange={(e) => setFormData({ ...formData, fromlist: e.target.value })}
|
|
placeholder="발신자 이메일 (쉼표로 구분)"
|
|
className="w-full px-3 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-primary-400"
|
|
/>
|
|
</div>
|
|
|
|
{/* 수신자 */}
|
|
<div>
|
|
<label className="block text-white/80 text-sm font-medium mb-2">수신자 *</label>
|
|
<input
|
|
type="text"
|
|
value={formData.tolist}
|
|
onChange={(e) => setFormData({ ...formData, tolist: e.target.value })}
|
|
placeholder="수신자 이메일 (쉼표로 구분)"
|
|
className="w-full px-3 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-primary-400"
|
|
/>
|
|
</div>
|
|
|
|
{/* 참조 */}
|
|
<div>
|
|
<label className="block text-white/80 text-sm font-medium mb-2">참조 (CC)</label>
|
|
<input
|
|
type="text"
|
|
value={formData.cc}
|
|
onChange={(e) => setFormData({ ...formData, cc: e.target.value })}
|
|
placeholder="참조 이메일 (쉼표로 구분)"
|
|
className="w-full px-3 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-primary-400"
|
|
/>
|
|
</div>
|
|
|
|
{/* 숨은참조 */}
|
|
<div>
|
|
<label className="block text-white/80 text-sm font-medium mb-2">숨은참조 (BCC)</label>
|
|
<input
|
|
type="text"
|
|
value={formData.bcc}
|
|
onChange={(e) => setFormData({ ...formData, bcc: e.target.value })}
|
|
placeholder="숨은참조 이메일 (쉼표로 구분)"
|
|
className="w-full px-3 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-primary-400"
|
|
/>
|
|
</div>
|
|
|
|
{/* 내용 */}
|
|
<div>
|
|
<label className="block text-white/80 text-sm font-medium mb-2">내용 *</label>
|
|
<textarea
|
|
value={formData.body}
|
|
onChange={(e) => setFormData({ ...formData, body: e.target.value })}
|
|
placeholder="메일 내용을 입력하세요 (HTML 가능)"
|
|
rows={8}
|
|
className="w-full px-3 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-primary-400 resize-none"
|
|
/>
|
|
</div>
|
|
|
|
<div className="text-white/50 text-xs">
|
|
* 메일은 발송 대기열에 추가됩니다. 실제 발송은 메일 서비스가 처리합니다.
|
|
</div>
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<div className="flex items-center justify-end gap-2 px-6 py-4 border-t border-white/10 bg-black/20">
|
|
<button
|
|
onClick={onClose}
|
|
disabled={processing}
|
|
className="px-4 py-2 rounded-lg bg-white/10 hover:bg-white/20 text-white transition-colors disabled:opacity-50"
|
|
>
|
|
취소
|
|
</button>
|
|
<button
|
|
onClick={() => handleSubmit('queue')}
|
|
disabled={processing}
|
|
className="px-4 py-2 rounded-lg bg-blue-500 hover:bg-blue-600 text-white transition-colors flex items-center gap-2 disabled:opacity-50"
|
|
>
|
|
{processing ? (
|
|
<>
|
|
<div className="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" />
|
|
처리중...
|
|
</>
|
|
) : (
|
|
<>
|
|
<Mail className="w-4 h-4" />
|
|
대기열 추가
|
|
</>
|
|
)}
|
|
</button>
|
|
<button
|
|
onClick={() => handleSubmit('direct')}
|
|
disabled={processing}
|
|
className="px-4 py-2 rounded-lg bg-green-500 hover:bg-green-600 text-white transition-colors flex items-center gap-2 disabled:opacity-50"
|
|
>
|
|
{processing ? (
|
|
<>
|
|
<div className="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" />
|
|
처리중...
|
|
</>
|
|
) : (
|
|
<>
|
|
<Send className="w-4 h-4" />
|
|
즉시 발송
|
|
</>
|
|
)}
|
|
</button>
|
|
<button
|
|
onClick={() => handleSubmit('outlook')}
|
|
disabled={processing}
|
|
className="px-4 py-2 rounded-lg bg-orange-500 hover:bg-orange-600 text-white transition-colors flex items-center gap-2 disabled:opacity-50"
|
|
>
|
|
{processing ? (
|
|
<>
|
|
<div className="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" />
|
|
처리중...
|
|
</>
|
|
) : (
|
|
<>
|
|
<Mail className="w-4 h-4" />
|
|
Outlook
|
|
</>
|
|
)}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|