From ecf7b549a319ed63de17f6885e4c9d1f5ffd880f Mon Sep 17 00:00:00 2001 From: kirukib Date: Sun, 14 Dec 2025 22:05:15 +0300 Subject: [PATCH] first --- .gitignore | 7 + app/api/email/[template]/route.ts | 36 ++++ app/layout.tsx | 18 ++ app/page.tsx | 270 ++++++++++++++++++++++++++++++ emails/components/Button.tsx | 28 ++++ emails/components/Card.tsx | 21 +++ emails/components/EmailLayout.tsx | 101 +++++++++++ emails/event-ticket.tsx | 222 ++++++++++++++++++++++++ emails/payment-request.tsx | 159 ++++++++++++++++++ emails/react-email.d.ts | 3 + emails/referral-success.tsx | 166 ++++++++++++++++++ emails/theme.ts | 22 +++ emails/transaction-complete.tsx | 118 +++++++++++++ emails/utils/logoDataUri.ts | 12 ++ emails/welcome.tsx | 69 ++++++++ next.config.js | 6 + package.json | 26 +++ public/logo.svg | 6 + tsconfig.json | 28 ++++ 19 files changed, 1318 insertions(+) create mode 100644 .gitignore create mode 100644 app/api/email/[template]/route.ts create mode 100644 app/layout.tsx create mode 100644 app/page.tsx create mode 100644 emails/components/Button.tsx create mode 100644 emails/components/Card.tsx create mode 100644 emails/components/EmailLayout.tsx create mode 100644 emails/event-ticket.tsx create mode 100644 emails/payment-request.tsx create mode 100644 emails/react-email.d.ts create mode 100644 emails/referral-success.tsx create mode 100644 emails/theme.ts create mode 100644 emails/transaction-complete.tsx create mode 100644 emails/utils/logoDataUri.ts create mode 100644 emails/welcome.tsx create mode 100644 next.config.js create mode 100644 package.json create mode 100644 public/logo.svg create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98b9c35 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +node_modules +.next +out +.DS_Store +*.log +.env.local +.env*.local diff --git a/app/api/email/[template]/route.ts b/app/api/email/[template]/route.ts new file mode 100644 index 0000000..e8f2cde --- /dev/null +++ b/app/api/email/[template]/route.ts @@ -0,0 +1,36 @@ +import { render } from '@react-email/render'; +import { WelcomeEmail } from '../../../../emails/welcome'; +import { TransactionCompleteEmail } from '../../../../emails/transaction-complete'; +import { EventTicketEmail } from '../../../../emails/event-ticket'; +import { PaymentRequestEmail } from '../../../../emails/payment-request'; +import { ReferralSuccessEmail } from '../../../../emails/referral-success'; +import { NextResponse } from 'next/server'; +import React from 'react'; + +const templates: Record> = { + welcome: WelcomeEmail, + 'transaction-complete': TransactionCompleteEmail, + 'event-ticket': EventTicketEmail, + 'payment-request': PaymentRequestEmail, + 'referral-success': ReferralSuccessEmail, +}; + +export async function GET( + request: Request, + context: { params: Promise<{ template: string }> } +) { + const { template } = await context.params; + const TemplateComponent = templates[template]; + + if (!TemplateComponent) { + return NextResponse.json({ error: 'Template not found' }, { status: 404 }); + } + + const html = render(React.createElement(TemplateComponent)); + + return new NextResponse(html, { + headers: { + 'Content-Type': 'text/html', + }, + }); +} diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 0000000..f205cf4 --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,18 @@ +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Amba Email Templates', + description: 'Preview and test email templates for Amba app', +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/app/page.tsx b/app/page.tsx new file mode 100644 index 0000000..7b4b5e3 --- /dev/null +++ b/app/page.tsx @@ -0,0 +1,270 @@ +'use client'; + +import { useState, useEffect } from 'react'; +import { theme } from '../emails/theme'; + +const templates = [ + { + id: 'welcome', + name: 'Welcome Email', + }, + { + id: 'transaction-complete', + name: 'Transaction Complete', + }, + { + id: 'event-ticket', + name: 'Event Ticket', + }, + { + id: 'payment-request', + name: 'Payment Request', + }, + { + id: 'referral-success', + name: 'Referral Success', + }, +]; + +export default function Home() { + const [selectedTemplate, setSelectedTemplate] = useState(templates[0]); + const [htmlContent, setHtmlContent] = useState(''); + const [loading, setLoading] = useState(true); + + const loadTemplate = async (templateId: string) => { + setLoading(true); + try { + const response = await fetch(`/api/email/${templateId}`); + const html = await response.text(); + setHtmlContent(html); + } catch (error) { + console.error('Error loading template:', error); + } finally { + setLoading(false); + } + }; + + const handleTemplateChange = (template: typeof templates[0]) => { + setSelectedTemplate(template); + loadTemplate(template.id); + }; + + const handleDownload = () => { + const blob = new Blob([htmlContent], { type: 'text/html' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = `${selectedTemplate.id}.html`; + a.click(); + URL.revokeObjectURL(url); + }; + + // Load initial template + useEffect(() => { + loadTemplate(selectedTemplate.id); + }, []); + + return ( +
+
+

Amba Email Templates

+

Preview and test all email templates

+
+ +
+ + +
+
+

{selectedTemplate.name}

+ +
+
+ {loading ? ( +
+

Loading template...

+
+ ) : ( +