diff options
Diffstat (limited to 'app/api/email-template/preview/route.ts')
| -rw-r--r-- | app/api/email-template/preview/route.ts | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/app/api/email-template/preview/route.ts b/app/api/email-template/preview/route.ts new file mode 100644 index 00000000..6e066d27 --- /dev/null +++ b/app/api/email-template/preview/route.ts @@ -0,0 +1,117 @@ +import { NextResponse } from 'next/server';
+import db from "@/db/db";
+import { templateDetailView } from '@/db/schema';
+import { eq } from 'drizzle-orm';
+import handlebars from 'handlebars';
+
+// Handlebars helper 등록
+handlebars.registerHelper('formatDate', function(date: any, format: string) {
+ if (!date) return '';
+
+ const d = new Date(date);
+ if (isNaN(d.getTime())) return '';
+
+ const year = d.getFullYear();
+ const month = String(d.getMonth() + 1).padStart(2, '0');
+ const day = String(d.getDate()).padStart(2, '0');
+ const hours = String(d.getHours()).padStart(2, '0');
+ const minutes = String(d.getMinutes()).padStart(2, '0');
+ const seconds = String(d.getSeconds()).padStart(2, '0');
+
+ switch (format) {
+ case 'YYYY-MM-DD':
+ return `${year}-${month}-${day}`;
+ case 'YYYY-MM-DD HH:mm:ss':
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+ case 'YYYY-MM-DD HH:mm':
+ return `${year}-${month}-${day} ${hours}:${minutes}`;
+ default:
+ return d.toLocaleDateString('ko-KR');
+ }
+});
+
+export async function POST(request: Request) {
+ try {
+ const { templateSlug, sampleData } = await request.json();
+
+ if (!templateSlug) {
+ return NextResponse.json(
+ {
+ success: false,
+ error: '템플릿 슬러그가 필요합니다.'
+ },
+ { status: 400 }
+ );
+ }
+
+ // 데이터베이스에서 템플릿 조회
+ const templates = await db
+ .select()
+ .from(templateDetailView)
+ .where(eq(templateDetailView.slug, templateSlug))
+ .limit(1);
+
+ if (templates.length === 0) {
+ return NextResponse.json(
+ {
+ success: false,
+ error: '템플릿을 찾을 수 없습니다.'
+ },
+ { status: 404 }
+ );
+ }
+
+ const template = templates[0];
+
+ if (!template.isActive) {
+ return NextResponse.json(
+ {
+ success: false,
+ error: '비활성화된 템플릿입니다.'
+ },
+ { status: 400 }
+ );
+ }
+
+ // HTML 템플릿에서 t helper 제거 ({{t 'key'}} -> {{key}})
+ let subjectTemplateStr = template.subject || '';
+ let contentTemplateStr = template.content || '';
+
+ // {{t 'key'}} 패턴을 {{key}}로 치환
+ subjectTemplateStr = subjectTemplateStr.replace(/\{\{t\s+['"]([^'"]+)['"]\}\}/g, '{{$1}}');
+ contentTemplateStr = contentTemplateStr.replace(/\{\{t\s+['"]([^'"]+)['"]\}\}/g, '{{$1}}');
+
+ // Handlebars 템플릿 컴파일 및 렌더링
+ try {
+ const subjectTemplate = handlebars.compile(subjectTemplateStr);
+ const contentTemplate = handlebars.compile(contentTemplateStr);
+
+ const renderedSubject = subjectTemplate(sampleData);
+ const renderedContent = contentTemplate(sampleData);
+
+ return NextResponse.json({
+ success: true,
+ subject: renderedSubject,
+ html: renderedContent
+ });
+ } catch (compileError) {
+ console.error('템플릿 컴파일 오류:', compileError);
+ return NextResponse.json(
+ {
+ success: false,
+ error: '템플릿 처리 중 오류가 발생했습니다.'
+ },
+ { status: 500 }
+ );
+ }
+ } catch (error) {
+ console.error('미리보기 생성 실패:', error);
+ return NextResponse.json(
+ {
+ success: false,
+ error: '미리보기를 생성하는데 실패했습니다.'
+ },
+ { status: 500 }
+ );
+ }
+}
|
