chore(server): clean mail-templates and add tailwind style (#11296)

With this commit I wanted to complete the react-mail
 structure by properly define the templates styles by
 including tailwind css framework.

The framework is extended by both react-mail and
 tailwindcss-preset-email. Those packages help the rendering
 for various email clients.

If in future there is the necessity to target specific mail
 clients the package `tailwindcss-email-variants` and
 `tailwindcss-mso` can help too. The latter has some
 workarounds for the Ms Outlook that is still lacking
 a lot of the CSS3 funcitonality.
 to target

Signed-off-by: hitech95 <nicveronese@gmail.com>
This commit is contained in:
Nicolò
2024-07-26 22:41:11 +02:00
committed by GitHub
parent a444ea7361
commit ee6f1a010c
11 changed files with 516 additions and 724 deletions

View File

@@ -1,21 +1,8 @@
import {
Body,
Button,
Column,
Container,
Head,
Hr,
Html,
Img,
Link,
Preview,
Row,
Section,
Text,
} from '@react-email/components';
import * as CSS from 'csstype';
import { Img, Link, Section, Text } from '@react-email/components';
import * as React from 'react';
import { AlbumInviteEmailProps } from 'src/interfaces/notification.interface';
import { ImmichButton } from './components/button.component';
import ImmichLayout from './components/immich.layout';
export const AlbumInviteEmail = ({
baseUrl,
@@ -25,122 +12,37 @@ export const AlbumInviteEmail = ({
albumId,
cid,
}: AlbumInviteEmailProps) => (
<Html>
<Head />
<Preview>You have been added to a shared album.</Preview>
<Body
style={{
margin: 0,
padding: 0,
backgroundColor: '#ffffff',
color: 'rgb(28,28,28)',
fontFamily: 'Overpass, sans-serif',
fontSize: '18px',
lineHeight: '24px',
}}
>
<Container
style={{
width: '540px',
maxWidth: '100%',
padding: '10px',
margin: '0 auto',
}}
>
<Section
<ImmichLayout preview="You have been added to a shared album.">
<Text className="m-0 text-2xl">
Hey <strong>{recipientName}</strong>!
</Text>
<Text>
{senderName} has added you to the album <strong>{albumName}</strong>.
</Text>
{cid && (
<Section className="flex justify-center my-0">
<Img
className="max-w-[300px] w-full rounded-lg"
src={`cid:${cid}`}
style={{
padding: '36px',
tableLayout: 'fixed',
backgroundColor: 'rgb(226, 232, 240)',
border: 'solid 0px rgb(248 113 113)',
borderRadius: '50px',
textAlign: 'center' as const,
boxShadow: 'rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px',
}}
>
<Img
src="https://immich.app/img/immich-logo-inline-light.png"
alt="Immich"
style={{
height: 'auto',
margin: '0 auto 48px auto',
width: '50%',
alignSelf: 'center',
color: 'white',
}}
/>
/>
</Section>
)}
<Text style={text}>Hey {recipientName}!</Text>
<Section className="flex justify-center my-6">
<ImmichButton href={`${baseUrl}/albums/${albumId}`}>View Album</ImmichButton>
</Section>
<Text style={text}>
{senderName} has added you to the album <strong>{albumName}</strong>.
</Text>
{cid && (
<Row>
<Column align="center">
<Img
src={`cid:${cid}`}
width="300"
style={{
borderRadius: '20px',
boxShadow: 'rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px',
}}
/>
</Column>
</Row>
)}
<Row style={{ marginBottom: '36px', marginTop: '36px' }}>
<Text style={{ ...text }}>To view the album, open the link in a browser, or click the button below.</Text>
</Row>
<Row>
<Column align="center">
<Link style={{ marginTop: '50px' }} href={`${baseUrl}/albums/${albumId}`}>
{baseUrl}/albums/{albumId}
</Link>
</Column>
</Row>
<Row>
<Column align="center">
<Button style={button} href={`${baseUrl}/albums/${albumId}`}>
View album
</Button>
</Column>
</Row>
</Section>
<Hr style={{ color: 'rgb(66, 80, 175)', marginTop: '24px' }} />
<Section style={{ textAlign: 'center' }}>
<Row>
<Column align="center">
<Link href="https://play.google.com/store/apps/details?id=app.alextran.immich">
<Img src={`https://immich.app/img/google-play-badge.png`} height="96px" alt="Immich" />
</Link>
<Link href="https://apps.apple.com/sg/app/immich/id1613945652">
<Img
src={`https://immich.app/img/ios-app-store-badge.png`}
alt="Immich"
style={{ height: '72px', padding: '14px' }}
/>
</Link>
</Column>
</Row>
</Section>
<Text
style={{
color: '#6a737d',
fontSize: '0.8rem',
textAlign: 'center' as const,
marginTop: '12px',
}}
>
<Link href="https://immich.app">Immich</Link> project is available under GNU AGPL v3 license.
</Text>
</Container>
</Body>
</Html>
<Text className="text-xs">
If you cannot click the button use the link below to view the album.
<br />
<Link href={`${baseUrl}/albums/${albumId}`}>{`${baseUrl}/albums/${albumId}`}</Link>
</Text>
</ImmichLayout>
);
AlbumInviteEmail.PreviewProps = {
@@ -148,27 +50,7 @@ AlbumInviteEmail.PreviewProps = {
albumName: 'Trip to Europe',
albumId: 'b63f6dae-e1c9-401b-9a85-9dbbf5612539',
senderName: 'Owner User',
recipientName: 'Guest User',
cid: '',
recipientName: 'Alan Turing',
} as AlbumInviteEmailProps;
export default AlbumInviteEmail;
const text = {
margin: '0 0 24px 0',
textAlign: 'left' as const,
fontSize: '18px',
lineHeight: '24px',
};
const button: CSS.Properties = {
backgroundColor: 'rgb(66, 80, 175)',
margin: '1em 0',
padding: '0.75em 3em',
color: '#fff',
fontSize: '1em',
fontWeight: 700,
lineHeight: 1.5,
textTransform: 'uppercase',
borderRadius: '9999px',
};

View File

@@ -1,165 +1,49 @@
import {
Body,
Button,
Column,
Container,
Head,
Hr,
Html,
Img,
Link,
Preview,
Row,
Section,
Text,
} from '@react-email/components';
import * as CSS from 'csstype';
import { Img, Link, Section, Text } from '@react-email/components';
import * as React from 'react';
import { AlbumUpdateEmailProps } from 'src/interfaces/notification.interface';
import { ImmichButton } from './components/button.component';
import ImmichLayout from './components/immich.layout';
export const AlbumUpdateEmail = ({ baseUrl, albumName, recipientName, albumId, cid }: AlbumUpdateEmailProps) => (
<Html>
<Head />
<Preview>New media has been added to a shared album.</Preview>
<Body
style={{
margin: 0,
padding: 0,
backgroundColor: '#ffffff',
color: 'rgb(28,28,28)',
fontFamily: 'Overpass, sans-serif',
fontSize: '18px',
lineHeight: '24px',
}}
>
<Container
style={{
width: '540px',
maxWidth: '100%',
padding: '10px',
margin: '0 auto',
}}
>
<Section
<ImmichLayout preview="New media has been added to a shared album.">
<Text className="m-0 text-2xl">
Hey <strong>{recipientName}</strong>!
</Text>
<Text>
New media has been added to <strong>{albumName}</strong>,
<br /> check it out!
</Text>
{cid && (
<Section className="flex justify-center my-0">
<Img
className="max-w-[300px] w-full rounded-lg"
src={`cid:${cid}`}
style={{
padding: '36px',
tableLayout: 'fixed',
backgroundColor: 'rgb(226, 232, 240)',
border: 'solid 0px rgb(248 113 113)',
borderRadius: '50px',
textAlign: 'center' as const,
boxShadow: 'rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px',
}}
>
<Img
src="https://immich.app/img/immich-logo-inline-light.png"
alt="Immich"
style={{
height: 'auto',
margin: '0 auto 48px auto',
width: '50%',
alignSelf: 'center',
color: 'white',
}}
/>
/>
</Section>
)}
<Text style={text}>Hey {recipientName}!</Text>
<Section className="flex justify-center my-6">
<ImmichButton href={`${baseUrl}/albums/${albumId}`}>View Album</ImmichButton>
</Section>
<Text style={text}>
New media has been added to <strong>{albumName}</strong>, check it out!
</Text>
{cid && (
<Row>
<Column align="center">
<Img
src={`cid:${cid}`}
width="300"
style={{
borderRadius: '20px',
boxShadow: 'rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px',
}}
/>
</Column>
</Row>
)}
<Row style={{ marginBottom: '36px', marginTop: '36px' }}>
<Text style={{ ...text }}>To view the album, open the link in a browser, or click the button below.</Text>
</Row>
<Row>
<Column align="center">
<Link style={{ marginTop: '50px' }} href={`${baseUrl}/albums/${albumId}`}>
{baseUrl}/albums/{albumId}
</Link>
</Column>
</Row>
<Row>
<Column align="center">
<Button style={button} href={`${baseUrl}/albums/${albumId}`}>
View album
</Button>
</Column>
</Row>
</Section>
<Hr style={{ color: 'rgb(66, 80, 175)', marginTop: '24px' }} />
<Section style={{ textAlign: 'center' }}>
<Row>
<Column align="center">
<Link href="https://play.google.com/store/apps/details?id=app.alextran.immich">
<Img src={`https://immich.app/img/google-play-badge.png`} height="96px" alt="Immich" />
</Link>
<Link href="https://apps.apple.com/sg/app/immich/id1613945652">
<Img
src={`https://immich.app/img/ios-app-store-badge.png`}
alt="Immich"
style={{ height: '72px', padding: '14px' }}
/>
</Link>
</Column>
</Row>
</Section>
<Text
style={{
color: '#6a737d',
fontSize: '0.8rem',
textAlign: 'center' as const,
marginTop: '12px',
}}
>
<Link href="https://immich.app">Immich</Link> project is available under GNU AGPL v3 license.
</Text>
</Container>
</Body>
</Html>
<Text className="text-xs">
If you cannot click the button use the link below to view the album.
<br />
<Link href={`${baseUrl}/albums/${albumId}`}>{`${baseUrl}/albums/${albumId}`}</Link>
</Text>
</ImmichLayout>
);
AlbumUpdateEmail.PreviewProps = {
baseUrl: 'https://demo.immich.app',
albumName: 'Trip to Europe',
albumId: 'b63f6dae-e1c9-401b-9a85-9dbbf5612539',
recipientName: 'Alex Tran',
recipientName: 'Alan Turing',
} as AlbumUpdateEmailProps;
export default AlbumUpdateEmail;
const text = {
margin: '0 0 24px 0',
textAlign: 'left' as const,
fontSize: '18px',
lineHeight: '24px',
};
const button: CSS.Properties = {
backgroundColor: 'rgb(66, 80, 175)',
margin: '1em 0',
padding: '0.75em 3em',
color: '#fff',
fontSize: '1em',
fontWeight: 700,
lineHeight: 1.5,
textTransform: 'uppercase',
borderRadius: '9999px',
};

View File

@@ -0,0 +1,14 @@
import React from 'react';
import { Button, ButtonProps } from '@react-email/components';
interface ImmichButtonProps extends ButtonProps {}
export const ImmichButton = ({ children, ...props }: ImmichButtonProps) => (
<Button
{...props}
className="py-3 px-8 border bg-immich-primary rounded-full no-underline hover:no-underline text-white hover:text-gray-50 font-bold uppercase"
>
{children}
</Button>
);

View File

@@ -0,0 +1,25 @@
import { Column, Img, Link, Row, Text } from '@react-email/components';
import * as React from 'react';
export const ImmichFooter = () => (
<>
<Row className="h-18 w-full">
<Column align="center" className="w-6/12 sm:w-full">
<Link href="https://play.google.com/store/apps/details?id=app.alextran.immich">
<Img className="h-full max-w-full" src={`https://immich.app/img/google-play-badge.png`} />
</Link>
</Column>
<Column align="center" className="w-6/12 sm:w-full">
<div className="h-full p-3">
<Link href="https://apps.apple.com/sg/app/immich/id1613945652">
<Img src={`https://immich.app/img/ios-app-store-badge.png`} alt="Immich" className="max-w-full" />
</Link>
</div>
</Column>
</Row>
<Text className="text-center text-sm text-immich-footer">
<Link href="https://immich.app">Immich</Link> project is available under GNU AGPL v3 license.
</Text>
</>
);

View File

@@ -0,0 +1,102 @@
import {
Body,
Container,
Font,
Head,
Hr,
Html,
Img,
Link,
Preview,
Section,
Tailwind,
Text,
} from '@react-email/components';
import * as React from 'react';
import { ImmichFooter } from './footer.template';
interface FutoLayoutProps {
children: React.ReactNode;
preview: string;
}
export const FutoLayout = ({ children, preview }: FutoLayoutProps) => (
<Html>
<Tailwind
config={{
presets: [require('tailwindcss-preset-email')],
theme: {
extend: {
colors: {
// Light Theme
'immich-primary': '#4250AF',
'futo-primary': '#000000',
'futo-bg': '#F4F4f4',
'futo-gray': '#F6F6F4',
'futo-footer': '#6A737D',
},
fontFamily: {
sans: ['Overpass', 'sans-serif'],
mono: ['Overpass Mono', 'monospace'],
},
},
},
}}
>
<Head>
<Font
fontFamily="Overpass"
fallbackFontFamily="sans-serif"
webFont={{
url: 'https://fonts.gstatic.com/s/overpass/v13/qFdH35WCmI96Ajtm81GrU9vyww.woff2',
format: 'woff2',
}}
fontWeight={'100 900'}
fontStyle="normal"
/>
</Head>
<Preview>{preview}</Preview>
<Body className="bg-futo-bg my-auto mx-auto px-2 font-sans text-base text-futo-primary">
<Container className="my-[40px] mx-auto max-w-[465px]">
<Section className="my-6 p-12 border border-red-400 rounded-[50px] bg-gray-50">
<Section className="flex justify-center mb-12">
<Img
src="https://immich.app/img/immich-logo-inline-light.png"
className="h-12 antialiased rounded-none"
alt="Immich"
/>
</Section>
{children}
</Section>
<Section className="flex justify-center my-6">
<Link href="https://futo.org">
<Img
className="h-6"
src="https://futo.org/images/FutoMainLogo.svg"
alt="FUTO"
// style={{
// height: '24px',
// marginTop: '25px',
// marginBottom: '25px',
// }}
/>
</Link>
</Section>
<Hr className="my-2 text-futo-gray" />
<ImmichFooter />
</Container>
</Body>
</Tailwind>
</Html>
);
FutoLayout.PreviewProps = {
preview: 'This is the preview shown on some mail clients',
children: <Text>Email body goes here.</Text>,
} as FutoLayoutProps;
export default FutoLayout;

View File

@@ -0,0 +1,74 @@
import { Body, Container, Font, Head, Hr, Html, Img, Preview, Section, Tailwind, Text } from '@react-email/components';
import * as React from 'react';
import { ImmichFooter } from './footer.template';
interface ImmichLayoutProps {
children: React.ReactNode;
preview: string;
}
export const ImmichLayout = ({ children, preview }: ImmichLayoutProps) => (
<Html>
<Tailwind
config={{
presets: [require('tailwindcss-preset-email')],
theme: {
extend: {
colors: {
// Light Theme
'immich-primary': '#4250AF',
'immich-bg': 'white',
'immich-fg': 'black',
'immich-gray': '#F6F6F4',
'immich-footer': '#6A737D',
},
fontFamily: {
sans: ['Overpass', 'sans-serif'],
mono: ['Overpass Mono', 'monospace'],
},
},
},
}}
>
<Head>
<Font
fontFamily="Overpass"
fallbackFontFamily="sans-serif"
webFont={{
url: 'https://fonts.gstatic.com/s/overpass/v13/qFdH35WCmI96Ajtm81GrU9vyww.woff2',
format: 'woff2',
}}
fontWeight={'100 900'}
fontStyle="normal"
/>
</Head>
<Preview>{preview}</Preview>
<Body className="my-auto mx-auto px-2 font-sans text-base text-immich-primary">
<Container className="my-[40px] mx-auto max-w-[465px]">
<Section className="my-6 p-12 border border-red-400 rounded-[50px] bg-slate-200">
<Section className="flex justify-center mb-12">
<Img
src="https://immich.app/img/immich-logo-inline-light.png"
className="h-12 antialiased rounded-none"
alt="Immich"
/>
</Section>
{children}
</Section>
<Hr className="my-2 text-immich-gray" />
<ImmichFooter />
</Container>
</Body>
</Tailwind>
</Html>
);
ImmichLayout.PreviewProps = {
preview: 'This is the preview shown on some mail clients',
children: <Text>Email body goes here.</Text>,
} as ImmichLayoutProps;
export default ImmichLayout;

View File

@@ -15,172 +15,50 @@ import {
} from '@react-email/components';
import * as CSS from 'csstype';
import * as React from 'react';
import { ImmichButton } from './components/button.component';
import FutoLayout from './components/futo.layout';
/**
* Template to be used for FUTOPay project
* Variable is {{LICENSEKEY}}
* */
export const LicenseEmail = () => (
<Html>
<Head />
<Preview>Your Immich Server License</Preview>
<Body
style={{
margin: 0,
padding: 0,
backgroundColor: '#f4f4f4',
color: 'rgb(28,28,28)',
fontFamily: 'Overpass, sans-serif',
fontSize: '18px',
lineHeight: '24px',
}}
>
<Container
style={{
width: '540px',
maxWidth: '100%',
padding: '10px',
margin: '0 auto',
}}
<FutoLayout preview="Your Immich Server License">
<Text>Thank you for supporting Immich and open-source software</Text>
<Text>
Your <strong>Immich</strong> license key is
</Text>
<Section className="my-2 bg-gray-200 rounded-2xl text-center p-4">
<Text className="m-0 text-monospace font-bold text-immich-primary">{'{{LICENSEKEY}}'}</Text>
</Section>
{/* <Text>
To activate your instance, you can click the following button or copy and paste the link below to your browser.
</Text>
<Section className="flex justify-center my-6">
<ImmichButton
href={`https://my.immich.app/link?target=activate_license&licenseKey={{LICENSEKEY}}&activationKey={{ACTIVATIONKEY}}`}
>
<Section
style={{
padding: '36px',
tableLayout: 'fixed',
backgroundColor: '#fefefe',
borderRadius: '16px',
textAlign: 'center' as const,
}}
>
<Img
src="https://immich.app/img/immich-logo-inline-light.png"
alt="Immich"
style={{
height: 'auto',
margin: '0 auto 48px auto',
width: '50%',
alignSelf: 'center',
color: 'white',
}}
/>
Activate
</ImmichButton>
</Section>
<Text style={text}>Thank you for supporting Immich and open-source software</Text>
<Text style={text}>
Your <strong>Immich</strong> license key is
</Text>
<Section
style={{
textAlign: 'center',
background: 'rgb(225, 225, 225)',
borderRadius: '16px',
marginBottom: '25px',
}}
>
<Text style={{ fontFamily: 'monospace', fontWeight: 600, color: 'rgb(66, 80, 175)' }}>
{'{{LICENSEKEY}}'}
</Text>
</Section>
{/* <Text style={text}>
To activate your instance, you can click the following button or copy and paste the link below to your
browser
</Text>
<Row>
<Column align="center">
<Button
style={button}
href={`https://my.immich.app/link?target=activate_license&licenseKey={{LICENSEKEY}}&activationKey={{ACTIVATIONKEY}}`}
>
Activate
</Button>
</Column>
</Row>
<Row>
<Column align="center">
<a
style={{ marginTop: '50px', color: 'rgb(66, 80, 175)', fontSize: '0.9rem' }}
href={`https://my.immich.app/link?target=activate_license&licenseKey={{LICENSEKEY}}&activationKey={{ACTIVATIONKEY}}`}
>
https://my.immich.app/link?target=activate_license&licenseKey={'{{LICENSEKEY}}'}&activationKey=
{'{{ACTIVATIONKEY}}'}
</a>
</Column>
</Row> */}
</Section>
<Section style={{ textAlign: 'center' }}>
<Row>
<Column align="center">
<Link href="https://futo.org">
<Img
src="https://futo.org/images/FutoMainLogo.svg"
alt="FUTO"
style={{
height: '24px',
marginTop: '25px',
marginBottom: '25px',
}}
/>
</Link>
</Column>
</Row>
</Section>
<Hr style={{ color: 'rgb(66, 80, 175)', marginTop: '0' }} />
<Section style={{ textAlign: 'center' }}>
<Column align="center">
<Link href="https://apps.apple.com/sg/app/immich/id1613945652">
<Img
src={`https://immich.app/img/ios-app-store-badge.png`}
alt="Immich"
style={{ height: '72px', padding: '14px' }}
/>
</Link>
<Link href="https://play.google.com/store/apps/details?id=app.alextran.immich">
<Img src={`https://immich.app/img/google-play-badge.png`} height="96px" alt="Immich" />
</Link>
</Column>
</Section>
<Text
style={{
color: '#6a737d',
fontSize: '0.8rem',
textAlign: 'center' as const,
marginTop: '14px',
}}
>
<Link href="https://immich.app">Immich</Link> project is available under GNU AGPL v3 license.
</Text>
</Container>
</Body>
</Html>
<Text className="text-center">
<Link
className="text-immich-primary text-sm"
// style={{ marginTop: '50px', color: 'rgb(66, 80, 175)', fontSize: '0.9rem' }}
href={`https://my.immich.app/link?target=activate_license&licenseKey={{LICENSEKEY}}&activationKey={{ACTIVATIONKEY}}`}
>
https://my.immich.app/link?target=activate_license&licenseKey={'{{LICENSEKEY}}'}&activationKey=
{'{{ACTIVATIONKEY}}'}
</Link>
</Text> */}
</FutoLayout>
);
LicenseEmail.PreviewProps = {};
export default LicenseEmail;
const text = {
margin: '0 0 24px 0',
textAlign: 'left' as const,
fontSize: '16px',
lineHeight: '24px',
};
const button: CSS.Properties = {
backgroundColor: 'rgb(66, 80, 175)',
margin: '1em 0',
padding: '0.75em 3em',
color: '#fff',
fontSize: '1em',
fontWeight: 600,
lineHeight: 1.5,
textTransform: 'uppercase',
borderRadius: '9999px',
};

View File

@@ -1,134 +1,25 @@
import {
Body,
Button,
Column,
Container,
Head,
Hr,
Html,
Img,
Link,
Preview,
Row,
Section,
Text,
} from '@react-email/components';
import * as CSS from 'csstype';
import { Link, Row, Text } from '@react-email/components';
import * as React from 'react';
import { TestEmailProps } from 'src/interfaces/notification.interface';
import ImmichLayout from './components/immich.layout';
export const TestEmail = ({ baseUrl, displayName }: TestEmailProps) => (
<Html>
<Head />
<Preview>This is a test email from Immich</Preview>
<Body
style={{
margin: 0,
padding: 0,
backgroundColor: '#ffffff',
color: 'rgb(66, 80, 175)',
fontFamily: 'Overpass, sans-serif',
fontSize: '18px',
lineHeight: '24px',
}}
>
<Container
style={{
width: '480px',
maxWidth: '100%',
padding: '10px',
margin: '0 auto',
}}
>
<Section
style={{
padding: '36px',
tableLayout: 'fixed',
backgroundColor: 'rgb(226, 232, 240)',
border: 'solid 0px rgb(248 113 113)',
borderRadius: '50px',
textAlign: 'center' as const,
}}
>
<Img
src="https://immich.app/img/immich-logo-inline-light.png"
alt="Immich"
style={{
height: 'auto',
margin: '0 auto 48px auto',
width: '50%',
alignSelf: 'center',
color: 'white',
}}
/>
<ImmichLayout preview="This is a test email from Immich.">
<Text className="m-0 text-2xl">
Hey <strong>{displayName}</strong>!
</Text>
<Text style={text}>
Hey <strong>{displayName}</strong>, this is the test email from your Immich Instance
</Text>
<Text>This is a test email from your Immich Instance!</Text>
<Row>
<Link style={{ marginTop: '50px' }} href={baseUrl}>
{baseUrl}
</Link>
</Row>
</Section>
<Hr style={{ color: 'rgb(66, 80, 175)', marginTop: '24px' }} />
<Section style={{ textAlign: 'center' }}>
<Row>
<Column align="center">
<Link href="https://play.google.com/store/apps/details?id=app.alextran.immich">
<Img src={`https://immich.app/img/google-play-badge.png`} height="96px" alt="Immich" />
</Link>
<Link href="https://apps.apple.com/sg/app/immich/id1613945652">
<Img
src={`https://immich.app/img/ios-app-store-badge.png`}
alt="Immich"
style={{ height: '72px', padding: '14px' }}
/>
</Link>
</Column>
</Row>
</Section>
<Text
style={{
color: '#6a737d',
fontSize: '0.8rem',
textAlign: 'center' as const,
marginTop: '12px',
}}
>
<Link href="https://immich.app">Immich</Link> project is available under GNU AGPL v3 license.
</Text>
</Container>
</Body>
</Html>
<Row>
<Link href={baseUrl}>{baseUrl}</Link>
</Row>
</ImmichLayout>
);
TestEmail.PreviewProps = {
baseUrl: 'https://demo.immich.app/auth/login',
baseUrl: 'https://demo.immich.app',
displayName: 'Alan Turing',
} as TestEmailProps;
export default TestEmail;
const text = {
margin: '0 0 24px 0',
textAlign: 'left' as const,
fontSize: '18px',
lineHeight: '24px',
};
const button: CSS.Properties = {
backgroundColor: 'rgb(66, 80, 175)',
margin: '1em 0',
padding: '0.75em 3em',
color: '#fff',
fontSize: '1em',
fontWeight: 700,
lineHeight: 1.5,
textTransform: 'uppercase',
borderRadius: '9999px',
};

View File

@@ -1,132 +1,37 @@
import {
Body,
Button,
Column,
Container,
Head,
Hr,
Html,
Img,
Link,
Preview,
Row,
Section,
Text,
} from '@react-email/components';
import * as CSS from 'csstype';
import { Link, Section, Text } from '@react-email/components';
import * as React from 'react';
import { WelcomeEmailProps } from 'src/interfaces/notification.interface';
import { ImmichButton } from './components/button.component';
import ImmichLayout from './components/immich.layout';
export const WelcomeEmail = ({ baseUrl, displayName, username, password }: WelcomeEmailProps) => (
<Html>
<Head />
<Preview>You have been invited to a new Immich instance.</Preview>
<Body
style={{
margin: 0,
padding: 0,
backgroundColor: '#ffffff',
color: 'rgb(66, 80, 175)',
fontFamily: 'Overpass, sans-serif',
fontSize: '18px',
lineHeight: '24px',
}}
>
<Container
style={{
width: '480px',
maxWidth: '100%',
padding: '10px',
margin: '0 auto',
}}
>
<Section
style={{
padding: '36px',
tableLayout: 'fixed',
backgroundColor: 'rgb(226, 232, 240)',
border: 'solid 0px rgb(248 113 113)',
borderRadius: '50px',
textAlign: 'center' as const,
}}
>
<Img
src="https://immich.app/img/immich-logo-inline-light.png"
alt="Immich"
style={{
height: 'auto',
margin: '0 auto 48px auto',
width: '50%',
alignSelf: 'center',
color: 'white',
}}
/>
<ImmichLayout preview="You have been invited to a new Immich instance.">
<Text className="m-0 text-2xl">
Hey <strong>{displayName}</strong>!
</Text>
<Text style={text}>
Hey <strong>{displayName}</strong>!
</Text>
<Text>A new account has been created for you.</Text>
<Text style={text}>A new account has been created for you.</Text>
<Text>
<strong>Username</strong>: {username}
{password && (
<>
<br />
<strong>Password</strong>: {password}
</>
)}
</Text>
<Text style={text}>
<strong>Username</strong>: {username}
{password && (
<>
<br />
<strong>Password</strong>: {password}
</>
)}
</Text>
<Section className="flex justify-center my-6">
<ImmichButton href={`${baseUrl}/auth/login`}>Login</ImmichButton>
</Section>
<Row>
<Text style={{ ...text, marginBottom: '36px' }}>
To login, open the link in a browser, or click the button below.
</Text>
</Row>
<Row>
<Link style={{ marginTop: '50px' }} href={baseUrl}>
{baseUrl}
</Link>
</Row>
<Row>
<Button style={button} href={`${baseUrl}/auth/login`}>
Login
</Button>
</Row>
</Section>
<Hr style={{ color: 'rgb(66, 80, 175)', marginTop: '24px' }} />
<Section style={{ textAlign: 'center' }}>
<Row>
<Column align="center">
<Link href="https://play.google.com/store/apps/details?id=app.alextran.immich">
<Img src={`https://immich.app/img/google-play-badge.png`} height="96px" alt="Immich" />
</Link>
<Link href="https://apps.apple.com/sg/app/immich/id1613945652">
<Img
src={`https://immich.app/img/ios-app-store-badge.png`}
alt="Immich"
style={{ height: '72px', padding: '14px' }}
/>
</Link>
</Column>
</Row>
</Section>
<Text
style={{
color: '#6a737d',
fontSize: '0.8rem',
textAlign: 'center' as const,
marginTop: '12px',
}}
>
<Link href="https://immich.app">Immich</Link> project is available under GNU AGPL v3 license.
</Text>
</Container>
</Body>
</Html>
<Text className="text-xs">
If you cannot click the button use the link below to proceed with first login.
<br />
<Link href={baseUrl}>{baseUrl}</Link>
</Text>
</ImmichLayout>
);
WelcomeEmail.PreviewProps = {
@@ -137,22 +42,3 @@ WelcomeEmail.PreviewProps = {
} as WelcomeEmailProps;
export default WelcomeEmail;
const text = {
margin: '0 0 24px 0',
textAlign: 'left' as const,
fontSize: '18px',
lineHeight: '24px',
};
const button: CSS.Properties = {
backgroundColor: 'rgb(66, 80, 175)',
margin: '1em 0',
padding: '0.75em 3em',
color: '#fff',
fontSize: '1em',
fontWeight: 700,
lineHeight: 1.5,
textTransform: 'uppercase',
borderRadius: '9999px',
};