Skip to content

Commit 65aa6c0

Browse files
committed
fix form & add toast
1 parent 3f95a13 commit 65aa6c0

4 files changed

Lines changed: 65 additions & 29 deletions

File tree

eslint.config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import globals from 'globals';
44
export default [
55
// add more generic rule sets here, such as:
66
// js.configs.recommended,
7-
...eslintPluginSvelte.configs['flat/recommended'],
87
{
98
rules: {
109
// override/add rules settings here, such as:

src/app.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!doctype html>
1+
<!DOCTYPE html>
22
<html lang="en" class="dark">
33
<head>
44
<meta charset="utf-8" />

src/lib/components/Contact.svelte

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,89 @@
11
<script>
22
import { Section } from '$lib/utils';
3-
import { IconMailFilled, IconPhoneFilled, IconMapPinFilled } from '@tabler/icons-svelte';
4-
import { dev } from '$app/environment';
3+
import { getToastStore } from '@skeletonlabs/skeleton';
4+
import { IconMailFilled, IconMapPinFilled } from '@tabler/icons-svelte';
55
6-
const formSpree = import.meta.env.VITE_FORMSPREE;
6+
const env = import.meta.env.VITE_ENV ?? 'development';
7+
const formSpree = import.meta.env.VITE_FORMSPREE ?? '#';
8+
const toast = getToastStore();
79
810
let firstname = '';
911
let lastname = '';
1012
let email = '';
1113
let phone = '';
1214
let message = '';
13-
let status = '';
1415
15-
async function handleSubmit(event) {
16-
const data = new FormData(event.target);
17-
if (dev) {
18-
status = 'Thanks for your submission!';
16+
function clearForm() {
17+
firstname = '';
18+
lastname = '';
19+
email = '';
20+
phone = '';
21+
message = '';
22+
}
23+
24+
function validateEmail(email) {
25+
const re = /\S+@\S+\.\S+/;
26+
return re.test(email);
27+
}
28+
29+
function triggerToast(message, type = 'success') {
30+
let background;
31+
switch (type) {
32+
case 'success':
33+
background = 'variant-filled-success';
34+
break;
35+
case 'error':
36+
background = 'variant-filled-error';
37+
break;
38+
default:
39+
background = 'variant-filled-success';
40+
}
41+
const t = {
42+
message,
43+
background,
44+
timeout: 2500
45+
};
46+
toast.trigger(t);
47+
}
48+
49+
async function handleSubmit(_event) {
50+
if (env === 'development') {
51+
triggerToast('Thanks for your submission!', 'success');
52+
clearForm();
1953
return;
2054
}
2155
try {
22-
const response = await fetch(event.target.action, {
56+
if (!validateEmail(email)) {
57+
triggerToast('Please enter a valid email address', 'error');
58+
return;
59+
}
60+
const response = await fetch(formSpree, {
2361
method: 'POST',
24-
body: data,
62+
body: {
63+
firstname,
64+
lastname,
65+
email,
66+
phone,
67+
message
68+
},
2569
headers: {
2670
Accept: 'application/json'
2771
}
2872
});
2973
if (response.ok) {
30-
status = 'Thanks for your submission!';
31-
firstname = '';
32-
lastname = '';
33-
email = '';
34-
phone = '';
35-
message = '';
74+
triggerToast('Thanks for your submission!', 'success');
75+
clearForm();
3676
} else {
3777
const data = await response.json();
3878
if (Object.hasOwn(data, 'errors')) {
39-
status = data['errors'].map((error) => error['message']).join(', ');
79+
const errorMessages = data['errors'].map((error) => error['message']).join(', ');
80+
triggerToast(errorMessages, 'error');
4081
} else {
41-
status = 'Oops! There was a problem submitting your form';
82+
triggerToast('Oops! There was a problem submitting your form', 'error');
4283
}
4384
}
4485
} catch (error) {
45-
status = 'Oops! There was a problem submitting your form';
86+
triggerToast('Oops! There was a problem submitting your form', 'error');
4687
}
4788
}
4889
</script>
@@ -55,16 +96,12 @@
5596
<div
5697
class="w-auto gap-4 mx-auto border-transparent rounded-md sm:p-1 lg:w-3/5 opacity-95 bg-slate-100 md:flex md:grid-cols-2"
5798
>
58-
<div class="p-6 text-white rounded-t-md sm:rounded-md bg-surface-600 lg:w-1/3">
99+
<div class="p-6 text-white rounded-t-md text-wrap sm:rounded-md bg-surface-600 lg:w-1/3">
59100
<header class="font-medium card-header h3">Contact Information</header>
60101
<section class="grid gap-5 mt-8 lg:mt-10 lg:gap-10">
61-
<div class="flex gap-5">
62-
<IconPhoneFilled />
63-
<span>+685 1234567</span>
64-
</div>
65102
<div class="flex gap-5">
66103
<IconMailFilled />
67-
<span>admin@sch.com</span>
104+
<span class="break-normal">samoastackoverflow@gmail.com</span>
68105
</div>
69106
<div class="flex gap-5">
70107
<IconMapPinFilled />
@@ -143,7 +180,6 @@
143180
<div class="mx-2 mt-2 mb-6 text-white bg-blue-500 rounded-xl md:justify-self-end btn">
144181
<button type="submit"> Send message </button>
145182
</div>
146-
<p class="text-blue-600">{status}</p>
147183
</form>
148184
</div>
149185
</section>

src/routes/+layout.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script>
22
import '../app.postcss';
3-
import { AppShell } from '@skeletonlabs/skeleton';
3+
import { AppShell, Toast } from '@skeletonlabs/skeleton';
44
import Footer from '$lib/components/Footer.svelte';
55
66
import { computePosition, autoUpdate, flip, shift, offset, arrow } from '@floating-ui/dom';
@@ -36,6 +36,7 @@
3636
</svelte:fragment>
3737
<svelte:fragment slot="sidebarLeft">
3838
<Sidebar bind:toggleSidebar />
39+
<Toast />
3940
</svelte:fragment>
4041
<!-- Page Route Content -->
4142
<slot />

0 commit comments

Comments
 (0)