271 lines
6.0 KiB
TypeScript
271 lines
6.0 KiB
TypeScript
'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<string>('');
|
|
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 (
|
|
<div style={container}>
|
|
<header style={header}>
|
|
<h1 style={title}>Amba Email Templates</h1>
|
|
<p style={subtitle}>Preview and test all email templates</p>
|
|
</header>
|
|
|
|
<div style={content}>
|
|
<aside style={sidebar}>
|
|
<h2 style={sidebarTitle}>Templates</h2>
|
|
<nav style={nav}>
|
|
{templates.map((template) => (
|
|
<button
|
|
key={template.id}
|
|
onClick={() => handleTemplateChange(template)}
|
|
style={{
|
|
...navButton,
|
|
...(selectedTemplate.id === template.id
|
|
? activeNavButton
|
|
: {}),
|
|
}}
|
|
>
|
|
{template.name}
|
|
</button>
|
|
))}
|
|
</nav>
|
|
</aside>
|
|
|
|
<main style={previewSection}>
|
|
<div style={previewHeader}>
|
|
<h2 style={previewTitle}>{selectedTemplate.name}</h2>
|
|
<button
|
|
onClick={handleDownload}
|
|
disabled={!htmlContent}
|
|
style={{
|
|
...downloadButton,
|
|
...(loading ? { opacity: 0.5, cursor: 'not-allowed' } : {}),
|
|
}}
|
|
>
|
|
Download HTML
|
|
</button>
|
|
</div>
|
|
<div style={emailContainer}>
|
|
{loading ? (
|
|
<div style={loadingContainer}>
|
|
<p>Loading template...</p>
|
|
</div>
|
|
) : (
|
|
<iframe
|
|
srcDoc={htmlContent}
|
|
style={iframe}
|
|
title={selectedTemplate.name}
|
|
/>
|
|
)}
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const container = {
|
|
minHeight: '100vh',
|
|
backgroundColor: '#f5f5f5',
|
|
fontFamily: theme.fonts.sans,
|
|
};
|
|
|
|
const header = {
|
|
backgroundColor: theme.colors.primary,
|
|
color: theme.colors.background,
|
|
padding: theme.spacing.lg,
|
|
textAlign: 'center' as const,
|
|
};
|
|
|
|
const title = {
|
|
margin: '0 0 8px',
|
|
fontSize: '32px',
|
|
fontWeight: '700',
|
|
};
|
|
|
|
const subtitle = {
|
|
margin: '0',
|
|
fontSize: '16px',
|
|
opacity: 0.9,
|
|
};
|
|
|
|
const content = {
|
|
display: 'flex',
|
|
maxWidth: '1400px',
|
|
margin: '0 auto',
|
|
padding: theme.spacing.md,
|
|
gap: theme.spacing.md,
|
|
};
|
|
|
|
const sidebar = {
|
|
width: '250px',
|
|
backgroundColor: theme.colors.background,
|
|
borderRadius: '8px',
|
|
padding: theme.spacing.md,
|
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
|
height: 'fit-content',
|
|
position: 'sticky' as const,
|
|
top: theme.spacing.md,
|
|
};
|
|
|
|
const sidebarTitle = {
|
|
margin: '0 0 16px',
|
|
fontSize: '18px',
|
|
fontWeight: '600',
|
|
color: theme.colors.primary,
|
|
};
|
|
|
|
const nav = {
|
|
display: 'flex',
|
|
flexDirection: 'column' as const,
|
|
gap: '8px',
|
|
};
|
|
|
|
const navButton = {
|
|
padding: '12px 16px',
|
|
border: 'none',
|
|
borderRadius: '6px',
|
|
backgroundColor: 'transparent',
|
|
color: theme.colors.textDark,
|
|
fontSize: '14px',
|
|
fontWeight: '500',
|
|
cursor: 'pointer',
|
|
textAlign: 'left' as const,
|
|
transition: 'all 0.2s',
|
|
};
|
|
|
|
const activeNavButton = {
|
|
backgroundColor: theme.colors.accentLight,
|
|
color: theme.colors.primary,
|
|
fontWeight: '600',
|
|
};
|
|
|
|
const previewSection = {
|
|
flex: '1',
|
|
backgroundColor: theme.colors.background,
|
|
borderRadius: '8px',
|
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
|
display: 'flex',
|
|
flexDirection: 'column' as const,
|
|
};
|
|
|
|
const previewHeader = {
|
|
padding: theme.spacing.md,
|
|
borderBottom: `1px solid ${theme.colors.border}`,
|
|
display: 'flex',
|
|
justifyContent: 'space-between',
|
|
alignItems: 'center',
|
|
};
|
|
|
|
const previewTitle = {
|
|
margin: '0',
|
|
fontSize: '24px',
|
|
fontWeight: '600',
|
|
color: theme.colors.primary,
|
|
};
|
|
|
|
const downloadButton = {
|
|
padding: '8px 16px',
|
|
backgroundColor: theme.colors.primary,
|
|
color: theme.colors.background,
|
|
border: 'none',
|
|
borderRadius: '6px',
|
|
fontSize: '14px',
|
|
fontWeight: '600',
|
|
cursor: 'pointer',
|
|
transition: 'background-color 0.2s',
|
|
};
|
|
|
|
const emailContainer = {
|
|
flex: '1',
|
|
padding: theme.spacing.lg,
|
|
overflow: 'auto',
|
|
display: 'flex',
|
|
justifyContent: 'center',
|
|
backgroundColor: '#e0e0e0',
|
|
};
|
|
|
|
const iframe = {
|
|
width: '100%',
|
|
maxWidth: '600px',
|
|
height: '800px',
|
|
border: 'none',
|
|
borderRadius: '8px',
|
|
backgroundColor: theme.colors.background,
|
|
boxShadow: '0 4px 8px rgba(0,0,0,0.1)',
|
|
};
|
|
|
|
const loadingContainer = {
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
width: '100%',
|
|
maxWidth: '600px',
|
|
height: '800px',
|
|
backgroundColor: theme.colors.background,
|
|
borderRadius: '8px',
|
|
color: theme.colors.textDark,
|
|
fontSize: '16px',
|
|
};
|