Create a contact component

This commit is contained in:
widgeter
2023-08-11 17:50:09 +02:00
parent fbbdda64e7
commit 5dbdf84dd7
4 changed files with 180 additions and 2 deletions

View File

@ -0,0 +1,86 @@
---
import { Form } from '~/types';
const { inputs, textarea, disclaimer, button = 'Contact us', description = '' } = Astro.props as Form;
---
<form>
{
inputs &&
inputs.map(
({ type = 'text', name, label = '', autocomplete = 'on', placeholder = '' }) =>
name && (
<div class="mb-6">
{label && (
<label for={name} class="block text-sm font-medium">
{label}
</label>
)}
<input
type={type}
name={name}
id={name}
autocomplete={autocomplete}
placeholder={placeholder}
class="py-3 px-4 block w-full text-md rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-slate-900"
/>
</div>
)
)
}
{
textarea && (
<div>
<label for="textarea" class="block text-sm font-medium">
{textarea.label}
</label>
<textarea
id="textarea"
name="textarea"
rows={textarea.rows ? textarea.rows : 4}
placeholder={textarea.placeholder}
class="py-3 px-4 block w-full text-md rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-slate-900"
/>
</div>
)
}
{
disclaimer && (
<div class="mt-3 flex items-start">
<div class="flex mt-0.5">
<input
id="disclaimer"
name="disclaimer"
type="checkbox"
class="cursor-pointer mt-1 py-3 px-4 block w-full text-md rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-slate-900"
/>
</div>
<div class="ml-3">
<label for="disclaimer" class="cursor-pointer select-none text-sm text-gray-600 dark:text-gray-400">
{disclaimer.label}
</label>
</div>
</div>
)
}
{
button && (
<div class="mt-10 grid">
<button type="submit" class="btn btn-primary cursor-pointer">
{button}
</button>
</div>
)
}
{
description && (
<div class="mt-3 text-center">
<p class="text-sm text-gray-600 dark:text-gray-400">{description}</p>
</div>
)
}
</form>

View File

@ -0,0 +1,40 @@
---
import FormContainer from '~/components/ui/Form.astro';
import Headline from '~/components/ui/Headline.astro';
import WidgetWrapper from '~/components/ui/WidgetWrapper.astro';
import { Contact } from '~/types';
const {
title = await Astro.slots.render('title'),
subtitle = await Astro.slots.render('subtitle'),
tagline = await Astro.slots.render('tagline'),
inputs,
textarea,
disclaimer,
button,
description,
id,
isDark = false,
classes = {},
bg = await Astro.slots.render('bg'),
} = Astro.props as Contact;
---
<WidgetWrapper id={id} isDark={isDark} containerClass={`max-w-screen-xl mx-auto ${classes?.container ?? ''}`} bg={bg}>
<Headline title={title} subtitle={subtitle} tagline={tagline} />
{
inputs && (
<div class="flex flex-col max-w-xl mx-auto rounded-lg backdrop-blur border border-gray-200 dark:border-gray-700 bg-white dark:bg-slate-900 shadow p-4 sm:p-6 lg:p-8 w-full">
<FormContainer
inputs={inputs}
textarea={textarea}
disclaimer={disclaimer}
button={button}
description={description}
/>
</div>
)
}
</WidgetWrapper>

View File

@ -1,11 +1,35 @@
--- ---
import Layout from '~/layouts/PageLayout.astro'; import Layout from '~/layouts/PageLayout.astro';
import ContactUs from '~/components/widgets/Contact.astro';
const metadata = { const metadata = {
title: "Contact", title: 'Contact',
}; };
--- ---
<Layout metadata={metadata}> <Layout metadata={metadata}>
Contact <ContactUs
title="Drop us a message today!"
subtitle="We are delighted that you've reached out to us with your questions, inquiries, or concerns. Your queries matter to us, and we're committed to providing you with the best possible support."
inputs={[
{
type: 'text',
name: 'name',
label: 'Name',
},
{
type: 'email',
name: 'email',
label: 'Email',
},
]}
textarea={{
label: 'Message',
}}
disclaimer={{
label:
'By submitting this contact form, you acknowledge and agree to the collection of your personal information.',
}}
description="Our support team typically responds within 24 business hours."
/>
</Layout> </Layout>

28
src/types.d.ts vendored
View File

@ -153,6 +153,24 @@ export interface Testimonial {
image?: string | unknown; image?: string | unknown;
} }
export interface Input {
type: HTMLInputTypeAttribute;
name: string;
label?: string;
autocomplete?: string;
placeholder?: string;
}
export interface Textarea {
label?: string;
placeholder?: string;
rows?: number;
}
export interface Disclaimer {
label?: string;
}
// COMPONENTS // COMPONENTS
export interface CallToAction { export interface CallToAction {
targetBlank?: boolean; targetBlank?: boolean;
@ -177,6 +195,14 @@ export interface Collapse {
classes?: Record<string, string>; classes?: Record<string, string>;
} }
export interface Form {
inputs?: Array<Input>;
textarea?: Textarea;
disclaimer?: Disclaimer;
button?: string;
description?: string;
}
// WIDGETS // WIDGETS
export interface Hero extends Headline, Widget { export interface Hero extends Headline, Widget {
content?: string; content?: string;
@ -247,3 +273,5 @@ export interface Content extends Headline, Widget {
isReversed?: boolean; isReversed?: boolean;
isAfterContent?: boolean; isAfterContent?: boolean;
} }
export interface Contact extends Headline, Form, Widget {}