From 89e0fee8e83e916b77553834c6549ee110561800 Mon Sep 17 00:00:00 2001 From: Josh Daniel Date: Tue, 17 Dec 2024 22:48:09 +0800 Subject: [PATCH] feat: update email format --- public/gdg-icon.png | Bin 0 -> 4281 bytes src/app/api/email/route.ts | 61 ++++++---------- src/components/devfest24-email.tsx | 111 +++++++++++++++++++++++------ src/lib/email.ts | 13 +++- 4 files changed, 121 insertions(+), 64 deletions(-) create mode 100644 public/gdg-icon.png diff --git a/public/gdg-icon.png b/public/gdg-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3f91ec5c14d3e5bc3b8e323ba893d0c083468784 GIT binary patch literal 4281 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 R5cn4c(Zd>IDz%&={|EKGTE74Q literal 0 HcmV?d00001 diff --git a/src/app/api/email/route.ts b/src/app/api/email/route.ts index 3a3eec7..9be9870 100644 --- a/src/app/api/email/route.ts +++ b/src/app/api/email/route.ts @@ -1,48 +1,31 @@ -import { NextResponse } from 'next/server'; -import nodemailer from 'nodemailer'; -import Mail from 'nodemailer/lib/mailer'; +import { NextRequest, NextResponse } from "next/server"; +import { render } from "@react-email/render"; +import Email from "@/components/devfest24-email"; +import { handleSendEmail } from "@/lib/email"; -type Payload = { - to: string; - subject: string; - html: string; - attachments: Mail.Attachment[]; -}; - -export async function POST(request: Request) { +export async function POST(request: NextRequest) { try { - const data: Payload = await request.json(); + const body = await request.json(); + const { id, email, firstName, lastName } = body; - let transporter = nodemailer.createTransport({ - service: 'gmail', - auth: { - user: process.env.NODEMAILER_EMAIL, - pass: process.env.NODEMAILER_PW, - }, - }); + const htmlContent = await render(Email({ id, firstName, lastName })); - await new Promise((resolve, reject) => { - transporter.sendMail( - { - from: process.env.NODEMAILER_EMAIL, - ...data, - }, - (error, info) => { - if (error) { - console.error('Error sending email:', error); - reject(error); - } else { - console.log('Email sent:', info.response); - resolve(info); - } - } - ); + await handleSendEmail({ + to: email, + subject: "Certificate: Google DevFest 2024", + html: htmlContent, }); - return NextResponse.json({ message: 'Email sent successfully' }, { status: 200 }); - } catch (error) { - console.error('Error in route handler:', error); - return NextResponse.json({ error: 'Failed to send email' }, { status: 500 }); + return NextResponse.json({ message: "Success" }, { status: 200 }); + } catch (err: any) { + console.error("Error sending email:", err, process.env.NODEMAILER_PW); + return NextResponse.json({ message: err.message }, { status: 500 }); } } +export async function GET() { + return NextResponse.json( + { message: "GET request received" }, + { status: 200 }, + ); +} diff --git a/src/components/devfest24-email.tsx b/src/components/devfest24-email.tsx index 82da1f0..3135960 100644 --- a/src/components/devfest24-email.tsx +++ b/src/components/devfest24-email.tsx @@ -6,6 +6,8 @@ import { Heading, Hr, Html, + Img, + Link, Preview, Section, Tailwind, @@ -17,44 +19,109 @@ type Props = { id: string; firstName: string; lastName: string; + eventName?: string; }; -export const CertificateEmail = ({ id, firstName, lastName }: Props) => { - const previewText = "Claim Your Certificate!"; +export const CertificateEmail = ({ + id, + firstName, + lastName, + eventName = "DevFest Bacolod 2024", +}: Props) => { + const previewText = `Your ${eventName} Certificate is Ready!`; return ( {previewText} - - - - GDG Bacolod - - - Hello {firstName} {lastName}, + + +
+ GDG Bacolod Logo + + GDG Bacolod + +
+
+ Certificate Preview +
+ + Dear {firstName} {lastName}, - - We're excited to let you know that your certificate for{" "} - Google DevFest 2024 is ready and waiting for you. - 🎉 To claim it, just click the button below or check out the - attached image: + + Congratulations! 🎉 Your certificate for{" "} + {eventName} is now available. We're thrilled + to recognize your participation and achievement. -
+
-
- - This certificate generator is powered by{" "} - omsimos.com — If you were not - expecting this certificate, you can ignore this email. + + Don't forget to share your achievement on social media. + It's a great way to showcase your involvement in the tech + community! + + + We value your feedback! Please take a moment to share your + thoughts about the event: + +
+ + Provide Feedback + +
+
+ + This certificate is powered by{" "} + + omsimos.com + + + + If you didn't participate in this event, please disregard + this email. +
+ + Follow us on social media: + + + Facebook + + + LinkedIn + +
diff --git a/src/lib/email.ts b/src/lib/email.ts index 5766087..b1fafda 100644 --- a/src/lib/email.ts +++ b/src/lib/email.ts @@ -5,12 +5,18 @@ type Payload = { to: string; subject: string; html: string; - attachments: Mail.Attachment[]; + attachments?: Mail.Attachment[]; }; export const handleSendEmail = async (data: Payload) => { let transporter = nodemailer.createTransport({ - service: "gmail", + host: "smtp.hostinger.com", + port: 465, + secure: true, + debug: process.env.NODE_ENV === "development", + tls: { + rejectUnauthorized: false, + }, auth: { user: process.env.NODEMAILER_EMAIL, pass: process.env.NODEMAILER_PW, @@ -19,11 +25,12 @@ export const handleSendEmail = async (data: Payload) => { return ( await transporter.sendMail({ - from: process.env.NODEMAILER_EMAIL, + from: "no-reply@omsimos.com", ...data, }), function (error: string, _info: string) { if (error) { + console.log("Your Email", process.env.NODEMAILER_EMAIL); throw new Error(error); } else { console.log("Email Sent");