Gishen-Email-Template/emails/components/EmailLayout.tsx
Kirubel-Kibru-Yaltopia f9fa3bc83b feat: add Gishen React Email demo with en/am templates
Ship 23 transactional templates, shared brand tokens/logo, preview UI,
render API, CHANGELOG, and docs for Ecom/Admin/B2B consumers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 22:12:21 +03:00

129 lines
3.0 KiB
TypeScript

import React from 'react';
import {
Body,
Container,
Head,
Html,
Img,
Link,
Preview,
Section,
Text,
} from '@react-email/components';
import { theme } from '../theme';
import { logoDataUri } from '../utils/logoDataUri';
import { tCommon } from '../i18n/common';
import type { Locale } from '../i18n/types';
interface EmailLayoutProps {
preview: string;
children: React.ReactNode;
locale?: Locale;
logoUrl?: string;
}
export const EmailLayout = ({
preview,
children,
locale = 'en',
logoUrl = logoDataUri,
}: EmailLayoutProps) => {
const common = tCommon(locale);
return (
<Html lang={locale}>
<Head>
<link
href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
</Head>
<Preview>{preview}</Preview>
<Body style={main}>
<Container style={container}>
<Section style={header}>
<Img
src={logoUrl}
width="180"
height="42"
alt={theme.brand.name}
style={logo}
/>
</Section>
<Section style={content}>{children}</Section>
<Section style={footer}>
<Text style={footerText}>
© {new Date().getFullYear()} {theme.brand.name}. {common.allRights}
</Text>
<Text style={footerText}>
{theme.brand.address} · {theme.brand.phone}
</Text>
<Text style={footerText}>
<Link href={`${theme.brand.website}/privacy`} style={footerLink}>
{common.privacy}
</Link>
{' · '}
<Link href={`${theme.brand.website}/terms`} style={footerLink}>
{common.terms}
</Link>
{' · '}
<Link href={`mailto:${theme.brand.email}`} style={footerLink}>
{theme.brand.email}
</Link>
</Text>
</Section>
</Container>
</Body>
</Html>
);
};
const main = {
backgroundColor: theme.colors.cream,
fontFamily: theme.fonts.sans,
};
const container = {
margin: '0 auto',
padding: '24px 0 48px',
maxWidth: '600px',
};
const header = {
padding: '28px 24px',
textAlign: 'center' as const,
backgroundColor: theme.colors.surface,
borderTop: `4px solid ${theme.colors.brand}`,
borderRadius: '12px 12px 0 0',
};
const logo = {
margin: '0 auto',
};
const content = {
backgroundColor: theme.colors.surface,
padding: '8px 28px 32px',
borderLeft: `1px solid ${theme.colors.line}`,
borderRight: `1px solid ${theme.colors.line}`,
};
const footer = {
backgroundColor: theme.colors.forest,
padding: '24px 28px',
borderRadius: '0 0 12px 12px',
textAlign: 'center' as const,
};
const footerText = {
color: '#C5C9B8',
fontSize: '12px',
lineHeight: '18px',
margin: '0 0 8px',
};
const footerLink = {
color: theme.colors.brand,
textDecoration: 'none',
};