-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(core): Added integration of resend and
@react-email
- Loading branch information
Showing
22 changed files
with
1,920 additions
and
271 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'x-boilerplate': minor | ||
--- | ||
|
||
Added integration of resend and `@react-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 |
---|---|---|
@@ -1,8 +1,14 @@ | ||
NEXT_PUBLIC_MSW_MOCKING = 'disabled' | ||
|
||
GITHUB_ID= | ||
GITHUB_SECRET= | ||
GITHUB_ID="" | ||
GITHUB_SECRET="" | ||
NEXTAUTH_URL="http://localhost:3000/" | ||
SECRET="" | ||
|
||
NEXTAUTH_URL=http://localhost:3000/ | ||
RESEND_API_KEY="" | ||
RESEND_DOMAIN="" | ||
|
||
SECRET= | ||
TWITTER_CREATOR="@wootsbot" | ||
SITE_NAME="X Boilerplate" | ||
SITE_URL="https://example.com" | ||
NEXT_PUBLIC_SITE_URL="https://example.com" |
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
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,90 @@ | ||
/* eslint-disable react/no-unescaped-entities */ | ||
import * as React from 'react'; | ||
|
||
import { | ||
Body, | ||
Button, | ||
Container, | ||
Head, | ||
Heading, | ||
Hr, | ||
Html, | ||
Img, | ||
Link, | ||
Preview, | ||
Section, | ||
Tailwind, | ||
Text, | ||
} from '@react-email/components'; | ||
|
||
import env from '~/env'; | ||
|
||
interface InviteEmailProps { | ||
invitedByUsername?: string; | ||
inviteLink?: string; | ||
} | ||
|
||
const baseUrl = env.SITE_URL ?? ''; | ||
|
||
export const InviteEmail = ({ invitedByUsername = 'X Boilerplate', inviteLink }: InviteEmailProps) => { | ||
return ( | ||
<Html> | ||
<Head /> | ||
<Preview>{invitedByUsername}</Preview> | ||
<Tailwind> | ||
<Body className="bg-white my-auto mx-auto font-sans"> | ||
<Container className="border border-solid border-[#eaeaea] rounded my-[40px] mx-auto p-[20px] w-[465px]"> | ||
<Section className="mt-[32px]"> | ||
<Img src={`${baseUrl}/email-img.png`} width="40" height="40" alt="Openkit img" className="my-0 mx-auto" /> | ||
</Section> | ||
|
||
<Heading className="text-black text-[24px] font-normal text-center p-0 mt-[30px] mb-[16px] mx-0"> | ||
Event | ||
</Heading> | ||
|
||
<Heading className="text-black text-[24px] font-normal text-center p-0 mb-[30px] mx-0"> | ||
<strong> | ||
Open Kit - Community <span className="text-blue-700">2023</span> | ||
</strong> | ||
</Heading> | ||
|
||
<Text className="text-black text-[14px] leading-[24px]"> | ||
On behalf of the entire <strong>openkit</strong> team, we want to express our sincerest gratitude for | ||
being part of this event and sharing your valuable knowledge with our community. | ||
</Text> | ||
|
||
<Section> | ||
<Text className="text-black text-[14px] leading-[24px]"> | ||
Don't miss out on the action! Make sure to add your talk to your calendar. We eagerly await you! | ||
</Text> | ||
</Section> | ||
|
||
<Section className="text-center mt-[32px] mb-[32px]"> | ||
<Button | ||
pX={20} | ||
pY={12} | ||
className="bg-[#000000] rounded text-white text-[12px] font-semibold no-underline text-center" | ||
href={inviteLink} | ||
> | ||
Join the Talk! | ||
</Button> | ||
</Section> | ||
<Text className="text-black text-[14px] leading-[24px]"> | ||
Or copy and paste this URL into your browser:{' '} | ||
<Link href={inviteLink} className="text-blue-600 no-underline"> | ||
{inviteLink} | ||
</Link> | ||
</Text> | ||
<Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" /> | ||
<Text className="text-[#666666] text-[12px] leading-[24px]"> | ||
🪂 X-boilerplate a starting boilerplate with configuration and best practices for your Nextjs projects, so | ||
you can only focus on building your product. | ||
</Text> | ||
</Container> | ||
</Body> | ||
</Tailwind> | ||
</Html> | ||
); | ||
}; | ||
|
||
export default InviteEmail; |
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,104 @@ | ||
'use client'; | ||
|
||
import { useRouter } from 'next/navigation'; | ||
import * as React from 'react'; | ||
import { useForm } from 'react-hook-form'; | ||
import toast from 'react-hot-toast'; | ||
|
||
import Button from '@design-system/Button'; | ||
import InputField from '@design-system/InputField'; | ||
import { zodResolver } from '@hookform/resolvers/zod'; | ||
import * as z from 'zod'; | ||
|
||
import { sendEmailSchema } from '@/utils/validations/send-email'; | ||
|
||
import Header from '@/components/Header'; | ||
import { useResendEmail } from '@/hooks/services/resend/email/use-resend-email.hook'; | ||
|
||
type FormValues = z.infer<typeof sendEmailSchema>; | ||
|
||
function ResendPage() { | ||
const router = useRouter(); | ||
|
||
const { | ||
register, | ||
handleSubmit, | ||
formState: { errors }, | ||
reset, | ||
} = useForm<FormValues>({ | ||
resolver: zodResolver(sendEmailSchema), | ||
}); | ||
|
||
const { mutate: handleResendEmail, isLoading } = useResendEmail({ | ||
onSuccess: (data) => { | ||
toast.success('Congratulations, you have successfully sent an email.'); | ||
reset(); | ||
}, | ||
onError: (_error) => { | ||
toast.error(`It seems we couldn't send the email, please try again.`); | ||
}, | ||
}); | ||
|
||
function handleGoBack() { | ||
router.push('/'); | ||
} | ||
|
||
function handleSubmitValues(data: FormValues) { | ||
console.log('data', data); | ||
handleResendEmail({ emailTo: data.emailToField, subject: data.subjectField, inviteLink: data.inviteLinkField }); | ||
} | ||
|
||
return ( | ||
<> | ||
<Header | ||
title="✉️ Resend" | ||
subTitle="Hi " | ||
name="Example with Resend, @react-email and TanStack Query" | ||
message="Example of sending an email with an invitation design to participate in an event, including a link." | ||
onGoBack={handleGoBack} | ||
/> | ||
|
||
<div | ||
style={{ | ||
display: 'flex', | ||
justifyContent: 'center', | ||
flexDirection: 'column', | ||
alignItems: 'center', | ||
}} | ||
> | ||
<form style={{ marginTop: 16 }} onSubmit={handleSubmit(handleSubmitValues)}> | ||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 24 }}> | ||
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}> | ||
<InputField | ||
placeholder="Email to" | ||
isError={Boolean(errors?.emailToField)} | ||
errMsg={errors?.emailToField?.message} | ||
{...register('emailToField')} | ||
/> | ||
|
||
<InputField | ||
placeholder="Email subject" | ||
isError={Boolean(errors?.subjectField)} | ||
errMsg={errors?.subjectField?.message} | ||
{...register('subjectField')} | ||
/> | ||
|
||
<InputField | ||
placeholder="Invite link" | ||
isError={Boolean(errors?.inviteLinkField)} | ||
errMsg={errors?.inviteLinkField?.message} | ||
{...register('inviteLinkField')} | ||
/> | ||
</div> | ||
|
||
<Button style={{ marginTop: '8px' }} type="submit" disabled={isLoading}> | ||
{isLoading ? 'Sending Email...' : ' Send Email'} | ||
</Button> | ||
</div> | ||
</form> | ||
</div> | ||
</> | ||
); | ||
} | ||
|
||
export default ResendPage; |
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,66 @@ | ||
'use client'; | ||
|
||
import * as React from 'react'; | ||
import { Toaster } from 'react-hot-toast'; | ||
|
||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; | ||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; | ||
|
||
import StoreProvider from '@/store/StoreProvider'; | ||
|
||
const queryClient = new QueryClient({ | ||
defaultOptions: { queries: { staleTime: 5000 } }, | ||
}); | ||
|
||
const Providers: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => { | ||
return ( | ||
<QueryClientProvider client={queryClient}> | ||
<StoreProvider> | ||
<>{children}</> | ||
</StoreProvider> | ||
<ReactQueryDevtools initialIsOpen={false} /> | ||
|
||
<Toaster | ||
position="top-center" | ||
reverseOrder={false} | ||
gutter={8} | ||
containerClassName="toast-container" | ||
containerStyle={{}} | ||
toastOptions={{ | ||
className: 'toast', | ||
duration: 5000, | ||
style: { | ||
borderRadius: '8px', | ||
}, | ||
icon: null, | ||
success: { | ||
style: { | ||
background: '#042f2e', | ||
borderColor: '#0f766e', | ||
borderWidth: 1, | ||
color: '#99f6e4', | ||
}, | ||
}, | ||
error: { | ||
style: { | ||
background: '#4c0519', | ||
borderColor: '#be123c', | ||
borderWidth: 1, | ||
color: '#fecdd3', | ||
}, | ||
}, | ||
loading: { | ||
style: { | ||
background: '#172554', | ||
borderColor: '#1d4ed8', | ||
borderWidth: 1, | ||
color: '#bfdbfe', | ||
}, | ||
}, | ||
}} | ||
/> | ||
</QueryClientProvider> | ||
); | ||
}; | ||
|
||
export default Providers; |
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,28 @@ | ||
import { NextResponse } from 'next/server'; | ||
|
||
import { Resend } from 'resend'; | ||
|
||
import { emailSchema } from '@/hooks/services/resend/email/email.schema'; | ||
import InviteEmail from '~/app/(marketing)/resend/InviteEmail'; | ||
import env from '~/env'; | ||
|
||
const resend = new Resend(env.RESEND_API_KEY); | ||
|
||
export async function POST(req: Request) { | ||
try { | ||
const json = await req.json(); | ||
const emailContent = emailSchema.parse(json); | ||
|
||
const data = await resend.emails.send({ | ||
from: env.RESEND_DOMAIN, | ||
to: emailContent.emailTo, | ||
subject: emailContent.subject, | ||
react: InviteEmail({ ...emailContent }), | ||
}); | ||
|
||
return NextResponse.json(data); | ||
} catch (error) { | ||
console.log('error', error); | ||
return NextResponse.json({ error }); | ||
} | ||
} |
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
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
Oops, something went wrong.
e754407
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
x-boilerplate – ./
x-boilerplate-git-main-codea.vercel.app
x-boilerplate-codea.vercel.app
x-boilerplate-demo.wootsbot.dev
x.openkit.run