/** * Template email check-in — envoyé À L'UTILISATEUR (le patron de TPE) * pour lui demander si une facture donnée a été payée AVANT que la 1re * relance ne parte chez son client. * * Cet email reste **toujours en branding Rubis**, indépendamment du plan * de l'org — c'est une communication Rubis → user (méta-produit), pas * user → client. Le dispatcher passe donc `DEFAULT_BRAND` ici, jamais * les tokens custom. */ import * as React from 'react' import { Section, Text, Button, Heading, Hr } from '@react-email/components' import type { BrandTokens } from '#services/brand' import { sp } from './_brand.js' import { EmailLayout } from './_layout.js' export type CheckinEmailProps = { /** Toujours DEFAULT_BRAND — checkin reste Rubis-branded. */ tokens: BrandTokens invoice: { numero: string amountFormatted: string dueDateFormatted: string } client: { name: string } user: { fullName: string | null } paidUrl: string pendingUrl: string landingUrl?: string | null } export function CheckinEmail({ tokens, invoice, client, user, paidUrl, pendingUrl, landingUrl, }: CheckinEmailProps) { const greeting = user.fullName ? `Bonjour ${user.fullName.split(' ')[0]},` : 'Bonjour,' const greetingStyle: React.CSSProperties = { fontSize: '14px', color: tokens.textMuted, margin: `0 0 ${sp.md} 0`, } const titleStyle: React.CSSProperties = { color: tokens.text, fontSize: '24px', fontWeight: 700, letterSpacing: '-0.018em', lineHeight: '1.2', margin: `0 0 ${sp.md} 0`, } const emStyle: React.CSSProperties = { color: tokens.primary, fontStyle: 'normal', } const leadStyle: React.CSSProperties = { color: tokens.textMuted, fontSize: '14px', lineHeight: '1.6', margin: `0 0 ${sp.xl} 0`, } const invoiceCardStyle: React.CSSProperties = { backgroundColor: tokens.white, border: `1px solid ${tokens.border}`, borderRadius: tokens.radiusCard, padding: `${sp.lg} ${sp.xl}`, margin: `0 0 ${sp.xl} 0`, } const invoiceNumeroStyle: React.CSSProperties = { fontSize: '13px', fontWeight: 600, color: tokens.textMuted, letterSpacing: '0.02em', margin: 0, } const invoiceClientStyle: React.CSSProperties = { fontSize: '13px', color: tokens.textVeryMuted, margin: `${sp.xs} 0 ${sp.md} 0`, } const invoiceAmountStyle: React.CSSProperties = { fontSize: '28px', fontWeight: 800, letterSpacing: '-0.02em', color: tokens.text, margin: 0, lineHeight: '1', fontVariantNumeric: 'tabular-nums', } const invoiceDueStyle: React.CSSProperties = { fontSize: '12px', color: tokens.textVeryMuted, margin: `${sp.sm} 0 0 0`, } const primaryButtonStyle: React.CSSProperties = { backgroundColor: tokens.primary, color: tokens.buttonText, borderRadius: tokens.radiusButton, display: 'block', textAlign: 'center', textDecoration: 'none', padding: `${sp.md} ${sp.xl}`, fontSize: '15px', fontWeight: 600, width: '100%', boxSizing: 'border-box', boxShadow: '0 4px 12px rgba(159, 18, 57, 0.25)', } const secondaryButtonStyle: React.CSSProperties = { backgroundColor: tokens.white, color: tokens.text, border: `1px solid ${tokens.text}`, borderRadius: tokens.radiusButton, display: 'block', textAlign: 'center', textDecoration: 'none', padding: `${sp.md} ${sp.xl}`, fontSize: '15px', fontWeight: 600, width: '100%', boxSizing: 'border-box', } const hrStyle: React.CSSProperties = { borderColor: tokens.border, borderStyle: 'solid', borderWidth: '0 0 1px 0', margin: `${sp.xl} 0 ${sp.lg} 0`, } const footnoteStyle: React.CSSProperties = { fontSize: '11.5px', color: tokens.textVeryMuted, lineHeight: '1.5', margin: 0, fontStyle: 'italic', } return ( {greeting} Avez-vous été payé sur cette facture ? Aucune relance ne part sans votre validation. Si la facture est déjà réglée, on évite l'email inutile et on encaisse +1 rubis.
{invoice.numero} {client.name} {invoice.amountFormatted} Échéance le {invoice.dueDateFormatted}

Ces liens expirent dans 24h. Vous pouvez aussi répondre directement depuis l'app sur la fiche facture.
) }