import { Body, Button as EmailButton, Container, Head, Html, Img, Link, Row, Section, Text as EmailText, } from '@react-email/components'; import type { PropsWithChildren } from 'react'; import { BasicTextStyle } from './common'; import { Footer } from './footer'; export function Title(props: PropsWithChildren) { return ( {props.children} ); } export function P(props: PropsWithChildren) { return {props.children}; } export function Text(props: PropsWithChildren) { return {props.children}; } export function SecondaryText(props: PropsWithChildren) { return ( {props.children} ); } export function Bold(props: PropsWithChildren) { return {props.children}; } export const Avatar = (props: { img: string; width?: string; height?: string; }) => { return ( avatar ); }; export const OnelineCodeBlock = (props: PropsWithChildren) => { return (
      {props.children}
    
); }; export const Name = (props: PropsWithChildren) => { return {props.children}; }; export const AvatarWithName = (props: { img?: string; name: string; width?: string; height?: string; }) => { return ( <> {props.img && ( )} {props.name} ); }; export function Content(props: PropsWithChildren) { return typeof props.children === 'string' ? ( {props.children} ) : ( props.children ); } export function Button( props: PropsWithChildren<{ type?: 'primary' | 'secondary'; href: string }> ) { const style = { ...BasicTextStyle, backgroundColor: props.type === 'secondary' ? '#FFFFFF' : '#1E96EB', color: props.type === 'secondary' ? '#141414' : '#FFFFFF', textDecoration: 'none', fontWeight: '600', padding: '8px 18px', borderRadius: '8px', border: '1px solid rgba(0,0,0,.1)', marginRight: '4px', }; return ( {props.children} ); } function fetchTitle( children: React.ReactElement[] ): React.ReactElement { const title = children.find(child => child.type === Title); if (!title || !title.props.children) { throw new Error(' is required for an email.'); } return title; } function fetchContent( children: React.ReactElement<PropsWithChildren>[] ): React.ReactElement | React.ReactElement[] { const content = children.find(child => child.type === Content); if (!content || !content.props.children) { throw new Error('<Content /> is required for an email.'); } if (Array.isArray(content.props.children)) { return content.props.children.map((child, i) => { /* oxlint-disable-next-line eslint-plugin-react/no-array-index-key */ return <Row key={i}>{child}</Row>; }); } return content; } function assertChildrenIsArray( children: React.ReactNode ): asserts children is React.ReactElement<PropsWithChildren>[] { if (!Array.isArray(children) || !children.every(child => 'type' in child)) { throw new Error( 'Children of `Template` element must be an array of [<Title />, <Content />, ...]' ); } } export function Template(props: PropsWithChildren) { assertChildrenIsArray(props.children); const content = ( <> <Section>{fetchTitle(props.children)}</Section> <Section>{fetchContent(props.children)}</Section> </> ); if (globalThis.env?.testing) { return content; } return ( <Html> <Head /> <Body style={{ backgroundColor: '#f6f7fb', overflow: 'hidden' }}> <Container style={{ backgroundColor: '#fff', maxWidth: '450px', margin: '32px auto 0', borderRadius: '16px 16px 0 0', boxShadow: '0px 0px 20px 0px rgba(66, 65, 73, 0.04)', padding: '24px', }} > <Section> <Link href="https://affine.pro"> <Img src="https://cdn.affine.pro/mail/2023-8-9/affine-logo.png" alt="AFFiNE logo" height="32px" /> </Link> </Section> {content} </Container> <Footer /> </Body> </Html> ); }