1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
'use client';
/* IMPORT */
import { ArrowLeft, Edit, List, Settings } from 'lucide-react';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { getCategoryDisplayName } from '../validations';
import Link from 'next/link';
import { Separator } from '@/components/ui/separator';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { TemplateContentEditor } from './template-content-editor';
import { TemplateSettings } from './template-settings';
import { TemplateVariableManager } from './template-variable-manager';
import { type TemplateWithVariables } from '@/db/schema';
import { useState } from 'react';
// ----------------------------------------------------------------------------------------------------
/* TYPES */
interface TemplateEditorProps {
templateSlug: string;
initialTemplate: TemplateWithVariables;
}
export function TemplateEditor({ templateSlug, initialTemplate }: TemplateEditorProps) {
const [template, setTemplate] = 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">
{getCategoryDisplayName(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>
</ul>
</div>
</div>
</div>
)
}
|