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

145 lines
6.1 KiB
TypeScript

"use client";
import React, { useState } from "react";
import { X, Eye, Mail, Code, Maximize2, Minimize2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { MailTemplate, renderTemplateToHtml, extractTemplateVariables } from "@/lib/api/mail";
interface MailTemplatePreviewModalProps {
isOpen: boolean;
onClose: () => void;
template: MailTemplate | null;
}
export default function MailTemplatePreviewModal({ isOpen, onClose, template }: MailTemplatePreviewModalProps) {
const [viewMode, setViewMode] = useState<"preview" | "code">("preview");
const [isFullscreen, setIsFullscreen] = useState(false);
const [variables, setVariables] = useState<Record<string, string>>({});
if (!isOpen || !template) return null;
const templateVariables = extractTemplateVariables(template);
const renderedHtml = renderTemplateToHtml(template, variables);
const handleVariableChange = (key: string, value: string) => {
setVariables((prev) => ({ ...prev, [key]: value }));
};
return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
<div
className={`bg-card overflow-hidden rounded-xl border shadow-2xl transition-all ${
isFullscreen ? "h-full w-full" : "max-h-[90vh] w-full max-w-6xl"
}`}
>
{/* 헤더 */}
<div className="bg-muted sticky top-0 z-10 flex items-center justify-between border-b px-6 py-4">
<div className="flex items-center gap-3">
<Eye className="text-foreground h-6 w-6" />
<div>
<h2 className="text-foreground text-xl font-bold">{template.name}</h2>
<p className="text-muted-foreground text-sm">{template.subject}</p>
</div>
</div>
<div className="flex items-center gap-2">
<button
onClick={() => setViewMode(viewMode === "preview" ? "code" : "preview")}
className="text-foreground hover:bg-background flex items-center gap-2 rounded-lg px-3 py-2 transition"
>
{viewMode === "preview" ? (
<>
<Code className="h-4 w-4" />
</>
) : (
<>
<Eye className="h-4 w-4" />
</>
)}
</button>
<button
onClick={() => setIsFullscreen(!isFullscreen)}
className="text-foreground hover:bg-background rounded-lg p-2 transition"
>
{isFullscreen ? <Minimize2 className="h-5 w-5" /> : <Maximize2 className="h-5 w-5" />}
</button>
<button onClick={onClose} className="text-foreground hover:bg-background rounded-lg p-2 transition">
<X className="h-5 w-5" />
</button>
</div>
</div>
{/* 본문 */}
<div className="flex h-full overflow-hidden">
{/* 왼쪽: 변수 입력 (변수가 있을 때만) */}
{templateVariables.length > 0 && (
<div className="bg-muted/30 w-80 overflow-y-auto border-r p-6">
<h3 className="text-foreground mb-4 flex items-center gap-2 text-lg font-semibold">
<Mail className="text-foreground h-5 w-5" />
릿
</h3>
<div className="space-y-4">
{templateVariables.map((variable) => (
<div key={variable}>
<label className="text-foreground mb-1 block text-sm font-medium">{variable}</label>
<input
type="text"
value={variables[variable] || ""}
onChange={(e) => handleVariableChange(variable, e.target.value)}
placeholder={`{${variable}}`}
className="focus:ring-primary focus:border-primary bg-background w-full rounded-lg border px-3 py-2 focus:ring-2"
/>
</div>
))}
</div>
<div className="bg-muted mt-6 rounded-lg border p-4">
<p className="text-muted-foreground text-xs">💡 .</p>
</div>
</div>
)}
{/* 오른쪽: 미리보기 또는 코드 */}
<div className="flex-1 overflow-y-auto p-6">
{viewMode === "preview" ? (
<div className="bg-card overflow-hidden rounded-lg border">
{/* 이메일 헤더 시뮬레이션 */}
<div className="bg-muted border-b px-6 py-4">
<div className="space-y-2 text-sm">
<div className="flex">
<span className="text-muted-foreground w-20 font-semibold">:</span>
<span className="text-foreground">{template.subject}</span>
</div>
<div className="flex">
<span className="text-muted-foreground w-20 font-semibold">:</span>
<span className="text-foreground">your-email@company.com</span>
</div>
<div className="flex">
<span className="text-muted-foreground w-20 font-semibold">:</span>
<span className="text-foreground">recipient@example.com</span>
</div>
</div>
</div>
{/* 이메일 본문 */}
<div className="p-6" dangerouslySetInnerHTML={{ __html: renderedHtml }} />
</div>
) : (
<div className="bg-muted/50 overflow-x-auto rounded-lg border p-6 font-mono text-sm">
<pre className="text-foreground break-words whitespace-pre-wrap">{renderedHtml}</pre>
</div>
)}
</div>
</div>
{/* 푸터 */}
<div className="bg-muted/30 sticky bottom-0 flex justify-end gap-3 border-t px-6 py-4">
<Button variant="outline" onClick={onClose}>
</Button>
</div>
</div>
</div>
);
}