diff options
Diffstat (limited to 'lib/email-template/editor/template-editor.tsx')
| -rw-r--r-- | lib/email-template/editor/template-editor.tsx | 175 |
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 |
