mirror of
https://github.com/immich-app/immich.git
synced 2024-11-15 18:08:48 -07:00
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:
parent
a444ea7361
commit
ee6f1a010c
175
server/package-lock.json
generated
175
server/package-lock.json
generated
@ -60,6 +60,7 @@
|
||||
"semver": "^7.6.2",
|
||||
"sharp": "^0.33.0",
|
||||
"sirv": "^2.0.4",
|
||||
"tailwindcss-preset-email": "^1.3.2",
|
||||
"thumbhash": "^0.1.1",
|
||||
"typeorm": "^0.3.17",
|
||||
"ua-parser-js": "^1.0.35"
|
||||
@ -13831,6 +13832,11 @@
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
|
||||
},
|
||||
"node_modules/react-email/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
@ -13981,6 +13987,53 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/tailwindcss": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz",
|
||||
"integrity": "sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA==",
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"arg": "^5.0.2",
|
||||
"chokidar": "^3.5.3",
|
||||
"didyoumean": "^1.2.2",
|
||||
"dlv": "^1.1.3",
|
||||
"fast-glob": "^3.3.0",
|
||||
"glob-parent": "^6.0.2",
|
||||
"is-glob": "^4.0.3",
|
||||
"jiti": "^1.19.1",
|
||||
"lilconfig": "^2.1.0",
|
||||
"micromatch": "^4.0.5",
|
||||
"normalize-path": "^3.0.0",
|
||||
"object-hash": "^3.0.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"postcss": "^8.4.23",
|
||||
"postcss-import": "^15.1.0",
|
||||
"postcss-js": "^4.0.1",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"postcss-selector-parser": "^6.0.11",
|
||||
"resolve": "^1.22.2",
|
||||
"sucrase": "^3.32.0"
|
||||
},
|
||||
"bin": {
|
||||
"tailwind": "lib/cli.js",
|
||||
"tailwindcss": "lib/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/tailwindcss/node_modules/glob-parent": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/typescript": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
|
||||
@ -15507,9 +15560,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz",
|
||||
"integrity": "sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA==",
|
||||
"version": "3.4.6",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.6.tgz",
|
||||
"integrity": "sha512-1uRHzPB+Vzu57ocybfZ4jh5Q3SdlH7XW23J5sQoM9LhE9eIOlzxer/3XPSsycvih3rboRsvt0QCmzSrqyOYUIA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"arg": "^5.0.2",
|
||||
@ -15519,7 +15573,7 @@
|
||||
"fast-glob": "^3.3.0",
|
||||
"glob-parent": "^6.0.2",
|
||||
"is-glob": "^4.0.3",
|
||||
"jiti": "^1.19.1",
|
||||
"jiti": "^1.21.0",
|
||||
"lilconfig": "^2.1.0",
|
||||
"micromatch": "^4.0.5",
|
||||
"normalize-path": "^3.0.0",
|
||||
@ -15542,15 +15596,48 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss-email-variants": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss-email-variants/-/tailwindcss-email-variants-3.0.1.tgz",
|
||||
"integrity": "sha512-bRk4R2jnfaW7BBaL2kDgOdBl0SpVP/JPDE/yCkZb1n3YrPK9ZQyQGZoVX3OX06GxjMOrNO3wZACVdHJce7dm8w==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">=3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss-mso": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss-mso/-/tailwindcss-mso-1.4.3.tgz",
|
||||
"integrity": "sha512-8YfZ4xnIComDrhoSr8FUwm7EGz1FkxsZy07Fs4Jm/JxHrFiubdiZjyxLuHMc3S8o02+U4fjRGHPOzoVXRus10A==",
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">=3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss-preset-email": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss-preset-email/-/tailwindcss-preset-email-1.3.2.tgz",
|
||||
"integrity": "sha512-kSPNZM5+tSi+uhCb4rk1XF9Q6zp8lhoNLCa3GQqe6gKmfI/nTqY8Y+5/DYNpwqhmUPCSHULlyI/LUCaF/q8sLg==",
|
||||
"dependencies": {
|
||||
"tailwindcss-email-variants": "^3.0.0",
|
||||
"tailwindcss-mso": "^1.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">=3.4.6"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss/node_modules/arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/tailwindcss/node_modules/glob-parent": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.3"
|
||||
},
|
||||
@ -26373,6 +26460,11 @@
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
@ -26476,6 +26568,45 @@
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
|
||||
},
|
||||
"tailwindcss": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz",
|
||||
"integrity": "sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA==",
|
||||
"requires": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"arg": "^5.0.2",
|
||||
"chokidar": "^3.5.3",
|
||||
"didyoumean": "^1.2.2",
|
||||
"dlv": "^1.1.3",
|
||||
"fast-glob": "^3.3.0",
|
||||
"glob-parent": "^6.0.2",
|
||||
"is-glob": "^4.0.3",
|
||||
"jiti": "^1.19.1",
|
||||
"lilconfig": "^2.1.0",
|
||||
"micromatch": "^4.0.5",
|
||||
"normalize-path": "^3.0.0",
|
||||
"object-hash": "^3.0.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"postcss": "^8.4.23",
|
||||
"postcss-import": "^15.1.0",
|
||||
"postcss-js": "^4.0.1",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"postcss-selector-parser": "^6.0.11",
|
||||
"resolve": "^1.22.2",
|
||||
"sucrase": "^3.32.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"glob-parent": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"requires": {
|
||||
"is-glob": "^4.0.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
|
||||
@ -27591,9 +27722,10 @@
|
||||
}
|
||||
},
|
||||
"tailwindcss": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.0.tgz",
|
||||
"integrity": "sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA==",
|
||||
"version": "3.4.6",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.6.tgz",
|
||||
"integrity": "sha512-1uRHzPB+Vzu57ocybfZ4jh5Q3SdlH7XW23J5sQoM9LhE9eIOlzxer/3XPSsycvih3rboRsvt0QCmzSrqyOYUIA==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"arg": "^5.0.2",
|
||||
@ -27603,7 +27735,7 @@
|
||||
"fast-glob": "^3.3.0",
|
||||
"glob-parent": "^6.0.2",
|
||||
"is-glob": "^4.0.3",
|
||||
"jiti": "^1.19.1",
|
||||
"jiti": "^1.21.0",
|
||||
"lilconfig": "^2.1.0",
|
||||
"micromatch": "^4.0.5",
|
||||
"normalize-path": "^3.0.0",
|
||||
@ -27622,18 +27754,41 @@
|
||||
"arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
|
||||
"peer": true
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"is-glob": "^4.0.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tailwindcss-email-variants": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss-email-variants/-/tailwindcss-email-variants-3.0.1.tgz",
|
||||
"integrity": "sha512-bRk4R2jnfaW7BBaL2kDgOdBl0SpVP/JPDE/yCkZb1n3YrPK9ZQyQGZoVX3OX06GxjMOrNO3wZACVdHJce7dm8w==",
|
||||
"requires": {}
|
||||
},
|
||||
"tailwindcss-mso": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss-mso/-/tailwindcss-mso-1.4.3.tgz",
|
||||
"integrity": "sha512-8YfZ4xnIComDrhoSr8FUwm7EGz1FkxsZy07Fs4Jm/JxHrFiubdiZjyxLuHMc3S8o02+U4fjRGHPOzoVXRus10A==",
|
||||
"requires": {}
|
||||
},
|
||||
"tailwindcss-preset-email": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss-preset-email/-/tailwindcss-preset-email-1.3.2.tgz",
|
||||
"integrity": "sha512-kSPNZM5+tSi+uhCb4rk1XF9Q6zp8lhoNLCa3GQqe6gKmfI/nTqY8Y+5/DYNpwqhmUPCSHULlyI/LUCaF/q8sLg==",
|
||||
"requires": {
|
||||
"tailwindcss-email-variants": "^3.0.0",
|
||||
"tailwindcss-mso": "^1.4.3"
|
||||
}
|
||||
},
|
||||
"tapable": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
||||
|
@ -86,6 +86,7 @@
|
||||
"semver": "^7.6.2",
|
||||
"sharp": "^0.33.0",
|
||||
"sirv": "^2.0.4",
|
||||
"tailwindcss-preset-email": "^1.3.2",
|
||||
"thumbhash": "^0.1.1",
|
||||
"typeorm": "^0.3.17",
|
||||
"ua-parser-js": "^1.0.35"
|
||||
|
@ -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',
|
||||
};
|
||||
|
@ -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',
|
||||
};
|
||||
|
14
server/src/emails/components/button.component.tsx
Normal file
14
server/src/emails/components/button.component.tsx
Normal 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>
|
||||
);
|
25
server/src/emails/components/footer.template.tsx
Normal file
25
server/src/emails/components/footer.template.tsx
Normal 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>
|
||||
</>
|
||||
);
|
102
server/src/emails/components/futo.layout.tsx
Normal file
102
server/src/emails/components/futo.layout.tsx
Normal 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;
|
74
server/src/emails/components/immich.layout.tsx
Normal file
74
server/src/emails/components/immich.layout.tsx
Normal 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;
|
@ -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',
|
||||
};
|
||||
|
@ -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',
|
||||
};
|
||||
|
@ -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',
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user