summaryrefslogtreecommitdiff
path: root/lib/email-template/editor/template-editor.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/email-template/editor/template-editor.tsx')
-rw-r--r--lib/email-template/editor/template-editor.tsx175
1 files changed, 175 insertions, 0 deletions
diff --git a/lib/email-template/editor/template-editor.tsx b/lib/email-template/editor/template-editor.tsx
new file mode 100644
index 00000000..68cade45
--- /dev/null
+++ b/lib/email-template/editor/template-editor.tsx
@@ -0,0 +1,175 @@
+"use client"
+
+import * as React from "react"
+import { useRouter } from "next/navigation"
+import { ArrowLeft, Save, Edit, Settings, List } from "lucide-react"
+import Link from "next/link"
+
+import { Button } from "@/components/ui/button"
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card"
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
+import { Separator } from "@/components/ui/separator"
+import { Badge } from "@/components/ui/badge"
+
+import { type TemplateWithVariables } from "@/db/schema"
+import { TemplateContentEditor } from "./template-content-editor"
+import { TemplateVariableManager } from "./template-variable-manager"
+import { TemplateSettings } from "./template-settings"
+
+interface TemplateEditorProps {
+ templateSlug: string
+ initialTemplate: TemplateWithVariables
+}
+
+export function TemplateEditor({ templateSlug, initialTemplate }: TemplateEditorProps) {
+ const router = useRouter()
+ const [template, setTemplate] = React.useState(initialTemplate)
+
+ return (
+ <div className="flex flex-1 flex-col gap-4 p-4 md:gap-8 md:p-8">
+ {/* 헤더 */}
+ <div className="flex items-center gap-4">
+ <Button variant="ghost" size="icon" asChild>
+ <Link href="/evcp/email-template">
+ <ArrowLeft className="h-4 w-4" />
+ </Link>
+ </Button>
+ <div className="flex-1">
+ <div className="flex items-center gap-3">
+ <h1 className="text-2xl font-semibold">{template.name}</h1>
+ <Badge variant="outline" className="text-xs">
+ v{template.version}
+ </Badge>
+ {template.category && (
+ <Badge variant="secondary" className="text-xs">
+ {template.category}
+ </Badge>
+ )}
+ </div>
+ <p className="text-sm text-muted-foreground">
+ {template.description || "템플릿 편집"}
+ </p>
+ </div>
+
+ {/* 헤더 액션 버튼들 */}
+ <div className="flex items-center gap-2">
+ <Button variant="outline" size="sm" asChild>
+ <Link href={`/evcp/templates/${template.slug}/send`}>
+ 테스트 발송
+ </Link>
+ </Button>
+ </div>
+ </div>
+
+ <Separator />
+
+ {/* 메인 편집 영역 - 3개 탭으로 간소화 */}
+ <Tabs defaultValue="editor" className="flex-1">
+ <TabsList className="grid w-full grid-cols-3">
+ <TabsTrigger value="editor" className="gap-2">
+ <Edit className="h-4 w-4" />
+ 편집 & 미리보기
+ </TabsTrigger>
+ <TabsTrigger value="variables" className="gap-2">
+ <List className="h-4 w-4" />
+ 변수 관리
+ </TabsTrigger>
+ <TabsTrigger value="settings" className="gap-2">
+ <Settings className="h-4 w-4" />
+ 설정
+ </TabsTrigger>
+ </TabsList>
+
+ {/* 편집 & 미리보기 탭 (통합) */}
+ <TabsContent value="editor" className="mt-6">
+ <Card>
+ <CardHeader>
+ <CardTitle>템플릿 편집 & 미리보기</CardTitle>
+ <CardDescription>
+ 왼쪽에서 이메일 제목과 내용을 편집하고, 오른쪽에서 실시간 미리보기를 확인하세요.
+ </CardDescription>
+ </CardHeader>
+ <CardContent>
+ <TemplateContentEditor
+ template={template}
+ onUpdate={setTemplate}
+ />
+ </CardContent>
+ </Card>
+ </TabsContent>
+
+ {/* 변수 관리 탭 */}
+ <TabsContent value="variables" className="mt-6">
+ <Card>
+ <CardHeader>
+ <CardTitle>변수 관리</CardTitle>
+ <CardDescription>
+ 템플릿에서 사용할 변수를 추가하고 관리하세요. 추가되는 변수는 실제 코드에서 정의가 되어있지 않으면 템플릿에 있더라도 나타나지 않습니다.
+ </CardDescription>
+ </CardHeader>
+ <CardContent>
+ <TemplateVariableManager
+ template={template}
+ onUpdate={setTemplate}
+ />
+ </CardContent>
+ </Card>
+ </TabsContent>
+
+ {/* 설정 탭 */}
+ <TabsContent value="settings" className="mt-6">
+ <Card>
+ <CardHeader>
+ <CardTitle>템플릿 설정</CardTitle>
+ <CardDescription>
+ 템플릿의 기본 정보와 설정을 관리하세요.
+ </CardDescription>
+ </CardHeader>
+ <CardContent>
+ <TemplateSettings
+ template={template}
+ onUpdate={setTemplate}
+ />
+ </CardContent>
+ </Card>
+ </TabsContent>
+ </Tabs>
+
+ {/* 추가 정보 */}
+ <div className="mt-8 grid grid-cols-1 md:grid-cols-3 gap-4 text-sm text-muted-foreground">
+ <div className="bg-blue-50 p-4 rounded-lg">
+ <h4 className="font-medium text-blue-900 mb-2">💡 편집 팁</h4>
+ <ul className="space-y-1 text-blue-800">
+ <li>• 자동 미리보기를 켜두면 편집하면서 바로 확인 가능</li>
+ <li>• 변수 배지를 클릭하면 커서 위치에 바로 삽입</li>
+ <li>• Ctrl+S로 빠른 저장</li>
+ </ul>
+ </div>
+
+ <div className="bg-green-50 p-4 rounded-lg">
+ <h4 className="font-medium text-green-900 mb-2">📊 템플릿 상태</h4>
+ <ul className="space-y-1 text-green-800">
+ <li>• 변수: {template.variables.length}개</li>
+ <li>• 필수 변수: {template.variables.filter(v => v.isRequired).length}개</li>
+ <li>• 최종 수정: {new Date(template.updatedAt).toLocaleDateString('ko-KR')}</li>
+ </ul>
+ </div>
+
+ <div className="bg-purple-50 p-4 rounded-lg">
+ <h4 className="font-medium text-purple-900 mb-2">🚀 다음 단계</h4>
+ <ul className="space-y-1 text-purple-800">
+ <li>• 변수 관리에서 필요한 변수 추가</li>
+ <li>• 설정에서 카테고리 및 설명 수정</li>
+ <li>• 테스트 발송으로 실제 이메일 확인</li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ )
+} \ No newline at end of file