Skip to content

Commit

Permalink
continue
Browse files Browse the repository at this point in the history
  • Loading branch information
borispoehland committed Oct 1, 2024
1 parent 2ac7803 commit 14803bf
Show file tree
Hide file tree
Showing 10 changed files with 746 additions and 28 deletions.
4 changes: 4 additions & 0 deletions src/email.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
export * from './email/email'
export * from './email/event-email'
export * from './email/invite-email'
export * from './email/approval-pending-email'
export * from './email/approval-accepted-email'
export * from './email/approval-rejected-email'
export * from './email/checkedin-email'
export * from './email/types'
export {
renderGenericEmail,
Expand Down
204 changes: 204 additions & 0 deletions src/email/approval-accepted-email.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
import React, { createElement, type ComponentProps } from 'react'

import { Body, Container, Img, Section } from '@react-email/components'
import { createTranslator } from 'use-intl'

import {
defaultHost,
getMapsLink,
getOnlineLocation,
IEmailConfig,
} from '../utils'
import { IEvent } from './types'
import type { Translations, WithUnsubscribeToken } from './utils'
import {
bodyStyle,
Center,
defaultBodyStyle,
FixedButton,
FixedHeading,
FixedLink,
FixedText,
GeneralEmail,
MEDIA,
MsFix,
renderGenericEmail,
smallHeadingStyle,
ThankYou,
} from './utils'

const translations = {
namespace: '',
translations: {
en: {
approval: {
meta: 'Congrats, you got accepted to join {eventName}!',
title: 'You got accepted to join {eventName}',
greeting: 'Dear {name},',
description:
"We're excited to let you know that the organizers <b>accepted your request to join {eventName}</b>! Click below link to access your ticket, which you can use to check-in.",
action: 'OPEN MY TICKET',
info: 'For more information and updates, <xoxnolink>visit our website</xoxnolink>. If you have any questions, feel free to reach out to us <emaillink>via email</emaillink>.',
maps: 'Open in Google Maps',
footer: 'Thank you for using {appName}!',
},
},
},
} as const satisfies Translations

type IProps = {
host?: IEmailConfig
name: string
event: IEvent
style?: {
background: string
backgroundColor: string
}
}

const messages = translations.translations.en

const ApprovalAcceptedEmail = ({
host = defaultHost,
event,
name,
style = defaultBodyStyle,
unsubscribeToken,
}: IProps & WithUnsubscribeToken) => {
const t = createTranslator({
locale: 'en',
messages,
namespace: 'approval',
})

const tPayload = { appName: host.appName }

const HOST = `https://${host.host}`

const href = `${HOST}/event/${event.eventId}`

const mapsLink = getMapsLink(event.location)

return (
<GeneralEmail
title={t('meta', { eventName: event.name, ...tPayload })}
HOST={HOST}
unsubscribeToken={unsubscribeToken}
>
{({ unsubscribeSection }) => {
return (
<Body className="body" style={style}>
<Section className="max-w-[1200px] mx-auto" style={style}>
<MsFix backgroundColor={style.backgroundColor} />
<Container className="px-5">
<Section className="mb-4">
<Img
src={`${MEDIA}/hotlink-ok/success.png`}
width="100%"
height="140px"
className="object-cover"
alt="XOXNO Banner"
/>
</Section>
<Section className="p-5">
<Center>
<FixedHeading className="my-0">
{t('title', { eventName: event.name, ...tPayload })}
</FixedHeading>
<FixedText className="mb-0">
{t('greeting', { name, ...tPayload })}
</FixedText>
<FixedText>
{t.rich('description', {
...tPayload,
eventName: event.name,
b: (chunks) => <b>{chunks}</b>,
})}
</FixedText>
<FixedButton href={href} className="block">
{t('action', tPayload)}
</FixedButton>
</Center>
</Section>
<Section>
<FixedText style={smallHeadingStyle} className="mb-0">
{event.time}
</FixedText>
<Center>
<table
role="presentation"
cellSpacing="0"
cellPadding="0"
border={0}
style={{ borderCollapse: 'collapse' }}
>
<tbody>
<tr>
<td
style={{
paddingRight: '16px',
verticalAlign: 'middle',
}}
>
<Img
src={`${MEDIA}/hotlink-ok/email_pin.png`}
width={24}
height={24}
alt="Location pin"
/>
</td>
<td style={{ verticalAlign: 'middle' }}>
<FixedText className="my-0">
{event.location.onlineLink
? getOnlineLocation(event.location.onlineLink)
: event.location.address}
</FixedText>
</td>
</tr>
</tbody>
</table>
{event.location.address && event.location.placeId && (
<FixedLink href={mapsLink}>
{t('maps', tPayload)}
</FixedLink>
)}
</Center>
</Section>
<Section className="pt-8 pb-3 mt-8 text-center border-t border-solid border-[#FFF]/[0.1]">
<FixedText className="my-0">
{t.rich('info', {
...tPayload,
xoxnolink: (children) => (
<FixedLink href={HOST} disableFix>
{children}
</FixedLink>
),
emaillink: (children) => (
<FixedLink
href={`mailto:${host.socials.email}`}
disableFix
>
{children}
</FixedLink>
),
})}
</FixedText>
<ThankYou text={t('footer', tPayload)} />
</Section>
{unsubscribeSection}
</Container>
</Section>
</Body>
)
}}
</GeneralEmail>
)
}

export const renderApprovalAcceptedEmail = async (
props: ComponentProps<typeof ApprovalAcceptedEmail>
) => {
const Email = createElement(ApprovalAcceptedEmail, props, null)

return renderGenericEmail(Email)
}
163 changes: 163 additions & 0 deletions src/email/approval-pending-email.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import React, { createElement, type ComponentProps } from 'react'

import { Body, Container, Img, Section } from '@react-email/components'
import { createTranslator } from 'use-intl'

import { defaultHost, IEmailConfig } from '../utils'
import { IEvent } from './types'
import type { Translations, WithUnsubscribeToken } from './utils'
import {
Center,
defaultBodyStyle,
FixedHeading,
FixedLink,
FixedText,
GeneralEmail,
MEDIA,
MsFix,
renderGenericEmail,
ThankYou,
} from './utils'

const translations = {
namespace: '',
translations: {
en: {
approval: {
meta: 'You requested to join {eventName}',
title: 'You requested to join {eventName}',
greeting: 'Dear {name},',
description:
'<b>You requested to join the {eventName} as a guest!</b> <br></br> The organizer will accept or reject your request, in the meantime you can <explorelink>explore more events on {appName}</explorelink>.',
info: 'For more information and updates, <xoxnolink>visit our website</xoxnolink>. If you have any questions, feel free to reach out to us <emaillink>via email</emaillink>.',
footer: 'Thank you for using {appName}!',
},
},
},
} as const satisfies Translations

type IProps = {
host?: IEmailConfig
name: string
event: Pick<IEvent, 'name' | 'backgroundImage'>
style?: {
background: string
backgroundColor: string
}
}

const messages = translations.translations.en

const ApprovalPendingEmail = ({
host = defaultHost,
event,
name,
style = defaultBodyStyle,
unsubscribeToken,
}: IProps & WithUnsubscribeToken) => {
const t = createTranslator({
locale: 'en',
messages,
namespace: 'approval',
})

const tPayload = { appName: host.appName }

const HOST = `https://${host.host}`

const href = `${HOST}/explore/events`

return (
<GeneralEmail
title={t('meta', { eventName: event.name, ...tPayload })}
HOST={HOST}
unsubscribeToken={unsubscribeToken}
>
{({ unsubscribeSection }) => {
return (
<Body className="body" style={style}>
<Section
className="max-w-[1200px] mx-auto bg-center bg-cover"
style={{
...style,
backgroundImage: event.backgroundImage
? `url(${event.backgroundImage})`
: style.background,
}}
>
<MsFix
backgroundColor={style.backgroundColor}
backgroundImage={event.backgroundImage}
/>
<Container className="px-5">
<Section className="min-h-[100px]">
<Center>
<Img
src={`${MEDIA}/hotlink-ok/email_logo.png`}
width={130}
height={24}
alt="XOXNO Logo"
/>
</Center>
</Section>
<Section className="p-5 pb-0">
<Center>
<FixedHeading className="my-0">
{t('title', { eventName: event.name, ...tPayload })}
</FixedHeading>
<FixedText className="mb-0">
{t('greeting', { name, ...tPayload })}
</FixedText>
<FixedText>
{t.rich('description', {
...tPayload,
eventName: event.name,
b: (chunks) => <b>{chunks}</b>,
br: () => <br />,
explorelink: (children) => (
<FixedLink href={href} disableFix>
{children}
</FixedLink>
),
})}{' '}
</FixedText>
</Center>
</Section>
<Section className="pt-8 pb-3 mt-8 text-center border-t border-solid border-[#FFF]/[0.1]">
<FixedText className="my-0">
{t.rich('info', {
...tPayload,
xoxnolink: (children) => (
<FixedLink href={HOST} disableFix>
{children}
</FixedLink>
),
emaillink: (children) => (
<FixedLink
href={`mailto:${host.socials.email}`}
disableFix
>
{children}
</FixedLink>
),
})}
</FixedText>
<ThankYou text={t('footer', tPayload)} />
</Section>
{unsubscribeSection}
</Container>
</Section>
</Body>
)
}}
</GeneralEmail>
)
}

export const renderApprovalPendingEmail = async (
props: ComponentProps<typeof ApprovalPendingEmail>
) => {
const Email = createElement(ApprovalPendingEmail, props, null)

return renderGenericEmail(Email)
}
Loading

0 comments on commit 14803bf

Please sign in to comment.