Files
Groupware/Project/frontend/src/components/mail/MailTestDialog.tsx
backuppc 77f1ddab80 ..
2025-12-05 17:33:12 +09:00

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>
);
}