Create a contact component
This commit is contained in:
86
src/components/ui/Form.astro
Normal file
86
src/components/ui/Form.astro
Normal 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>
|
40
src/components/widgets/Contact.astro
Normal file
40
src/components/widgets/Contact.astro
Normal 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>
|
@ -1,11 +1,35 @@
|
||||
---
|
||||
import Layout from '~/layouts/PageLayout.astro';
|
||||
import ContactUs from '~/components/widgets/Contact.astro';
|
||||
|
||||
const metadata = {
|
||||
title: "Contact",
|
||||
title: 'Contact',
|
||||
};
|
||||
---
|
||||
|
||||
<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>
|
||||
|
28
src/types.d.ts
vendored
28
src/types.d.ts
vendored
@ -153,6 +153,24 @@ export interface Testimonial {
|
||||
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
|
||||
export interface CallToAction {
|
||||
targetBlank?: boolean;
|
||||
@ -177,6 +195,14 @@ export interface Collapse {
|
||||
classes?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface Form {
|
||||
inputs?: Array<Input>;
|
||||
textarea?: Textarea;
|
||||
disclaimer?: Disclaimer;
|
||||
button?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
// WIDGETS
|
||||
export interface Hero extends Headline, Widget {
|
||||
content?: string;
|
||||
@ -247,3 +273,5 @@ export interface Content extends Headline, Widget {
|
||||
isReversed?: boolean;
|
||||
isAfterContent?: boolean;
|
||||
}
|
||||
|
||||
export interface Contact extends Headline, Form, Widget {}
|
||||
|
Reference in New Issue
Block a user