Added contact form
This commit is contained in:
@@ -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"
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
<div>
|
class="grid md:grid-cols-2 md:gap-4"
|
||||||
<label class="flex flex-col mb-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>
|
<span class="text-slate-400">{$t('contact.message')}</span>
|
||||||
<textarea
|
<textarea
|
||||||
|
name="message"
|
||||||
rows="5"
|
rows="5"
|
||||||
|
autocomplete="off"
|
||||||
|
bind:value={form.message}
|
||||||
|
class="md:h-full"
|
||||||
></textarea>
|
></textarea>
|
||||||
|
{#if attemptedSubmit && errorSlugs.message}
|
||||||
|
<span class="text-sm text-red-500 absolute top-full">{$t(errorSlugs.message)}</span>
|
||||||
|
{/if}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<label class="flex flex-col mb-4">
|
<label class="relative flex flex-col mb-6">
|
||||||
<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>
|
||||||
</div>
|
<button
|
||||||
<button class="p-4 mt-5 bg-slate-300 rounded-lg text-lg text-slate-950 font-semibold">
|
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')}
|
{$t('contact.submit')}
|
||||||
|
{:else}
|
||||||
|
{$t('contact.submitted')}
|
||||||
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user