-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2ac7803
commit 14803bf
Showing
10 changed files
with
746 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
Oops, something went wrong.