Skip to content

Commit 9f37da6

Browse files
committed
feat: resend
1 parent 2707466 commit 9f37da6

File tree

8 files changed

+92
-13
lines changed

8 files changed

+92
-13
lines changed

apps/web/.env.example

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
NEXTAUTH_SECRET=
2+
NEXTAUTH_URL=
3+
4+
NEXT_PUBLIC_FRONTEND_URL=
5+
6+
GITHUB_ID=
7+
GITHUB_SECRET=
8+
9+
JWT_SECRET=
10+
11+
NEXT_PUBLIC_FB_APP_ID=
12+
13+
RESEND_AUDIENCE_ID=

apps/web/@/actions/auth/index.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import bcryptjs from "bcryptjs"
44
import { signIn, signOut } from "configs/auth"
55
import { Prisma } from "database"
66
import { createUser } from "database/src/users/queries"
7+
import { sendEmail } from "emails"
8+
import VerifyEmail from "emails/verify-email"
79

810
import { redirect } from "@/utils/navigation"
911

@@ -42,8 +44,31 @@ export const signUp = async (
4244
},
4345
})
4446

47+
console.log("create user...successfully")
48+
49+
// create verification code
50+
const token = crypto.randomUUID()
51+
await prisma.verificationToken.create({
52+
data: {
53+
token, // 6 digits code
54+
identifier: email,
55+
expires: new Date(Date.now() + 1000 * 60 * 60 * 24), // 1 day
56+
},
57+
})
58+
59+
console.log("verification token...successfully")
60+
4561
// send email
62+
await sendEmail({
63+
email,
64+
subject: "Welcome to Next Forum",
65+
react: VerifyEmail({
66+
token,
67+
email,
68+
}),
69+
})
4670
} catch (error) {
71+
console.error("signUp.error", error)
4772
if (error?.error?.code === "P2002") {
4873
return {
4974
formErrors: null,

apps/web/@/libs/resend/index.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Resend } from "resend"
2+
3+
const resendApiKey = process.env.RESEND_API_KEY
4+
5+
export const resend = resendApiKey ? new Resend(resendApiKey) : null
6+
7+
export async function subscribe({ email, name }: { email: string; name?: string | null }) {
8+
const audienceId = process.env.RESEND_AUDIENCE_ID
9+
10+
if (!audienceId) {
11+
console.error("RESEND_AUDIENCE_ID is not set in the .env. Skipping.")
12+
return
13+
}
14+
15+
return await resend?.contacts.create({
16+
email,
17+
...(name && {
18+
firstName: name.split(" ")[0],
19+
lastName: name.split(" ").slice(1).join(" "),
20+
}),
21+
audienceId: process.env.RESEND_AUDIENCE_ID as string,
22+
})
23+
}
24+
25+
export async function unsubscribe({ email }: { email: string }) {
26+
return await resend?.contacts.remove({
27+
email,
28+
audienceId: process.env.RESEND_AUDIENCE_ID as string,
29+
})
30+
}

apps/web/@/molecules/auth/sign-up/index.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,18 @@
33
import Link from "next/link"
44

55
import { zodResolver } from "@hookform/resolvers/zod"
6-
import { Prisma } from "database"
7-
import { GithubIcon } from "lucide-react"
86
import { useTranslations } from "next-intl"
9-
import { useFormState } from "react-dom"
107
import { useForm } from "react-hook-form"
118
import { toast } from "react-toastify"
129
import {
1310
Button,
14-
Card,
15-
CardContent,
16-
CardFooter,
1711
Form,
1812
FormControl,
1913
FormField,
2014
FormItem,
2115
FormLabel,
2216
FormMessage,
2317
Input,
24-
Label,
2518
Typography,
2619
} from "ui"
2720
import { z } from "zod"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"use client"
2+
3+
import { useSearchParams } from "next/navigation"
4+
5+
export default function VerifyEmail() {
6+
const searchParams = useSearchParams()
7+
const code = searchParams.get("code")
8+
9+
return <div>Verify Email</div>
10+
}

apps/web/emails/index.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { render } from "@react-email/components"
44
import nodemailer from "nodemailer"
55
import { CreateEmailOptions } from "resend"
66

7-
import { resend } from "@/lib/resend"
7+
import { resend } from "@/libs/resend"
88

99
// Send email using SMTP (Recommended for local development)
1010
const sendEmailViaSMTP = async ({
@@ -63,18 +63,21 @@ export const sendEmailViaResend = async ({
6363
return await resend.emails.send({
6464
to: email,
6565
from:
66-
from || (marketing ? "Steven from Dub.co <steven@ship.dub.co>" : "Dub.co <system@dub.co>"),
66+
from ||
67+
(marketing
68+
? "Luan Nguyen from codeforstartup.com <support@codeforstartup.com>"
69+
: "codeforstartup.com <support@codeforstartup.com>"),
6770
bcc: bcc,
6871
...(!replyToFromEmail && {
69-
replyTo: "support@dub.co",
72+
replyTo: "support@codeforstartup.com",
7073
}),
7174
subject: subject,
7275
text: text,
7376
react: react,
7477
scheduledAt,
7578
...(marketing && {
7679
headers: {
77-
"List-Unsubscribe": "https://app.dub.co/account/settings",
80+
"List-Unsubscribe": process.env.NEXT_PUBLIC_FRONTEND_URL,
7881
},
7982
}),
8083
})
@@ -97,6 +100,8 @@ export const sendEmail = async ({
97100
marketing?: boolean
98101
}) => {
99102
if (resend) {
103+
console.info("sendmail...", email)
104+
100105
return await sendEmailViaResend({
101106
email,
102107
subject,

apps/web/emails/verify-email.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
Text,
1313
} from "@react-email/components"
1414

15-
export default function VerifyEmail({}) {
15+
export default function VerifyEmail({ token, email }: { token: string; email: string }) {
1616
return (
1717
<Html>
1818
<Head />
@@ -29,7 +29,7 @@ export default function VerifyEmail({}) {
2929
</Text>
3030
<Section className="my-8">
3131
<Link
32-
href=""
32+
href={`${process.env.NEXT_PUBLIC_APP_URL}/auth/verify-email?code=${token}&email=${email}`}
3333
className="align-center flex w-[100%] justify-center rounded-sm bg-[tomato] py-2 text-center font-medium text-white"
3434
>
3535
GET STARTED

apps/web/tsconfig.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
"@/*",
1515
"./src/*",
1616
"assets/*"
17+
],
18+
"emails/*": [
19+
"./emails/*"
1720
]
1821
}
1922
},

0 commit comments

Comments
 (0)