Implement Contact Page #1
2 changed files with 127 additions and 27 deletions
87
src/routes/contact/+page.server.ts
Normal file
87
src/routes/contact/+page.server.ts
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
import {
|
||||||
|
MAIL_TRANSPORT_HOST,
|
||||||
|
MAIL_TRANSPORT_PASS,
|
||||||
|
MAIL_TRANSPORT_PORT,
|
||||||
|
MAIL_TRANSPORT_USER,
|
||||||
|
} from "$env/static/private";
|
||||||
|
import { fail } from "@sveltejs/kit";
|
||||||
|
import { createTransport } from "nodemailer";
|
||||||
|
import type { Actions } from "./$types";
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
default: async ({ request }) => {
|
||||||
|
const form = await request.formData();
|
||||||
|
|
||||||
|
if (!form.has("name")) {
|
||||||
|
return fail(400, { name: null, missing: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!form.has("email")) {
|
||||||
|
return fail(400, { email: null, missing: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!form.has("subject")) {
|
||||||
|
return fail(400, { subject: null, missing: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!form.has("message")) {
|
||||||
|
return fail(400, { message: null, missing: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = form.get("name");
|
||||||
|
if (typeof name !== "string") {
|
||||||
|
return fail(400, { name, incorrect: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const email = form.get("email");
|
||||||
|
if (typeof email !== "string") {
|
||||||
|
return fail(400, { email, incorrect: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const subject = form.get("subject");
|
||||||
|
if (typeof subject !== "string") {
|
||||||
|
return fail(400, { subject, incorrect: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = form.get("message");
|
||||||
|
if (typeof message !== "string") {
|
||||||
|
return fail(400, { message, incorrect: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const transport = createTransport({
|
||||||
|
host: MAIL_TRANSPORT_HOST,
|
||||||
|
port: isNaN(Number(MAIL_TRANSPORT_PORT))
|
||||||
|
? 587
|
||||||
|
: Number(MAIL_TRANSPORT_PORT),
|
||||||
|
auth: {
|
||||||
|
user: MAIL_TRANSPORT_USER,
|
||||||
|
pass: MAIL_TRANSPORT_PASS,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const info1 = await transport.sendMail({
|
||||||
|
from: "no-reply@benjaminpalko.ca",
|
||||||
|
to: email,
|
||||||
|
subject: `Thank you for reaching out`,
|
||||||
|
text: `Hello ${name}!\n\nThank you for reaching out! I will be sure to get back to you ASAP.\n\nCheers,\nBenjamin`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const info2 = await transport.sendMail({
|
||||||
|
from: email,
|
||||||
|
to: "contact@benjaminpalko.ca",
|
||||||
|
subject: subject,
|
||||||
|
text: message,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
response: {
|
||||||
|
accepted: [...info1.accepted, ...info2.accepted],
|
||||||
|
rejected: [...info1.rejected, ...info2.rejected],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} satisfies Actions;
|
||||||
|
|
@ -1,41 +1,54 @@
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { enhance } from '$app/forms';
|
import { enhance } from '$app/forms';
|
||||||
import { Croissant, Mail, UserRound } from 'lucide-svelte';
|
import { CircleCheck, CircleX, Croissant, Mail, UserRound } from 'lucide-svelte';
|
||||||
|
import type { PageProps } from './$types';
|
||||||
|
|
||||||
|
let { form, data }: PageProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col">
|
<form class="w-full" id="contact" method="post" use:enhance>
|
||||||
<div class="flex flex-col items-center">
|
<div class="grid w-full max-w-xl grid-cols-2 gap-6">
|
||||||
<span class="animate-bounce text-2xl">😁</span>
|
<div class="col-span-2 flex flex-col items-center">
|
||||||
<h2 class="text-2xl">Hello there friend</h2>
|
<span class="animate-bounce text-2xl">😁</span>
|
||||||
</div>
|
<h2 class="text-2xl">Hello there friend</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
<form id="contact" use:enhance>
|
<h3 class="col-span-2 text-xl">Reach out! 🤝</h3>
|
||||||
<div class="bg-base-200 flex flex-col gap-4">
|
|
||||||
<h1 class="text-4xl">Want to chat?</h1>
|
{#if form?.response.rejected.length ?? 0 > 0}
|
||||||
<h5 class="text-lg">Reach out! 🤝</h5>
|
<div role="alert" class="alert alert-error col-span-2">
|
||||||
|
<CircleX />
|
||||||
|
<span>Ruh roh raggy!</span>
|
||||||
|
</div>
|
||||||
|
{:else if form?.response.accepted.length ?? 0 > 0}
|
||||||
|
<div role="alert" class="alert alert-success col-span-2">
|
||||||
|
<CircleCheck />
|
||||||
|
<span>Your message has been sent successfully!</span>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="flex h-full flex-col gap-4">
|
||||||
<label class="input input-bordered flex items-center gap-2">
|
<label class="input input-bordered flex items-center gap-2">
|
||||||
<UserRound />
|
<UserRound />
|
||||||
<input name="name" type="text" class="grow" placeholder="What is your name?" />
|
<input name="name" type="text" class="grow" placeholder="Name" />
|
||||||
</label>
|
</label>
|
||||||
<label class="input input-bordered flex items-center gap-2">
|
<label class="input input-bordered flex items-center gap-2">
|
||||||
<Mail />
|
<Mail />
|
||||||
<input name="email" type="text" class="grow" placeholder="I'm going to need your email." />
|
<input name="email" type="text" class="grow" placeholder="Your Email" />
|
||||||
</label>
|
</label>
|
||||||
<label class="input input-bordered flex items-center gap-2">
|
<label class="input input-bordered flex items-center gap-2">
|
||||||
<Croissant />
|
<Croissant />
|
||||||
<input name="name" type="text" class="grow" placeholder="Subject" />
|
<input name="subject" type="text" class="grow" placeholder="Subject" />
|
||||||
</label>
|
|
||||||
<label class="form-control">
|
|
||||||
<div class="label">
|
|
||||||
<span class="label-text">What do you want to say?</span>
|
|
||||||
</div>
|
|
||||||
<textarea
|
|
||||||
name="message"
|
|
||||||
form="contact"
|
|
||||||
class="textarea textarea-bordered h-24"
|
|
||||||
placeholder="Hello friend..."
|
|
||||||
></textarea>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
</div>
|
<textarea
|
||||||
|
name="message"
|
||||||
|
form="contact"
|
||||||
|
class="textarea textarea-bordered h-full min-w-xl resize-none"
|
||||||
|
placeholder="Message"
|
||||||
|
></textarea>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary">Send Message</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue