Skip to content

Commit

Permalink
feat(api): Add email template for inviting user to workspace (keyshad…
Browse files Browse the repository at this point in the history
…e-xyz#480)

Co-authored-by: Rajdip Bhattacharya <[email protected]>
  • Loading branch information
2 people authored and muntaxir4 committed Jan 1, 2025
1 parent cdbf1bc commit f83b952
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 164 deletions.
84 changes: 84 additions & 0 deletions apps/api/src/mail/emails/components/base-email-template.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import * as React from 'react'
import {
Body,
Container,
Head,
Heading,
Html,
Link,
Preview,
Section,
Text
} from '@react-email/components'
import {
container,
content,
footer,
footerText,
h1,
link,
main,
text
} from '../styles/common-styles'

interface BaseEmailTemplateProps {
previewText: string
heading: string
children: React.ReactNode
}

export const BaseEmailTemplate: React.FC<BaseEmailTemplateProps> = ({
previewText,
heading,
children
}) => {
return (
<Html>
<Head />
<Preview>{previewText}</Preview>
<Body style={main}>
<Container style={container}>
<Section style={content}>
<Heading style={h1}>{heading}</Heading>
{children}
<Text style={text}>
If you believe this action was taken in error or have any
questions regarding this change, please contact your project
administrator or our support team.
</Text>
<Text style={text}>
We appreciate your understanding and thank you for your
contributions to the project.
</Text>
<Text style={text}>
Cheers,
<br />
Team Keyshade
</Text>
</Section>
<Section style={footer}>
<Text style={footerText}>
This is an automated message. Please do not reply to this email.
</Text>
<Text style={footerText}>
Read our{' '}
<Link href="https://www.keyshade.xyz/privacy" style={link}>
Privacy Policy
</Link>{' '}
and{' '}
<Link
href="https://www.keyshade.xyz/terms_and_condition"
style={link}
>
Terms and Conditions
</Link>{' '}
for more information on how we manage your data and services.
</Text>
</Section>
</Container>
</Body>
</Html>
)
}

export default BaseEmailTemplate
78 changes: 78 additions & 0 deletions apps/api/src/mail/emails/styles/common-styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { CSSProperties } from 'react'

export const main: CSSProperties = {
fontFamily: "'Segoe UI', 'Roboto', sans-serif",
lineHeight: '1.6',
color: '#04050a',
backgroundColor: '#fafafa',
margin: '0',
padding: '20px'
}

export const container: CSSProperties = {
maxWidth: '600px',
margin: '0 auto',
backgroundColor: '#fff',
borderRadius: '5px',
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.05)'
}

export const content: CSSProperties = {
padding: '20px 40px'
}

export const h1: CSSProperties = {
color: '#000',
marginBottom: '20px',
fontSize: '24px',
fontWeight: '600'
}

export const text: CSSProperties = {
marginBottom: '5px',
color: '#666'
}

export const workspaceDetails: CSSProperties = {
width: '100%',
backgroundColor: '#fafafa',
borderRadius: '5px',
margin: '20px 0px',
padding: '10px 20px'
}

export const workspaceInfo: CSSProperties = {
margin: '7px 0px'
}

export const ctaButton: CSSProperties = {
width: '100px',
color: '#ffffff',
fontSize: '14px',
fontWeight: '500',
textAlign: 'center',
marginTop: '10px',
cursor: 'pointer',
display: 'inline-block',
backgroundColor: '#000',
textDecoration: 'none',
padding: '10px 22px',
borderRadius: '5px'
}

export const footer: CSSProperties = {
borderTop: '1px solid #eaeaea',
padding: '20px'
}

export const footerText: CSSProperties = {
fontSize: '12px',
color: '#999',
textAlign: 'center' as const,
margin: '0'
}

export const link: CSSProperties = {
color: '#000',
textDecoration: 'underline'
}
67 changes: 67 additions & 0 deletions apps/api/src/mail/emails/workspace-invitation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import * as React from 'react'
import { Button, Section, Text } from '@react-email/components'
import dayjs from 'dayjs'
import {
ctaButton,
text,
workspaceDetails,
workspaceInfo
} from './styles/common-styles'
import BaseEmailTemplate from './components/base-email-template'

interface WorkspaceInvitationEmailProps {
workspaceName: string
actionUrl: string
invitedBy: string
invitedOn: string
forRegisteredUser: boolean
}

export const WorkspaceInvitationEmail = ({
workspaceName,
actionUrl,
invitedBy,
invitedOn,
forRegisteredUser
}: WorkspaceInvitationEmailProps) => {
const formattedInvitedOnDate = dayjs(invitedOn).format(
'ddd, MMM D, YYYY h:mm A'
)

const previewText = forRegisteredUser
? 'Welcome Back! Join Your Workspace'
: 'You are Invited to Join the Workspace'

return (
<BaseEmailTemplate
previewText={previewText}
heading={previewText}
>
<Text style={text}>Dear User,</Text>
<Text style={text}>
We're excited to inform you that you've been invited to join a
workspace on Keyshade. Here are the details of your invitation:
</Text>
<Section style={workspaceDetails}>
<Text style={workspaceInfo}>
<strong>Workspace Name:</strong> {workspaceName}
</Text>
<Text style={workspaceInfo}>
<strong>Invited By:</strong> {invitedBy}
</Text>
<Text style={workspaceInfo}>
<strong>Invited On:</strong> {formattedInvitedOnDate}
</Text>
</Section>
<Text style={text}>
Join the project by clicking the button below - we're excited to
have you!
</Text>
<Button href={actionUrl} style={ctaButton}>
Get started
</Button>
</BaseEmailTemplate>
)
}

export default WorkspaceInvitationEmail
Loading

0 comments on commit f83b952

Please sign in to comment.