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