Skip to content

Commit 669b8f1

Browse files
authored
Merge pull request #3524 from SeedCompany/email-refresh
2 parents c67339e + 251bfef commit 669b8f1

File tree

4 files changed

+47
-21
lines changed

4 files changed

+47
-21
lines changed

src/core/config/config.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export const makeConfig = (env: EnvironmentService) =>
149149
.string('DEFAULT_TIMEZONE')
150150
.optional('America/Chicago');
151151

152-
frontendUrl = env.string('FRONTEND_URL').optional('http://localhost:3001');
152+
frontendUrl = env.url('FRONTEND_URL').optional('http://localhost:3001');
153153

154154
neo4j = (() => {
155155
const driverConfig: Neo4JDriverConfig = {};

src/core/email/templates/base.tsx

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,63 @@ import {
77
Divider,
88
Font,
99
Head,
10+
HideInText,
1011
Image,
1112
InText,
1213
Mjml,
14+
Preview,
1315
Raw,
1416
Section,
1517
Style,
1618
Text,
1719
Title,
1820
Wrapper,
1921
} from '@seedcompany/nestjs-email/templates';
20-
import type { ComponentProps, ReactElement, ReactNode } from 'react';
22+
import {
23+
type ComponentProps,
24+
Fragment,
25+
type ReactElement,
26+
type ReactNode,
27+
} from 'react';
2128
import { useFrontendUrl } from './frontend-url';
2229

2330
export const EmailTemplate = ({
2431
title,
32+
preview,
2533
children,
2634
}: {
2735
title: string;
36+
preview?: ReactNode;
2837
children: ReactNode;
2938
}) => (
3039
<Mjml lang="en">
3140
<Head>
32-
<Title>{`${title} - CORD Field`}</Title>
41+
<Title>{title}</Title>
42+
{preview != null && (
43+
<HideInText>
44+
<Preview>
45+
{preview}
46+
{/* Fill the remaining space with nothing-ness so the email context is avoided */}
47+
{[...Array(140).keys()].map((i) => (
48+
<Fragment key={i}>&#847;&zwnj;&nbsp;</Fragment>
49+
))}
50+
</Preview>
51+
</HideInText>
52+
)}
3353
<Theme />
3454
<Style
3555
inline
3656
children={`
57+
.body {
58+
/* prevents card shadow being cut off */
59+
padding: 8px;
60+
/* add more just to look more symmetrical with branding header */
61+
padding-bottom: 48px;
62+
}
3763
.card-shadow {
38-
-webkit-box-shadow: 0px 5px 5px -3px rgba(0,0,0,0.2), 0px 8px 10px 1px rgba(0,0,0,0.14), 0px 3px 14px 2px rgba(0,0,0,0.12);
39-
-moz-box-shadow: 0px 5px 5px -3px rgba(0,0,0,0.2), 0px 8px 10px 1px rgba(0,0,0,0.14), 0px 3px 14px 2px rgba(0,0,0,0.12);
40-
box-shadow: 0px 5px 5px -3px rgba(0,0,0,0.2), 0px 8px 10px 1px rgba(0,0,0,0.14), 0px 3px 14px 2px rgba(0,0,0,0.12);
64+
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0px 3px 1px -2px, rgba(0, 0, 0, 0.14) 0px 2px 2px 0px, rgba(0, 0, 0, 0.12) 0px 1px 5px 0px;
65+
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0px 3px 1px -2px, rgba(0, 0, 0, 0.14) 0px 2px 2px 0px, rgba(0, 0, 0, 0.12) 0px 1px 5px 0px;
66+
box-shadow: rgba(0, 0, 0, 0.2) 0px 3px 1px -2px, rgba(0, 0, 0, 0.14) 0px 2px 2px 0px, rgba(0, 0, 0, 0.12) 0px 1px 5px 0px;
4167
}
4268
.button-shadow td {
4369
-webkit-box-shadow: 0px 3px 1px -2px rgba(0,0,0,0.2), 0px 2px 2px 0px rgba(0,0,0,0.14), 0px 1px 5px 0px rgba(0,0,0,0.12);
@@ -48,7 +74,9 @@ export const EmailTemplate = ({
4874
/>
4975
</Head>
5076
<Body>
51-
<Branding />
77+
<HideInText>
78+
<Branding />
79+
</HideInText>
5280

5381
<Wrapper
5482
cssClass="card-shadow"
@@ -65,15 +93,15 @@ export const Theme = () => (
6593
<>
6694
<Font name="sofia-pro" href="https://use.typekit.net/qrd6jxb.css" />
6795
<Attributes>
68-
<All fontFamily="sofia-pro" fontSize="16px" />
69-
<Body width={600} backgroundColor="#fafafa">
96+
<All fontFamily="sofia-pro, sans-serif" fontSize="16px" />
97+
<Body width={600} backgroundColor="#fafafa" cssClass="body">
7098
{[]}
7199
</Body>
72100
<Section backgroundColor="#ffffff">{}</Section>
73101
<Text lineHeight="1.5">{}</Text>
74102
<Button
75103
color="#ffffff"
76-
backgroundColor="#64b145"
104+
backgroundColor="#1ea973"
77105
padding="8px 22px"
78106
cssClass="button-shadow"
79107
>
@@ -90,7 +118,7 @@ export const Theme = () => (
90118
);
91119

92120
export const Branding = (): ReactElement => {
93-
const iconUrl = useFrontendUrl('/images/web-app-manifest-192x192.png');
121+
const iconUrl = useFrontendUrl('/images/cord-icon.png');
94122
return (
95123
<Section backgroundColor="#fafafa">
96124
<Column verticalAlign="middle" width="80px">
@@ -104,7 +132,7 @@ export const Branding = (): ReactElement => {
104132
</Column>
105133
<Column verticalAlign="middle" width="220px">
106134
<Text fontSize={32} align="center">
107-
CORD Field
135+
<span style={{ whiteSpace: 'nowrap !important' }}>CORD Field</span>
108136
</Text>
109137
</Column>
110138
<TextBreak />

src/core/email/templates/forgot-password.template.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,12 @@ export interface ForgotPasswordProps {
1616
export function ForgotPassword({ token }: ForgotPasswordProps) {
1717
const url = useFrontendUrl(`/reset-password/${token}`);
1818
return (
19-
<EmailTemplate title="Forgot Password">
20-
<Heading>You have submitted a password change request!</Heading>
19+
<EmailTemplate title="Reset Password" preview={null}>
20+
<Heading>We received your password reset request</Heading>
2121

2222
<Section>
2323
<Column>
24-
<Text>
25-
If it was you, confirm the password change{' '}
26-
<InText>by clicking this link</InText>
27-
</Text>
24+
<Text align="center">If it was you, create a new password here</Text>
2825
<HideInText>
2926
<Button href={url}>CONFIRM</Button>
3027
</HideInText>
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import { createContext, type ReactElement, useContext } from 'react';
22
import { ServerException } from '~/common/exceptions';
33

4-
const FrontendUrlContext = createContext<string | undefined>(undefined);
4+
const FrontendUrlContext = createContext<Readonly<URL> | undefined>(undefined);
55

66
export const useFrontendUrl = (path: string) => {
77
const base = useContext(FrontendUrlContext);
88
if (!base) {
99
throw new ServerException('Frontend url has not been provided');
1010
}
11-
return base + path;
11+
path = path.startsWith('/') ? path.slice(1) : path;
12+
return new URL(path, base).toString();
1213
};
1314

14-
export const FrontendUrlWrapper = (url: string) => (el: ReactElement) =>
15+
export const FrontendUrlWrapper = (url: Readonly<URL>) => (el: ReactElement) =>
1516
<FrontendUrlContext.Provider value={url}>{el}</FrontendUrlContext.Provider>;

0 commit comments

Comments
 (0)