Added email templating, and user welcome email
This commit is contained in:
52
server/emails/WelcomeEmail.js
Normal file
52
server/emails/WelcomeEmail.js
Normal file
@@ -0,0 +1,52 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import EmailTemplate from './components/EmailLayout';
|
||||
import Body from './components/Body';
|
||||
import Button from './components/Button';
|
||||
import Footer from './components/Footer';
|
||||
import EmptySpace from './components/EmptySpace';
|
||||
|
||||
export const welcomeEmailText = `
|
||||
Welcome to Outline!
|
||||
|
||||
Outline is a place for your team to build and share knowledge.
|
||||
|
||||
To get started, head to your dashboard and try creating a collection to help document your workflow, create playbooks or help with team onboarding.
|
||||
|
||||
You can also import existing Markdown document by drag and dropping them to your collections
|
||||
|
||||
${process.env.URL}/dashboard
|
||||
`;
|
||||
|
||||
export const WelcomeEmail = () => {
|
||||
return (
|
||||
<EmailTemplate>
|
||||
<Body>
|
||||
<p>
|
||||
<strong>Welcome to Outline!</strong>
|
||||
</p>
|
||||
|
||||
<p>Outline is a place for your team to build and share knowledge.</p>
|
||||
<p>
|
||||
To get started, head to your dashboard and try creating a collection
|
||||
to help document your workflow, create playbooks or help with team
|
||||
onboarding.
|
||||
</p>
|
||||
<p>
|
||||
You can also import existing Markdown document by drag and dropping
|
||||
them to your collections
|
||||
</p>
|
||||
|
||||
<EmptySpace height={10} />
|
||||
|
||||
<p>
|
||||
<Button href={`${process.env.URL}/dashboard`}>
|
||||
View my dashboard
|
||||
</Button>
|
||||
</p>
|
||||
</Body>
|
||||
|
||||
<Footer />
|
||||
</EmailTemplate>
|
||||
);
|
||||
};
|
||||
25
server/emails/components/Body.js
Normal file
25
server/emails/components/Body.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import { Table, TBody, TR, TD } from 'oy-vey';
|
||||
|
||||
import EmptySpace from './EmptySpace';
|
||||
|
||||
type Props = {
|
||||
children: React$Element<*>,
|
||||
};
|
||||
|
||||
export default ({ children }: Props) => {
|
||||
return (
|
||||
<Table width="100%">
|
||||
<TBody>
|
||||
<TR>
|
||||
<TD>
|
||||
<EmptySpace height={40} />
|
||||
{children}
|
||||
<EmptySpace height={40} />
|
||||
</TD>
|
||||
</TR>
|
||||
</TBody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
17
server/emails/components/Button.js
Normal file
17
server/emails/components/Button.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
|
||||
export default (props: { href: string, children: React.Element<*> }) => {
|
||||
const style = {
|
||||
display: 'inline-block',
|
||||
padding: '10px 20px',
|
||||
color: '#FFFFFF',
|
||||
background: '#000000',
|
||||
borderRadius: '4px',
|
||||
fontWeight: 500,
|
||||
textDecoration: 'none',
|
||||
cursor: 'pointer',
|
||||
};
|
||||
|
||||
return <a {...props} style={style} />;
|
||||
};
|
||||
26
server/emails/components/EmailLayout.js
Normal file
26
server/emails/components/EmailLayout.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import { Table, TBody, TR, TD } from 'oy-vey';
|
||||
import { fonts } from '../../../shared/styles/constants';
|
||||
|
||||
type Props = {
|
||||
children: React$Element<*>,
|
||||
};
|
||||
|
||||
export default (props: Props) => (
|
||||
<Table width="550" padding="40">
|
||||
<TBody>
|
||||
<TR>
|
||||
<TD align="left">{props.children}</TD>
|
||||
</TR>
|
||||
</TBody>
|
||||
</Table>
|
||||
);
|
||||
|
||||
export const baseStyles = `
|
||||
#__bodyTable__ {
|
||||
font-family: ${fonts.regular};
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
`;
|
||||
29
server/emails/components/EmptySpace.js
Normal file
29
server/emails/components/EmptySpace.js
Normal file
@@ -0,0 +1,29 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import { Table, TBody, TR, TD } from 'oy-vey';
|
||||
|
||||
const EmptySpace = ({ height }: { height?: number }) => {
|
||||
height = height || 16;
|
||||
const style = {
|
||||
lineHeight: `${height}px`,
|
||||
fontSize: '1px',
|
||||
msoLineHeightRule: 'exactly',
|
||||
};
|
||||
|
||||
return (
|
||||
<Table width="100%">
|
||||
<TBody>
|
||||
<TR>
|
||||
<TD
|
||||
width="100%"
|
||||
height={`${height}px`}
|
||||
style={style}
|
||||
dangerouslySetInnerHTML={{ __html: ' ' }}
|
||||
/>
|
||||
</TR>
|
||||
</TBody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmptySpace;
|
||||
31
server/emails/components/Footer.js
Normal file
31
server/emails/components/Footer.js
Normal file
@@ -0,0 +1,31 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import { Table, TBody, TR, TD } from 'oy-vey';
|
||||
|
||||
export default () => {
|
||||
const style = {
|
||||
padding: '20px 0',
|
||||
borderTop: '1px solid #e8e8e8',
|
||||
color: '#9BA6B2',
|
||||
fontSize: '14px',
|
||||
};
|
||||
|
||||
const linkStyle = {
|
||||
color: '#9BA6B2',
|
||||
textDecoration: 'none',
|
||||
};
|
||||
|
||||
return (
|
||||
<Table width="100%">
|
||||
<TBody>
|
||||
<TR>
|
||||
<TD width="75%" style={style}>
|
||||
<a href={process.env.URL} style={linkStyle}>
|
||||
Outline
|
||||
</a>
|
||||
</TD>
|
||||
</TR>
|
||||
</TBody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
35
server/emails/index.js
Normal file
35
server/emails/index.js
Normal file
@@ -0,0 +1,35 @@
|
||||
// @flow
|
||||
import Koa from 'koa';
|
||||
import Router from 'koa-router';
|
||||
import { Mailer } from '../mailer';
|
||||
|
||||
const emailPreviews = new Koa();
|
||||
const router = new Router();
|
||||
|
||||
router.get('/:type/:format', async ctx => {
|
||||
const previewMailer = new Mailer();
|
||||
let mailerOutput;
|
||||
previewMailer.transporter = {
|
||||
sendMail: data => (mailerOutput = data),
|
||||
};
|
||||
|
||||
switch (ctx.params.type) {
|
||||
case 'welcome':
|
||||
previewMailer.welcome('user@example.com');
|
||||
break;
|
||||
default:
|
||||
console.log(1);
|
||||
}
|
||||
|
||||
if (!mailerOutput) return;
|
||||
|
||||
if (ctx.params.format === 'text') {
|
||||
ctx.body = mailerOutput.text;
|
||||
} else {
|
||||
ctx.body = mailerOutput.html;
|
||||
}
|
||||
});
|
||||
|
||||
emailPreviews.use(router.routes());
|
||||
|
||||
export default emailPreviews;
|
||||
Reference in New Issue
Block a user