todo: mailer config

This commit is contained in:
2023-10-02 18:39:46 -05:00
parent 3d5079ec2e
commit c1fcc4af41
5 changed files with 75 additions and 11 deletions

View File

@@ -1,40 +1,41 @@
'use client';
import { useState } from "react";
import { contactFormSubmit, testMailerSDK } from "@/server/actions/mailer.actions"
import { useMemo, useState } from "react";
export default function ContactPage() {
const MESSAGE_LIMIT = 600;
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [message, setMessage] = useState('');
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
console.log(name, email, message);
}
const characterCount = useMemo(() => message.length.toString(), [message]);
return (
<div className="min-w-screen min-h-screen bg-gradient-to-b from-black to-darkPlum">
<div className="flex flex-col mx-24 items-center">
<h1 className="text-3xl my-8 place-self-start">Thanks for your interest! I&apos;m looking forward to hearing from you.</h1>
<form onSubmit={handleSubmit} className="w-full">
<form action={testMailerSDK} className="w-full">
<div className="flex w-full">
<div className="flex flex-col w-1/2 mr-2">
<label htmlFor="name">Name</label>
<input className="bg-neutral-100 px-1.5 py-1 text-black" value={name} onChange={(e) => setName(e.target.value)} type="text" name="name" id="name" />
<input required className="bg-neutral-100 px-1.5 py-1 text-black" value={name} onChange={(e) => setName(e.target.value)} type="text" name="name" id="name" />
</div>
<div className="flex flex-col w-1/2 ml-2">
<label htmlFor="email">Email</label>
<input className="bg-neutral-100 px-1.5 py-1 text-black" value={email} onChange={(e) => setEmail(e.target.value)} type="email" name="email" id="email" />
<input required className="bg-neutral-100 px-1.5 py-1 text-black" value={email} onChange={(e) => setEmail(e.target.value)} type="email" name="email" id="email" />
</div>
</div>
<div className="flex flex-col w-full mt-4">
<label htmlFor="message">Message</label>
<textarea className="bg-neutral-100 px-1.5 py-1 text-black" value={message} onChange={(e) => setMessage(e.target.value)} name="message" id="message" cols={30} rows={5}></textarea>
<textarea required className="bg-neutral-100 px-1.5 py-1 text-black" value={message} onChange={(e) => setMessage(e.target.value)} name="message" id="message" cols={30} rows={5}></textarea>
<p className={"text-sm " + (parseInt(characterCount) > MESSAGE_LIMIT ? "text-red-500" : "text-white")}>{characterCount}/{MESSAGE_LIMIT}</p>
</div>
<button className="p-2 px-8 mt-8 rounded-lg bg-rose-300 hover:bg-rose-400 text-black" type="submit">Send!</button>
<button disabled={parseInt(characterCount) > MESSAGE_LIMIT} className="p-2 px-8 mt-8 rounded-lg bg-rose-300 hover:bg-rose-400 text-black" type="submit">Send!</button>
</form>
</div>
</div>

View File

@@ -19,7 +19,7 @@ const nextConfig = {
reactStrictMode: true,
experimental: {
// mdxRs: true,
// serverActions: true,
serverActions: true,
}
}

View File

@@ -13,6 +13,7 @@
"@mdx-js/loader": "^2.3.0",
"@mdx-js/react": "^2.3.0",
"@next/mdx": "^13.4.4",
"@sendgrid/mail": "^7.7.0",
"@supabase/supabase-js": "^2.26.0",
"autoprefixer": "10.4.14",
"eslint": "^8.46.0",

View File

@@ -0,0 +1,34 @@
'use server';
import { Mailer } from "../services/sendgrid";
export async function contactFormSubmit(e: FormData) {
const data = [e.get('email'), e.get('message'), e.get('name')].map(each => each?.valueOf());
const mailer = new Mailer();
data.forEach(item => {
if (typeof item !== 'string') throw new Error('Invalid form data')
})
const result = await mailer.send(...data as [string, string, string]);
return result;
}
export async function testMailerSDK(e: FormData) {
const sgMail = require('@sendgrid/mail')
sgMail.setApiKey(process.env.SENDGRID_API_KEY)
const msg = {
to: 'mikaylaherself@gmail.com', // Change to your recipient
from: 'me@mikayla.dev', // Change to your verified sender
subject: 'Sending with SendGrid is Fun',
text: 'and easy to do anywhere, even with Node.js',
html: '<strong>and easy to do anywhere, even with Node.js</strong>',
}
sgMail
.send(msg)
.then(() => {
console.log('Email sent')
})
.catch((error: unknown) => {
console.error(error)
})
}

View File

@@ -0,0 +1,28 @@
import mailer, { ClientResponse, MailDataRequired, MailService } from "@sendgrid/mail";
export class Mailer {
private mailer: MailService;
constructor() {
const service = mailer;
const key = process.env.SENDGRID_API_KEY;
if (!key) throw new Error("No SendGrid API key provided");
service.setApiKey(key);
this.mailer = service;
}
public async send(from: string, text: string, name: string) {
const data: MailDataRequired = {
text, from,
cc: from,
to: 'hello@mikayla.dev',
subject: `Contact form submission from ${name}`
}
const result = await this.mailer.send(data);
return result[0] as ClientResponse;
}
}