Skip to content

Commit

Permalink
feat: update email format
Browse files Browse the repository at this point in the history
  • Loading branch information
joshxfi committed Dec 17, 2024
1 parent 4b3f732 commit 89e0fee
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 64 deletions.
Binary file added public/gdg-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 22 additions & 39 deletions src/app/api/email/route.ts
Original file line number Diff line number Diff line change
@@ -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 },
);
}
111 changes: 89 additions & 22 deletions src/components/devfest24-email.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
Heading,
Hr,
Html,
Img,
Link,
Preview,
Section,
Tailwind,
Expand All @@ -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 (
<Html>
<Head />
<Preview>{previewText}</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]">
<Heading className="text-black text-[24px] font-normal text-center p-0 my-[30px] mx-0">
<strong>GDG Bacolod</strong>
</Heading>
<Text>
Hello {firstName} {lastName},
<Body className="mx-auto my-auto bg-gray-100 font-sans">
<Container className="mx-auto my-[40px] w-[600px] rounded-lg bg-white p-[40px] shadow-lg">
<Section className="text-center">
<Img
src="https://utfs.io/f/K2HIaQ8LhAUDkkIOjmX91ZWgOj8dDqEUPL56RSs2ra4foY0B"
width="80"
height="80"
alt="GDG Bacolod Logo"
className="mx-auto mb-4 object-contain"
/>
<Heading className="m-0 mb-2 text-3xl font-bold text-gray-800">
GDG Bacolod
</Heading>
</Section>
<Section className="mb-8 text-center">
<Img
src="https://utfs.io/f/K2HIaQ8LhAUDxjZaTu0PmZioRV2GOf4tcMjsN1pS6LD9dQ0k"
width="250"
height="250"
alt="Certificate Preview"
className="mx-auto mb-4 object-contain"
/>
</Section>
<Text className="mb-4 text-base leading-6 text-gray-600">
Dear {firstName} {lastName},
</Text>
<Text className="text-black text-[14px] leading-[24px]">
We&apos;re excited to let you know that your certificate for{" "}
<strong>Google DevFest 2024</strong> is ready and waiting for you.
🎉 To claim it, just click the button below or check out the
attached image:
<Text className="mb-6 text-base leading-6 text-gray-600">
Congratulations! 🎉 Your certificate for{" "}
<strong>{eventName}</strong> is now available. We&apos;re thrilled
to recognize your participation and achievement.
</Text>
<Section className="text-center mt-[32px] mb-[32px]">
<Section className="mb-8 text-center">
<Button
className="bg-blue-600 rounded text-white text-[12px] font-semibold no-underline text-center"
className="rounded-full bg-blue-600 px-6 py-3 text-center text-base font-semibold text-white no-underline transition-all hover:bg-blue-700"
href={`https://devfest23.omsimos.com/cert/${id}`}
>
Claim Certificate
View Your Certificate
</Button>
</Section>
<Hr className="border border-solid border-[#eaeaea] my-[26px] mx-0 w-full" />
<Text className="text-[#666666] text-[12px] leading-[24px]">
This certificate generator is powered by{" "}
<span className="text-black">omsimos.com</span> — If you were not
expecting this certificate, you can ignore this email.
<Text className="mb-6 text-base leading-6 text-gray-600">
Don&apos;t forget to share your achievement on social media.
It&apos;s a great way to showcase your involvement in the tech
community!
</Text>
<Text className="mb-4 text-base leading-6 text-gray-600">
We value your feedback! Please take a moment to share your
thoughts about the event:
</Text>
<Section className="mb-8 text-center">
<Link
href="https://omsimos.com"
className="text-blue-600 underline"
>
Provide Feedback
</Link>
</Section>
<Hr className="mx-0 my-6 w-full border border-solid border-gray-200" />
<Text className="text-center text-sm leading-6 text-gray-500">
This certificate is powered by{" "}
<Link
href="https://omsimos.com"
className="text-blue-600 no-underline"
>
omsimos.com
</Link>
</Text>
<Text className="text-center text-sm leading-6 text-gray-500">
If you didn&apos;t participate in this event, please disregard
this email.
</Text>
<Section className="mt-8 text-center">
<Text className="mb-4 text-sm text-gray-500">
Follow us on social media:
</Text>
<Link
href="https://facebook.com/gdgbacolod"
className="mx-2 text-blue-600 no-underline"
>
Facebook
</Link>
<Link
href="https://linkedin.com/company/gdgbacolod"
className="mx-2 text-blue-600 no-underline"
>
LinkedIn
</Link>
</Section>
</Container>
</Body>
</Tailwind>
Expand Down
13 changes: 10 additions & 3 deletions src/lib/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -19,11 +25,12 @@ export const handleSendEmail = async (data: Payload) => {

return (
await transporter.sendMail({
from: process.env.NODEMAILER_EMAIL,
from: "[email protected]",
...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");
Expand Down

0 comments on commit 89e0fee

Please sign in to comment.