ERP-node/frontend/components/mail/MailTemplateCard.tsx

151 lines
5.2 KiB
TypeScript
Raw Normal View History

2025-10-01 16:15:53 +09:00
"use client";
import React from 'react';
import { Mail, Edit2, Trash2, Eye, Copy, Calendar } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { MailTemplate } from '@/lib/api/mail';
interface MailTemplateCardProps {
template: MailTemplate;
onEdit: (template: MailTemplate) => void;
onDelete: (template: MailTemplate) => void;
onPreview: (template: MailTemplate) => void;
onDuplicate?: (template: MailTemplate) => void;
}
export default function MailTemplateCard({
template,
onEdit,
onDelete,
onPreview,
onDuplicate,
}: MailTemplateCardProps) {
const formatDate = (dateString: string) => {
return new Date(dateString).toLocaleDateString('ko-KR', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
});
};
const getCategoryColor = (category?: string) => {
const colors: Record<string, string> = {
welcome: 'bg-primary/20 text-blue-700 border-blue-300',
2025-10-01 16:15:53 +09:00
promotion: 'bg-purple-100 text-purple-700 border-purple-300',
notification: 'bg-green-100 text-green-700 border-green-300',
newsletter: 'bg-orange-100 text-orange-700 border-orange-300',
system: 'bg-gray-100 text-gray-700 border-gray-300',
};
return colors[category || ''] || 'bg-gray-100 text-gray-700 border-gray-300';
};
return (
<div className="group bg-white rounded-xl border border-gray-200 shadow-sm hover:shadow-lg transition-all duration-300 overflow-hidden">
{/* 헤더 */}
<div className="bg-gradient-to-r from-orange-50 to-amber-50 p-4 border-b border-gray-200">
<div className="flex items-start justify-between">
<div className="flex items-start gap-3 flex-1">
<div className="p-2 bg-white rounded-lg shadow-sm">
<Mail className="w-5 h-5 text-orange-500" />
</div>
<div className="flex-1 min-w-0">
<h3 className="font-semibold text-gray-900 truncate">
{template.name}
</h3>
<p className="text-sm text-muted-foreground truncate mt-1">
2025-10-01 16:15:53 +09:00
{template.subject}
</p>
</div>
</div>
{template.category && (
<span
className={`text-xs px-2 py-1 rounded-full border ${getCategoryColor(
template.category
)}`}
>
{template.category}
</span>
)}
</div>
</div>
{/* 본문 미리보기 */}
<div className="p-4 space-y-3">
<div className="bg-gray-50 rounded-lg p-3 border border-gray-200 min-h-[100px]">
<p className="text-xs text-gray-500 mb-2"> {template.components.length}</p>
<div className="space-y-1">
{template.components.slice(0, 3).map((component, idx) => (
<div key={idx} className="flex items-center gap-2 text-xs text-muted-foreground">
2025-10-01 16:15:53 +09:00
<div className="w-1.5 h-1.5 rounded-full bg-orange-400" />
<span className="capitalize">{component.type}</span>
{component.type === 'text' && component.content && (
<span className="text-gray-400 truncate flex-1">
{component.content.replace(/<[^>]*>/g, '').substring(0, 30)}...
</span>
)}
</div>
))}
{template.components.length > 3 && (
<p className="text-xs text-gray-400 pl-3.5">
+{template.components.length - 3}
</p>
)}
</div>
</div>
{/* 메타 정보 */}
<div className="flex items-center gap-3 text-xs text-gray-500 pt-2 border-t">
<div className="flex items-center gap-1">
<Calendar className="w-3.5 h-3.5" />
<span>{formatDate(template.createdAt)}</span>
</div>
{template.updatedAt !== template.createdAt && (
<span className="text-gray-400"></span>
)}
</div>
</div>
{/* 액션 버튼 */}
<div className="p-4 pt-0 flex gap-2">
<Button
size="sm"
variant="outline"
className="flex-1 hover:bg-accent hover:text-primary hover:border-blue-300"
2025-10-01 16:15:53 +09:00
onClick={() => onPreview(template)}
>
<Eye className="w-4 h-4 mr-1" />
</Button>
<Button
size="sm"
variant="outline"
className="flex-1 hover:bg-green-50 hover:text-green-600 hover:border-green-300"
onClick={() => onEdit(template)}
>
<Edit2 className="w-4 h-4 mr-1" />
</Button>
{onDuplicate && (
<Button
size="sm"
variant="outline"
className="hover:bg-purple-50 hover:text-purple-600 hover:border-purple-300"
onClick={() => onDuplicate(template)}
>
<Copy className="w-4 h-4" />
</Button>
)}
<Button
size="sm"
variant="outline"
className="hover:bg-destructive/10 hover:text-destructive hover:border-red-300"
2025-10-01 16:15:53 +09:00
onClick={() => onDelete(template)}
>
<Trash2 className="w-4 h-4" />
</Button>
</div>
</div>
);
}