/** * Squelette commun aux 2 templates Rubis : header rubis-deep avec brand * + container cream + footer "Émis via Rubis sur l'ongle" (cliquable * vers la landing publique). * * Approche : on stylé en inline via les `style` props que React Email * convertit en HTML inline (compatible tous mail clients y compris * Outlook). Pas de classes Tailwind ici — risquées en mail. */ import * as React from 'react' import { Html, Head, Preview, Body, Container, Section, Row, Column, Text, Link, } from '@react-email/components' import { BRAND, sp } from './_brand.js' type LayoutProps = { /** Aperçu dans la liste mail (Gmail preview text). */ preview: string /** Nom commercial affiché dans le header (vendeur ou "Rubis"). */ brandName: string /** Sous-titre header (ex: numéro de facture, date). Optionnel. */ brandSubtitle?: string | null /** URL de la landing publique — lien dans le footer ("Rubis sur l'ongle"). */ landingUrl?: string children: React.ReactNode } export function EmailLayout({ preview, brandName, brandSubtitle, landingUrl, children, }: LayoutProps) { return ( {preview} {/* Bandeau rubis-deep avec gem ◆ + brand */}
{brandName} {brandSubtitle ? ( {brandSubtitle} ) : null}
{/* Corps de l'email */}
{children}
{/* Footer Rubis — "Rubis sur l'ongle" cliquable vers la landing */}
Émis via{' '} {landingUrl ? ( Rubis sur l'ongle ) : ( Rubis sur l'ongle )} {' — '} vos factures relancées toutes seules pendant que vous travaillez.
) } // --------------------------------------------------------------------------- // Styles inline // --------------------------------------------------------------------------- const bodyStyle: React.CSSProperties = { backgroundColor: BRAND.cream, fontFamily: BRAND.fontBody, margin: 0, padding: `${sp.xl} 0`, color: BRAND.ink, } const containerStyle: React.CSSProperties = { backgroundColor: BRAND.white, borderRadius: BRAND.radiusCard, border: `1px solid ${BRAND.line}`, margin: '0 auto', maxWidth: '560px', overflow: 'hidden', } const headerStyle: React.CSSProperties = { backgroundColor: BRAND.rubisDeep, padding: `${sp.xl} ${sp.xl}`, } const headerBrandStyle: React.CSSProperties = { color: BRAND.white, fontSize: '20px', fontWeight: 800, letterSpacing: '-0.01em', margin: 0, lineHeight: '1.1', } const gemStyle: React.CSSProperties = { display: 'inline-block', marginRight: sp.sm, color: BRAND.rubisGlow, fontSize: '18px', verticalAlign: '-1px', } const headerSubtitleStyle: React.CSSProperties = { color: BRAND.cream2, fontSize: '12px', margin: `${sp.xs} 0 0 0`, letterSpacing: '0.04em', textTransform: 'uppercase', fontWeight: 600, } const contentStyle: React.CSSProperties = { padding: `${sp.xl} ${sp.xl}`, } const footerStyle: React.CSSProperties = { borderTop: `1px solid ${BRAND.line}`, backgroundColor: BRAND.cream2, padding: `${sp.lg} ${sp.xl}`, } const footerTextStyle: React.CSSProperties = { color: BRAND.ink3, fontSize: '11px', lineHeight: '1.5', margin: 0, textAlign: 'center', } const footerLinkStyle: React.CSSProperties = { color: BRAND.rubis, fontWeight: 600, textDecoration: 'none', }