Added contact form
All checks were successful
Deploy / build-and-publish (push) Successful in 1m18s
Deploy / deploy (push) Successful in 13s

This commit is contained in:
2024-09-29 18:23:41 +03:00
parent 47f367c96b
commit 0e72c78174
5 changed files with 125 additions and 22 deletions

View File

@@ -49,6 +49,18 @@
"description": "Facts about sleep, background noise generator with the ability to share and select sounds from the community, dream log." "description": "Facts about sleep, background noise generator with the ability to share and select sounds from the community, dream log."
} }
}, },
"contact": {
"h": "Contact me",
"email": "Email",
"name": "Your name",
"message": "Message",
"submit": "Submit",
"submitted": "Message successfully sent!",
"errors": {
"required": "Required field",
"email": "Enter a valid email"
}
},
"footer": { "footer": {
"made_with": "Made with SvelteKit and Tailwind", "made_with": "Made with SvelteKit and Tailwind",
"go_back": "Go back in time" "go_back": "Go back in time"

View File

@@ -54,7 +54,12 @@
"email": "Email", "email": "Email",
"name": "Ваше имя", "name": "Ваше имя",
"message": "Сообщение", "message": "Сообщение",
"submit": "Отправить" "submit": "Отправить",
"submitted": "Сообщение успешно отправлено!",
"errors": {
"required": "Обязательное поле",
"email": "Введите валидный email"
}
}, },
"footer": { "footer": {
"made_with": "Сделано с SvelteKit и Tailwind", "made_with": "Сделано с SvelteKit и Tailwind",

View File

@@ -33,12 +33,12 @@
:global(input, textarea) { :global(input, textarea) {
font-size: 18px; font-size: 18px;
transition: border .3s; transition: border .3s;
@apply px-3 py-3 rounded-lg bg-slate-700 text-slate-400 border border-slate-500; @apply px-3 py-3 rounded-lg bg-slate-950 text-slate-400 border border-slate-500;
} }
:global(input:focus, textarea:focus) { :global(input:focus, textarea:focus) {
outline: none; outline: none;
border: 1px solid theme(colors.blue.500); border: 1px solid theme(colors.slate.50);
} }
:global(textarea) { :global(textarea) {

View File

@@ -4,7 +4,7 @@
import About from "./About.svelte"; import About from "./About.svelte";
import Projects from "./Projects/Projects.svelte"; import Projects from "./Projects/Projects.svelte";
import Footer from "./Footer.svelte"; import Footer from "./Footer.svelte";
// import ContactForm from "./ContactForm/ContactForm.svelte"; import ContactForm from "./ContactForm/ContactForm.svelte";
export let data; export let data;
</script> </script>
@@ -14,6 +14,6 @@
<Hero starCount={data.starCount}></Hero> <Hero starCount={data.starCount}></Hero>
<About></About> <About></About>
<Projects></Projects> <Projects></Projects>
<!-- <ContactForm></ContactForm>--> <ContactForm></ContactForm>
<Footer></Footer> <Footer></Footer>
</main> </main>

View File

@@ -1,5 +1,59 @@
<script> <script lang="ts">
import {t} from "$lib/translations"; import {t} from "$lib/translations";
let attemptedSubmit = false;
let submitted = false;
let form: {
message: string
name: string
email: string
} = {
message: '',
name: '',
email: ''
}
$: errorSlugs = ((): {
message: string | null
name: string | null
email: string | null
} => {
let message = null
let name = null
let email = null
if (form.message.trim() === '') message = 'contact.errors.required'
if (form.name.trim() === '') name = 'contact.errors.required'
if (form.email.trim() === '') email = 'contact.errors.required'
if (!form.email.includes('@') || form.email.endsWith('@')) email = 'contact.errors.email'
return {
message,
name,
email
}
})()
$: invalid = Object.values(errorSlugs).some(slug => slug !== null)
const handleSubmit = () => {
attemptedSubmit = true
if (invalid) return
submitted = true
const formData = new FormData()
formData.append('message', form.message)
formData.append('name', form.name)
formData.append('email', form.email)
fetch(
'https://send.pageclip.co/ipMETNW8CCV8ka21myU6D22bvnOAV0Ag',
{
method: 'POST',
body: formData
}
)
}
</script> </script>
<section class="px-2 md:px-8 mb-16 max-w-[1280px] mx-auto"> <section class="px-2 md:px-8 mb-16 max-w-[1280px] mx-auto">
@@ -7,27 +61,59 @@ import {t} from "$lib/translations";
{$t('contact.h')} {$t('contact.h')}
</h2> </h2>
<form class="grid"> <form
class="grid md:grid-cols-2 md:gap-4"
on:submit|preventDefault={handleSubmit}
>
<label class="relative flex flex-col mb-6 md:mb-0">
<span class="text-slate-400">{$t('contact.message')}</span>
<textarea
name="message"
rows="5"
autocomplete="off"
bind:value={form.message}
class="md:h-full"
></textarea>
{#if attemptedSubmit && errorSlugs.message}
<span class="text-sm text-red-500 absolute top-full">{$t(errorSlugs.message)}</span>
{/if}
</label>
<div> <div>
<label class="flex flex-col mb-4"> <label class="relative flex flex-col mb-6">
<span class="text-slate-400">{$t('contact.message')}</span>
<textarea
rows="5"
></textarea>
</label>
</div>
<div>
<label class="flex flex-col mb-4">
<span class="text-slate-400">{$t('contact.name')}</span> <span class="text-slate-400">{$t('contact.name')}</span>
<input type="text" /> <input
name="name"
type="text"
autocomplete="off"
bind:value={form.name}
/>
{#if attemptedSubmit && errorSlugs.name}
<span class="text-sm text-red-500 absolute top-full">{$t(errorSlugs.name)}</span>
{/if}
</label> </label>
<label class="flex flex-col mb-4"> <label class="relative flex flex-col mb-6">
<span class="text-slate-400">{$t('contact.email')}</span> <span class="text-slate-400">{$t('contact.email')}</span>
<input type="email" /> <input
name="email"
type="email"
autocomplete="off"
bind:value={form.email}
/>
{#if attemptedSubmit && errorSlugs.email}
<span class="text-sm text-red-500 absolute top-full">{$t(errorSlugs.email)}</span>
{/if}
</label> </label>
<button
class="p-4 mt-5 bg-slate-50 rounded-lg text-lg text-slate-950 font-semibold w-full hover:bg-white disabled:bg-slate-300"
disabled={invalid && attemptedSubmit}
>
{#if !submitted}
{$t('contact.submit')}
{:else}
{$t('contact.submitted')}
{/if}
</button>
</div> </div>
<button class="p-4 mt-5 bg-slate-300 rounded-lg text-lg text-slate-950 font-semibold">
{$t('contact.submit')}
</button>
</form> </form>
</section> </section>