summaryrefslogtreecommitdiff
path: root/src/routes/contact
diff options
context:
space:
mode:
authorLogan Hunt <loganhunt@simponic.xyz>2022-05-03 15:57:42 -0600
committerLogan Hunt <loganhunt@simponic.xyz>2022-05-03 15:57:42 -0600
commita48a2c7f7ea1ac650ce1817af704bdf5138a9e73 (patch)
tree85b45b931bb3399620a695de0a6adc6e3746760b /src/routes/contact
parentf0d8562b7ba671fa6dd60867c542be3ed52758bf (diff)
downloadmistymountainstherapy-a48a2c7f7ea1ac650ce1817af704bdf5138a9e73.tar.gz
mistymountainstherapy-a48a2c7f7ea1ac650ce1817af704bdf5138a9e73.zip
Add contact page
Diffstat (limited to 'src/routes/contact')
-rw-r--r--src/routes/contact/index.svelte128
-rw-r--r--src/routes/contact/submit.js69
2 files changed, 193 insertions, 4 deletions
diff --git a/src/routes/contact/index.svelte b/src/routes/contact/index.svelte
index cbedec9..84d9621 100644
--- a/src/routes/contact/index.svelte
+++ b/src/routes/contact/index.svelte
@@ -1,8 +1,128 @@
-<main>
- <div class="h-captcha" data-sitekey={import.meta.env.VITE_HCAPTCHA_KEY}></div>
+<script context="module">
+ import { browser } from '$app/env';
+ import { toast } from '@zerodevx/svelte-toast'
+ import HCaptcha from 'svelte-hcaptcha';
+ let submission = {
+ name: '',
+ email: '',
+ message: '',
+ captchaToken: '',
+ };
- <script src="https://js.hcaptcha.com/1/api.js" async defer></script>
-</main>
+ let captcha;
+
+ function handleSubmit (e) {
+ e.preventDefault();
+
+ if (browser) {
+ const sendToast = toast.push('Sending...', {
+ duration: 300,
+ initial: 0,
+ next: 0.2,
+ dismissable: false
+ });
+ fetch('/contact/submit', {
+ method: "POST",
+ body: JSON.stringify(submission)
+ })
+ .then((x) => x.json())
+ .then((x) => {
+ toast.set(sendToast, { next: 1 });
+
+ if (x.success) {
+ toast.push('Success! Reloading...', {
+ theme: {
+ '--toastBackground': '#48BB78',
+ '--toastBarBackground': '#2F855A'
+ },
+ duration: 1000,
+ onpop: () => { window.location.reload(); },
+ });
+ } else if (x.error) {
+ toast.push(x.error, {
+ theme: {
+ '--toastBackground': '#F56565',
+ '--toastBarBackground': '#C53030'
+ }
+ });
+ }
+ })
+ .catch((err) => console.log(err));
+ }
+ }
+ function onCaptchaError () {
+ toast.push('Failed to verify captcha, try again.', {
+ theme: {
+ '--toastBackground': '#F56565',
+ '--toastBarBackground': '#C53030'
+ }
+ });
+ captcha.reset();
+ }
+
+ function onCaptchaSuccess ({ detail: { token } }) {
+ submission.captchaToken = token;
+ }
+</script>
+
+<main>
+ <h1 class="text-center">Let's get in touch</h1>
+ <div class="d-flex justify-content-center flex-row row">
+ <div class="border shadow bg-light py-2 col-lg-3 d-flex align-items-center flex-column m-2">
+ <h1><i class="bi bi-map-fill"></i></h1>
+ <p style="hyphens: auto;">
+ <a href="https://goo.gl/maps/DdkzDQTRHBTtG8ys6">534 Trejo Street, Suite 200F
+ <br>
+ Rexburg, ID, 83440
+ </a>
+ </p>
+ </div>
+ <div class="border shadow bg-light py-2 col-lg-2 d-flex align-items-center flex-column m-2">
+ <h1><i class="bi bi-phone-fill"></i></h1>
+ <p style="hyphens: auto;">
+ Call or text
+ <br>
+ <a href="tel:15306383546">(530) 638 - 3546</a>
+ </p>
+ </div>
+ <div class="border shadow bg-light py-2 col-lg-3 d-flex align-items-center flex-column m-2">
+ <h1><i class="bi bi-envelope-fill"></i></h1>
+ <p style="hyphens: auto;">
+ Email
+ <br>
+ <a href="mailto:jeffer@mistymountainsthreapy.com">jeffer@mistymountainstherapy.com</a>
+ </p>
+ </div>
+ </div>
+ <br>
+ <h3>Or send us a message</h3>
+ <form class="bg-light border shadow p-4" on:submit|preventDefault={handleSubmit}>
+ <div class="row mb-2">
+ <div class="form-group col-md-6">
+ <label>Email *</label>
+ <input type="email" class="form-control" bind:value={submission.email} placeholder="johnnyappleseed@example.com" required>
+ </div>
+ <div class="form-group col-md-6">
+ <label>Name *</label>
+ <input type="text" class="form-control" bind:value={submission.name} placeholder="Johnny Appleseed" required>
+ </div>
+ </div>
+ <div class="form-group">
+ <label>Message *</label>
+ <textarea class="form-control" bind:value={submission.message} rows="3" placeholder="Hello! I would like to schedule a free 15-minute consultation..." required></textarea>
+ </div>
+ <div class="pt-2">
+ <HCaptcha
+ sitekey={import.meta.env.VITE_HCAPTCHA_KEY}
+ bind:this={captcha}
+ on:success={onCaptchaSuccess}
+ on:error={onCaptchaError}
+ />
+ </div>
+ <button type="submit" class="btn btn-primary">Submit</button>
+ </form>
+ <br>
+</main>
diff --git a/src/routes/contact/submit.js b/src/routes/contact/submit.js
new file mode 100644
index 0000000..cf0d65c
--- /dev/null
+++ b/src/routes/contact/submit.js
@@ -0,0 +1,69 @@
+import 'dotenv/config';
+import sgMail from '@sendgrid/mail';
+sgMail.setApiKey(process.env.SENDGRID_API_KEY);
+
+export async function get() {
+ const items = [
+ {a: 1, b: 2},
+ {a: 3, b: 4},
+ {a: 5, b: 6},
+ ];
+ return {
+ body: items
+ };
+}
+
+export async function post({ request }) {
+ const body = await request.json();
+ const { HCAPTCHA_SECRET, FORM_FROM_EMAIL, FORM_TO_EMAIL } = process.env;
+
+ const captchaVerified = await fetch(`https://hcaptcha.com/siteverify?response=${body.captchaToken}&secret=${HCAPTCHA_SECRET}`, {
+ method: 'POST',
+ })
+ .then((res) => res.json())
+ .then((json) => json.success)
+ .catch(() => false);
+
+ if (!captchaVerified) {
+ return {
+ statusCode: 400,
+ body: {
+ error: 'Captcha verification failed',
+ },
+ };
+ }
+
+ const msg = {
+ to: FORM_TO_EMAIL,
+ from: FORM_FROM_EMAIL,
+ subject: `Form Submission from ${body.name}`,
+ text: `
+ Name: ${body.name}
+ Email: ${body.email}
+ Message: ${body.message}
+ `,
+ };
+
+ const messageSent = await sgMail
+ .send(msg)
+ .then(() => true)
+ .catch((error) => {
+ console.error(error);
+ return false;
+ });
+
+ if (!messageSent) {
+ return {
+ statusCode: 500,
+ body: {
+ error: 'Message could not be sent',
+ },
+ };
+ }
+
+ return {
+ body: {
+ success: true,
+ },
+ };
+}