Last active
December 15, 2023 23:41
-
-
Save jonshipman/3d1864084394577a587389be7520b43a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts"> | |
import { applyAction, enhance } from '$app/forms'; | |
import { page } from '$app/stores'; | |
import { RoofGraphic } from '$lib/graphics'; | |
import { fade } from 'svelte/transition'; | |
import type { ActionUpdate, Result } from './form.svelte.d'; | |
import Button from './button.svelte'; | |
import Field from './field.svelte'; | |
import { EmailIcon, MessageIcon, NameIcon, PhoneIcon } from './icons'; | |
import { FormStore, type FormDataInterface } from './store'; | |
export let action = '/contact/'; | |
$: error = $page.form?.error || ''; | |
$: success = $page.form?.success || ''; | |
let className = ''; | |
function handleCloseError() { | |
error = ''; | |
} | |
function handleSubmit({ formData }: { formData: FormData }) { | |
const data = Object.fromEntries(formData) as unknown; | |
FormStore.set(data as FormDataInterface); | |
return ({ update, result }: { update: ActionUpdate; result: Result }) => { | |
return update().then(() => applyAction(result)); | |
}; | |
} | |
export { className as class }; | |
</script> | |
<form {action} method="POST" class={className} use:enhance={handleSubmit}> | |
<div class="px-4 pb-4 pt-8 rounded-lg border-gray-300 border bg-white relative"> | |
{#if error || success} | |
<div transition:fade class="flex items-center justify-center relative text-center"> | |
<div class="z-10 absolute bottom-16 max-w-5xl mx-auto w-full"> | |
{#if error} | |
<div | |
class="mb-4 last:mb-0 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded" | |
role="alert" | |
> | |
{@html error} | |
<span class="absolute top-0 bottom-0 right-0 px-4 py-3"> | |
<svg | |
on:click|stopPropagation={handleCloseError} | |
on:keydown|stopPropagation={handleCloseError} | |
tabindex={0} | |
class="fill-current h-6 w-6 text-red-500" | |
role="button" | |
xmlns="http://www.w3.org/2000/svg" | |
viewBox="0 0 20 20" | |
> | |
<title>Close</title> | |
<path | |
d="M14.348 14.849a1.2 1.2 0 0 1-1.697 0L10 11.819l-2.651 3.029a1.2 1.2 0 1 1-1.697-1.697l2.758-3.15-2.759-3.152a1.2 1.2 0 1 1 1.697-1.697L10 8.183l2.651-3.031a1.2 1.2 0 1 1 1.697 1.697l-2.758 3.152 2.758 3.15a1.2 1.2 0 0 1 0 1.698z" | |
/> | |
</svg> | |
</span> | |
</div> | |
{/if} | |
{#if success} | |
<div | |
class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded" | |
role="alert" | |
> | |
{@html success} | |
</div> | |
{/if} | |
</div> | |
</div> | |
{/if} | |
<slot> | |
<div class="flex flex-col md:grid gap-4 grid-cols-4"> | |
<Field tabindex={2} name="name" placeholder="Name" required> | |
<svelte:fragment slot="icon"> | |
<NameIcon /> | |
</svelte:fragment> | |
</Field> | |
<Field tabindex={2} name="phone" type="tel" placeholder="Phone"> | |
<svelte:fragment slot="icon"> | |
<PhoneIcon /> | |
</svelte:fragment> | |
</Field> | |
<Field tabindex={2} name="email" type="email" placeholder="Email" required> | |
<svelte:fragment slot="icon"> | |
<EmailIcon /> | |
</svelte:fragment> | |
</Field> | |
<div class="order-last md:order-none"> | |
<Button class="w-full" tabindex={3}>Get a Free Quote</Button> | |
</div> | |
<div class="spanning-message"> | |
<Field tabindex={2} name="message" placeholder="Message"> | |
<svelte:fragment slot="icon"> | |
<MessageIcon /> | |
</svelte:fragment> | |
</Field> | |
</div> | |
</div> | |
</slot> | |
</div> | |
</form> | |
<style> | |
.spanning-message { | |
grid-area: 2 / 1 / 3 / 4; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment