Add ContactIconBlock and revamp contact form
Implemented a new ContactIconBlock in the UI, including its Astro file and related props. Also added various form input components including EmailContactInput, PhoneInput, and PasswordInput for a more comprehensive contact section. Updated ContactSection with the new input fields and improved structure for better user experience and functionality.
This commit is contained in:
parent
443597b15d
commit
b8097da9ab
12 changed files with 705 additions and 0 deletions
177
src/components/ContactSection.astro
Normal file
177
src/components/ContactSection.astro
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
---
|
||||||
|
// Import the necessary dependencies from individual component files
|
||||||
|
import AuthBtn from "./ui/buttons/AuthBtn.astro";
|
||||||
|
import ContactIconBlock from "./ui/blocks/ContactIconBlock.astro";
|
||||||
|
import TextInput from "./ui/forms/input/TextInput.astro";
|
||||||
|
import EmailContactInput from "./ui/forms/input/EmailContactInput.astro";
|
||||||
|
import PhoneInput from "./ui/forms/input/PhoneInput.astro";
|
||||||
|
import TextAreaInput from "./ui/forms/input/TextAreaInput.astro";
|
||||||
|
|
||||||
|
// Variables for customization of the HeroSection2 Component
|
||||||
|
// Main heading
|
||||||
|
const title: string = "Contact us";
|
||||||
|
|
||||||
|
// Sub-heading text
|
||||||
|
const subTitle: string =
|
||||||
|
"Have questions or want to discuss a project? Reach out, and let's craft the perfect solution with our tools and services.";
|
||||||
|
|
||||||
|
// Form heading text
|
||||||
|
const formTitle: string = "Fill in the form below";
|
||||||
|
|
||||||
|
// Form sub-heading text
|
||||||
|
const formSubTitle: string = "We'll get back to you in 1-2 business days.";
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Contact Us -->
|
||||||
|
<div class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14">
|
||||||
|
<div class="mx-auto max-w-2xl lg:max-w-5xl">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1
|
||||||
|
class="text-balance text-2xl font-bold tracking-tight text-neutral-800 dark:text-neutral-200 md:text-4xl md:leading-tight"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</h1>
|
||||||
|
<p class="mt-1 text-pretty text-neutral-600 dark:text-neutral-400">
|
||||||
|
{subTitle}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-12 grid items-center gap-6 lg:grid-cols-2 lg:gap-16">
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="flex flex-col rounded-xl p-4 sm:p-6 lg:p-8">
|
||||||
|
<h2
|
||||||
|
class="mb-8 text-xl font-bold text-neutral-700 dark:text-neutral-300"
|
||||||
|
>
|
||||||
|
{formTitle}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<div class="grid gap-4">
|
||||||
|
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||||
|
<TextInput
|
||||||
|
id="hs-firstname-contacts"
|
||||||
|
label="First Name"
|
||||||
|
name="hs-firstname-contacts"
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
id="hs-lastname-contacts"
|
||||||
|
label="Last Name"
|
||||||
|
name="hs-firstname-contacts"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<EmailContactInput id="hs-email-contacts" />
|
||||||
|
<PhoneInput id="hs-phone-number" />
|
||||||
|
<TextAreaInput
|
||||||
|
id="hs-about-contacts"
|
||||||
|
label="Details"
|
||||||
|
name="hs-about-contacts"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-4 grid">
|
||||||
|
<AuthBtn title="Send Message" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3 text-center">
|
||||||
|
<p class="text-sm text-neutral-600 dark:text-neutral-400">
|
||||||
|
{formSubTitle}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
|
||||||
|
<div class="divide-y divide-neutral-300 dark:divide-neutral-700">
|
||||||
|
<ContactIconBlock
|
||||||
|
heading="Knowledgebase"
|
||||||
|
content="Browse through all of our knowledgebase articles."
|
||||||
|
link={true}
|
||||||
|
linkTitle="Visit guides & tutorials"
|
||||||
|
linkURL="#"
|
||||||
|
arrow={true}
|
||||||
|
><svg
|
||||||
|
class="mt-1.5 h-6 w-6 flex-shrink-0 text-neutral-600 dark:text-neutral-400"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</ContactIconBlock>
|
||||||
|
|
||||||
|
<ContactIconBlock
|
||||||
|
heading="FAQ"
|
||||||
|
content="Explore our FAQ for quick, clear answers to common queries."
|
||||||
|
link={true}
|
||||||
|
linkTitle="Visit FAQ"
|
||||||
|
linkURL="#"
|
||||||
|
arrow={true}
|
||||||
|
><svg
|
||||||
|
class="mt-1.5 h-6 w-6 flex-shrink-0 text-neutral-600 dark:text-neutral-400"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 0 1-.825-.242m9.345-8.334a2.126 2.126 0 0 0-.476-.095 48.64 48.64 0 0 0-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0 0 11.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</ContactIconBlock>
|
||||||
|
|
||||||
|
<ContactIconBlock
|
||||||
|
heading="Visit our office"
|
||||||
|
content="UK ScrewFast"
|
||||||
|
address={true}
|
||||||
|
addressContent="72 Union Terrace, E10 4PE London"
|
||||||
|
><svg
|
||||||
|
class="mt-1.5 h-6 w-6 flex-shrink-0 text-neutral-600 dark:text-neutral-400"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"></path>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1 1 15 0Z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</ContactIconBlock>
|
||||||
|
|
||||||
|
<ContactIconBlock
|
||||||
|
heading="Contact us by email"
|
||||||
|
content="Prefer the written word? Drop us an email at"
|
||||||
|
link={true}
|
||||||
|
linkTitle="support@screwfast.uk"
|
||||||
|
linkURL="#"
|
||||||
|
><svg
|
||||||
|
class="mt-1.5 h-6 w-6 flex-shrink-0 text-neutral-600 dark:text-neutral-400"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M21.75 9v.906a2.25 2.25 0 0 1-1.183 1.981l-6.478 3.488M2.25 9v.906a2.25 2.25 0 0 0 1.183 1.981l6.478 3.488m8.839 2.51-4.66-2.51m0 0-1.023-.55a2.25 2.25 0 0 0-2.134 0l-1.022.55m0 0-4.661 2.51m16.5 1.615a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V8.844a2.25 2.25 0 0 1 1.183-1.981l7.5-4.039a2.25 2.25 0 0 1 2.134 0l7.5 4.039a2.25 2.25 0 0 1 1.183 1.98V19.5Z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</ContactIconBlock>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Contact Us -->
|
63
src/components/ui/blocks/ContactIconBlock.astro
Normal file
63
src/components/ui/blocks/ContactIconBlock.astro
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
---
|
||||||
|
const {
|
||||||
|
heading,
|
||||||
|
content,
|
||||||
|
address,
|
||||||
|
addressContent,
|
||||||
|
link,
|
||||||
|
linkTitle,
|
||||||
|
linkURL,
|
||||||
|
arrow,
|
||||||
|
} = Astro.props;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
heading?: string;
|
||||||
|
content?: string;
|
||||||
|
address?: boolean;
|
||||||
|
addressContent?: string;
|
||||||
|
link?: boolean;
|
||||||
|
linkTitle?: string;
|
||||||
|
linkURL?: string;
|
||||||
|
arrow?: boolean;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="flex gap-x-7 py-6">
|
||||||
|
<slot />
|
||||||
|
<div class="grow">
|
||||||
|
<h3 class="font-bold text-neutral-700 dark:text-neutral-300">
|
||||||
|
{heading}
|
||||||
|
</h3>
|
||||||
|
<p class="mt-1 text-sm text-neutral-600 dark:text-neutral-400">{content}</p>
|
||||||
|
{
|
||||||
|
address ? (
|
||||||
|
<p class="mt-1 text-sm italic text-neutral-500">{addressContent}</p>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
{
|
||||||
|
link ? (
|
||||||
|
<a
|
||||||
|
class="group mt-2 inline-flex items-center gap-x-2 rounded-lg text-sm font-medium text-zinc-600 outline-none ring-zinc-500 transition duration-300 hover:text-zinc-800 focus-visible:ring dark:text-zinc-400 dark:ring-zinc-200 dark:hover:text-zinc-200 dark:focus:outline-none dark:focus:ring-1 "
|
||||||
|
href={linkURL}
|
||||||
|
>
|
||||||
|
{linkTitle}
|
||||||
|
{arrow ? (
|
||||||
|
<svg
|
||||||
|
class="h-4 w-4 flex-shrink-0 transition ease-in-out group-hover:translate-x-1"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
) : null}
|
||||||
|
</a>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
85
src/components/ui/forms/LoginModal.astro
Normal file
85
src/components/ui/forms/LoginModal.astro
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
---
|
||||||
|
// Import the necessary dependencies from individual component files
|
||||||
|
import GoogleBtn from "../buttons/GoogleBtn.astro";
|
||||||
|
import AuthBtn from "../buttons/AuthBtn.astro";
|
||||||
|
import EmailInput from "./input/EmailInput.astro";
|
||||||
|
import PasswordInput from "./input/PasswordInput.astro";
|
||||||
|
import Checkbox from "./input/Checkbox.astro";
|
||||||
|
|
||||||
|
// Variables for customization of the LoginModal Component
|
||||||
|
// Modal identifier
|
||||||
|
const id = "hs-toggle-between-modals-login-modal";
|
||||||
|
|
||||||
|
// Main heading
|
||||||
|
const title: string = "Sign in";
|
||||||
|
|
||||||
|
// Sub-heading text
|
||||||
|
const subTitle: string = "Don't have an account yet?";
|
||||||
|
|
||||||
|
// Text for registration button
|
||||||
|
const registerBtn: string = "Sign up here";
|
||||||
|
|
||||||
|
// Target link for registration button
|
||||||
|
const registerBtnDataHS: string = "#hs-toggle-between-modals-register-modal";
|
||||||
|
---
|
||||||
|
|
||||||
|
<div
|
||||||
|
id={id}
|
||||||
|
class="hs-overlay absolute start-0 top-0 z-50 hidden h-full w-full hs-overlay-backdrop-open:bg-neutral-900/90"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="m-3 mt-0 opacity-0 transition-all ease-out hs-overlay-open:mt-7 hs-overlay-open:opacity-100 hs-overlay-open:duration-500 sm:mx-auto sm:w-full sm:max-w-lg"
|
||||||
|
>
|
||||||
|
<div class="mx-auto w-full max-w-md p-6">
|
||||||
|
<div
|
||||||
|
class="mt-7 rounded-xl border border-neutral-200 bg-neutral-100 shadow-sm dark:border-neutral-700 dark:bg-neutral-800"
|
||||||
|
>
|
||||||
|
<div class="p-4 sm:p-7">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1
|
||||||
|
class="block text-2xl font-bold text-neutral-800 dark:text-neutral-200"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</h1>
|
||||||
|
<p class="mt-2 text-sm text-neutral-600 dark:text-neutral-400">
|
||||||
|
{subTitle}
|
||||||
|
<button
|
||||||
|
class="rounded-lg p-1 font-medium text-[#fa5a15] decoration-2 outline-none ring-zinc-500 hover:underline focus-visible:ring dark:text-[#fa5a15] dark:ring-zinc-200 dark:focus:outline-none"
|
||||||
|
data-hs-overlay={registerBtnDataHS}
|
||||||
|
>
|
||||||
|
{registerBtn}
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="mt-5">
|
||||||
|
<GoogleBtn title="Sign in with Google" />
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex items-center py-3 text-xs uppercase text-neutral-400 before:me-6 before:flex-[1_1_0%] before:border-t before:border-neutral-200 after:ms-6 after:flex-[1_1_0%] after:border-t after:border-neutral-200 dark:text-neutral-500 dark:before:border-neutral-600 dark:after:border-neutral-600"
|
||||||
|
>
|
||||||
|
Or
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<div class="grid gap-y-4">
|
||||||
|
<EmailInput id="login-email" />
|
||||||
|
|
||||||
|
<PasswordInput
|
||||||
|
forgot={true}
|
||||||
|
id="password"
|
||||||
|
;
|
||||||
|
errorId="password-error"
|
||||||
|
content="8+ characters required"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Checkbox id="remember-me" />
|
||||||
|
|
||||||
|
<AuthBtn title="Sign in" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
64
src/components/ui/forms/RecoverModal.astro
Normal file
64
src/components/ui/forms/RecoverModal.astro
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
---
|
||||||
|
// Import the necessary dependencies from individual component files
|
||||||
|
import AuthBtn from "../buttons/AuthBtn.astro";
|
||||||
|
import EmailInput from "./input/EmailInput.astro";
|
||||||
|
|
||||||
|
// Variables to customize the RecoverModal Component
|
||||||
|
|
||||||
|
// Modal identifier
|
||||||
|
const id = "hs-toggle-between-modals-recover-modal";
|
||||||
|
|
||||||
|
// Main heading
|
||||||
|
const title: string = "Forgot password?";
|
||||||
|
|
||||||
|
// Sub-heading text
|
||||||
|
const subTitle: string = "Remember your password?";
|
||||||
|
|
||||||
|
// Text and target link for the login button
|
||||||
|
const loginBtn: string = "Sign in here";
|
||||||
|
const loginBtnDataHS: string = "#hs-toggle-between-modals-login-modal";
|
||||||
|
---
|
||||||
|
|
||||||
|
<div
|
||||||
|
id={id}
|
||||||
|
class="hs-overlay absolute start-0 top-0 z-50 hidden h-full w-full hs-overlay-backdrop-open:bg-neutral-900/90"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="m-3 mt-0 opacity-0 transition-all ease-out hs-overlay-open:mt-7 hs-overlay-open:opacity-100 hs-overlay-open:duration-500 sm:mx-auto sm:w-full sm:max-w-lg"
|
||||||
|
>
|
||||||
|
<div class="mx-auto w-full max-w-md p-6">
|
||||||
|
<div
|
||||||
|
class="mt-7 rounded-xl border border-neutral-200 bg-neutral-100 shadow-sm dark:border-neutral-700 dark:bg-neutral-800"
|
||||||
|
>
|
||||||
|
<div class="p-4 sm:p-7">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1
|
||||||
|
class="block text-2xl font-bold text-neutral-800 dark:text-neutral-200"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</h1>
|
||||||
|
<p class="mt-2 text-sm text-neutral-600 dark:text-neutral-400">
|
||||||
|
{subTitle}
|
||||||
|
<button
|
||||||
|
class="rounded-lg p-1 font-medium text-[#fa5a15] decoration-2 outline-none ring-zinc-500 hover:underline focus-visible:ring dark:text-[#fa5a15] dark:ring-zinc-200 dark:focus:outline-none"
|
||||||
|
data-hs-overlay={loginBtnDataHS}
|
||||||
|
>
|
||||||
|
{loginBtn}
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-5">
|
||||||
|
<!-- Form -->
|
||||||
|
<form>
|
||||||
|
<div class="grid gap-y-4">
|
||||||
|
<EmailInput id="recover-email" />
|
||||||
|
<AuthBtn title="Reset password" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
96
src/components/ui/forms/RegisterModal.astro
Normal file
96
src/components/ui/forms/RegisterModal.astro
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
---
|
||||||
|
// Import the necessary dependencies from individual component files
|
||||||
|
import GoogleBtn from "../buttons/GoogleBtn.astro";
|
||||||
|
import AuthBtn from "../buttons/AuthBtn.astro";
|
||||||
|
import EmailInput from "./input/EmailInput.astro";
|
||||||
|
import PasswordInput from "./input/PasswordInput.astro";
|
||||||
|
import Checkbox from "./input/Checkbox.astro";
|
||||||
|
|
||||||
|
// Variables to customize the RegisterModal Component
|
||||||
|
|
||||||
|
// Modal identifier
|
||||||
|
const id = "hs-toggle-between-modals-register-modal";
|
||||||
|
|
||||||
|
// Main title
|
||||||
|
const title: string = "Sign up";
|
||||||
|
|
||||||
|
// Subtitle text
|
||||||
|
const subTitle: string = "Already have an account?";
|
||||||
|
|
||||||
|
// Text and target link for the login button
|
||||||
|
const loginBtn: string = "Sign in here";
|
||||||
|
const loginBtnDataHS: string = "#hs-toggle-between-modals-login-modal";
|
||||||
|
---
|
||||||
|
|
||||||
|
<div
|
||||||
|
id={id}
|
||||||
|
class="hs-overlay absolute start-0 top-0 z-50 hidden h-full w-full hs-overlay-backdrop-open:bg-neutral-900/90"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="m-3 mt-0 opacity-0 transition-all ease-out hs-overlay-open:mt-7 hs-overlay-open:opacity-100 hs-overlay-open:duration-500 sm:mx-auto sm:w-full sm:max-w-lg"
|
||||||
|
>
|
||||||
|
<div class="mx-auto w-full max-w-md p-6">
|
||||||
|
<div
|
||||||
|
class="mt-7 max-h-full overflow-hidden rounded-xl border border-neutral-200 bg-neutral-100 shadow-sm dark:border-neutral-700 dark:bg-neutral-800"
|
||||||
|
>
|
||||||
|
<div class="p-4 sm:p-7">
|
||||||
|
<div class="text-center">
|
||||||
|
<h1
|
||||||
|
class="block text-2xl font-bold text-neutral-800 dark:text-neutral-200"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</h1>
|
||||||
|
<p class="mt-2 text-sm text-neutral-600 dark:text-neutral-400">
|
||||||
|
{subTitle}
|
||||||
|
<button
|
||||||
|
class="rounded-lg p-1 font-medium text-[#fa5a15] decoration-2 outline-none ring-zinc-500 hover:underline focus-visible:ring dark:text-[#fa5a15] dark:ring-zinc-200 dark:focus:outline-none"
|
||||||
|
data-hs-overlay={loginBtnDataHS}
|
||||||
|
>
|
||||||
|
{loginBtn}
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-5">
|
||||||
|
<GoogleBtn title="Sign up with Google" />
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex items-center py-3 text-xs uppercase text-neutral-400 before:me-6 before:flex-[1_1_0%] before:border-t before:border-neutral-200 after:ms-6 after:flex-[1_1_0%] after:border-t after:border-neutral-200 dark:text-neutral-500 dark:before:border-neutral-600 dark:after:border-neutral-600"
|
||||||
|
>
|
||||||
|
Or
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<div class="grid gap-y-4">
|
||||||
|
<EmailInput id="register-email" />
|
||||||
|
<PasswordInput
|
||||||
|
id="create-password"
|
||||||
|
;
|
||||||
|
errorId="password-error"
|
||||||
|
content="8+ characters required"
|
||||||
|
/>
|
||||||
|
<PasswordInput
|
||||||
|
label="Confirm Password"
|
||||||
|
id="confirm-password"
|
||||||
|
;
|
||||||
|
errorId="confirm-password-error"
|
||||||
|
aria="confirm-password-error"
|
||||||
|
content="Password does not match the password"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Checkbox label="I accept the " , id="terms-agree">
|
||||||
|
<a
|
||||||
|
class="font-medium text-[#fa5a15] decoration-2 hover:underline dark:text-[#fa5a15] dark:focus:outline-none"
|
||||||
|
href="#">Terms and Conditions</a
|
||||||
|
>
|
||||||
|
</Checkbox>
|
||||||
|
|
||||||
|
<AuthBtn title="Sign up" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
20
src/components/ui/forms/input/EmailContactInput.astro
Normal file
20
src/components/ui/forms/input/EmailContactInput.astro
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
const { label = "Email", id } = Astro.props;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
label?: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for={id} class="sr-only">{label}</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="hs-email-contacts"
|
||||||
|
id={id}
|
||||||
|
autocomplete="email"
|
||||||
|
class="block w-full rounded-lg border border-neutral-200 bg-neutral-50 px-4 py-3 text-sm text-neutral-700 placeholder:text-neutral-500 focus:border-neutral-200 focus:outline-none focus:ring focus:ring-neutral-400 disabled:pointer-events-none disabled:opacity-50 dark:border-neutral-600 dark:bg-neutral-700/30 dark:text-neutral-300 dark:placeholder:text-neutral-400 dark:focus:ring-1"
|
||||||
|
placeholder="Email"
|
||||||
|
/>
|
||||||
|
</div>
|
30
src/components/ui/forms/input/EmailFooterInput.astro
Normal file
30
src/components/ui/forms/input/EmailFooterInput.astro
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
const { label = "Search", title = "Subscribe", id = "footer-input" } = Astro.props;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
label?: string;
|
||||||
|
title?: string;
|
||||||
|
id?: string;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="mt-4 flex flex-col items-center gap-2 rounded-lg bg-neutral-200 p-2 dark:bg-neutral-800 sm:flex-row sm:gap-3"
|
||||||
|
>
|
||||||
|
<div class="w-full">
|
||||||
|
<label for={id} class="sr-only">{label}</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id={id}
|
||||||
|
name="footer-input"
|
||||||
|
class="block w-full rounded-lg border-transparent bg-neutral-100 px-4 py-3 text-sm text-neutral-600 focus:border-[#fa5a15] focus:ring-[#fa5a15] disabled:pointer-events-none disabled:opacity-50 dark:border-transparent dark:bg-neutral-700 dark:text-gray-300 dark:placeholder:text-neutral-300"
|
||||||
|
placeholder="Enter your email"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<a
|
||||||
|
class="inline-flex w-full items-center justify-center gap-x-2 whitespace-nowrap rounded-lg border border-transparent bg-[#fa5a15] p-3 text-sm font-bold text-neutral-50 outline-none ring-zinc-500 transition duration-300 hover:bg-[#e14d0b] focus-visible:ring disabled:pointer-events-none disabled:opacity-50 dark:ring-zinc-200 dark:focus:outline-none dark:focus:ring-1 sm:w-auto"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</a>
|
||||||
|
</div>
|
44
src/components/ui/forms/input/EmailInput.astro
Normal file
44
src/components/ui/forms/input/EmailInput.astro
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
const { label = "Email address", id } = Astro.props;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
label?: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
for={id}
|
||||||
|
class="mb-2 block text-sm text-neutral-800 dark:text-neutral-200"
|
||||||
|
>{label}</label
|
||||||
|
>
|
||||||
|
<div class="relative">
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
id={id}
|
||||||
|
name="email"
|
||||||
|
autocomplete="email"
|
||||||
|
class="block w-full rounded-lg border border-neutral-200 bg-neutral-50 px-4 py-3 text-sm text-neutral-700 focus:border-neutral-200 focus:outline-none focus:ring focus:ring-neutral-400 disabled:pointer-events-none disabled:opacity-50 dark:border-neutral-600 dark:bg-neutral-700/30 dark:text-neutral-300 dark:focus:ring-1"
|
||||||
|
required
|
||||||
|
aria-describedby="email-error"
|
||||||
|
/>
|
||||||
|
<div class="pointer-events-none absolute inset-y-0 end-0 hidden pe-3">
|
||||||
|
<svg
|
||||||
|
class="h-5 w-5 text-red-500"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="mt-2 hidden text-xs text-red-600" id="email-error">
|
||||||
|
Please include a valid email address so we can get back to you
|
||||||
|
</p>
|
||||||
|
</div>
|
68
src/components/ui/forms/input/PasswordInput.astro
Normal file
68
src/components/ui/forms/input/PasswordInput.astro
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
---
|
||||||
|
const {
|
||||||
|
label = "Password",
|
||||||
|
forgot,
|
||||||
|
id,
|
||||||
|
errorId,
|
||||||
|
content,
|
||||||
|
aria = "password-error",
|
||||||
|
} = Astro.props;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
label?: string;
|
||||||
|
forgot?: boolean;
|
||||||
|
id?: string;
|
||||||
|
errorId?: string;
|
||||||
|
content?: string;
|
||||||
|
aria?: string;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<label
|
||||||
|
for={id}
|
||||||
|
class="mb-2 block text-sm text-neutral-800 dark:text-neutral-200"
|
||||||
|
>{label}</label
|
||||||
|
>
|
||||||
|
{
|
||||||
|
forgot ? (
|
||||||
|
<button
|
||||||
|
class="text-sm font-medium text-[#fa5a15] decoration-2 outline-none ring-zinc-500 hover:underline focus-visible:ring dark:text-[#fa5a15] dark:ring-zinc-200 dark:focus:outline-none dark:focus:ring-1"
|
||||||
|
data-hs-overlay="#hs-toggle-between-modals-recover-modal"
|
||||||
|
>
|
||||||
|
Forgot password?
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="relative">
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
id={id}
|
||||||
|
name="password"
|
||||||
|
class="block w-full rounded-lg border border-neutral-200 bg-neutral-50 px-4 py-3 text-sm text-neutral-700 focus:border-neutral-200 focus:outline-none focus:ring focus:ring-neutral-400 disabled:pointer-events-none disabled:opacity-50 dark:border-neutral-600 dark:bg-neutral-700/30 dark:text-neutral-300 dark:focus:ring-1"
|
||||||
|
required
|
||||||
|
aria-describedby={aria}
|
||||||
|
/>
|
||||||
|
<div class="pointer-events-none absolute inset-y-0 end-0 hidden pe-3">
|
||||||
|
<svg
|
||||||
|
class="h-5 w-5 text-red-500"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="mt-2 hidden text-xs text-red-600" id={errorId}>
|
||||||
|
{content}
|
||||||
|
</p>
|
||||||
|
</div>
|
19
src/components/ui/forms/input/PhoneInput.astro
Normal file
19
src/components/ui/forms/input/PhoneInput.astro
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
const { label = "Phone Number", id } = Astro.props;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
label?: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for={id} class="sr-only">{label}</label>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
name="hs-phone-number"
|
||||||
|
id={id}
|
||||||
|
class="block w-full rounded-lg border border-neutral-200 bg-neutral-50 px-4 py-3 text-sm text-neutral-700 placeholder:text-neutral-500 focus:border-neutral-200 focus:outline-none focus:ring focus:ring-neutral-400 disabled:pointer-events-none disabled:opacity-50 dark:border-neutral-600 dark:bg-neutral-700/30 dark:text-neutral-300 dark:placeholder:text-neutral-400 dark:focus:ring-1"
|
||||||
|
placeholder={label}
|
||||||
|
/>
|
||||||
|
</div>
|
19
src/components/ui/forms/input/TextAreaInput.astro
Normal file
19
src/components/ui/forms/input/TextAreaInput.astro
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
const { label, id, name } = Astro.props;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
label: string;
|
||||||
|
name: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="hs-about-contacts-1" class="sr-only">{label}</label>
|
||||||
|
<textarea
|
||||||
|
id={id}
|
||||||
|
name={name}
|
||||||
|
rows="4"
|
||||||
|
class="block w-full rounded-lg border border-neutral-200 bg-neutral-50 px-4 py-3 text-sm text-neutral-700 placeholder:text-neutral-500 focus:border-neutral-200 focus:outline-none focus:ring focus:ring-neutral-400 disabled:pointer-events-none disabled:opacity-50 dark:border-neutral-600 dark:bg-neutral-700/30 dark:text-neutral-300 dark:placeholder:text-neutral-400 dark:focus:ring-1"
|
||||||
|
placeholder={label}></textarea>
|
||||||
|
</div>
|
20
src/components/ui/forms/input/TextInput.astro
Normal file
20
src/components/ui/forms/input/TextInput.astro
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
const { label, id, name } = Astro.props;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
label: string;
|
||||||
|
name: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for={id} class="sr-only">{label}</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name={name}
|
||||||
|
id={id}
|
||||||
|
class="block w-full rounded-lg border border-neutral-200 bg-neutral-50 px-4 py-3 text-sm text-neutral-700 placeholder:text-neutral-500 focus:border-neutral-200 focus:outline-none focus:ring focus:ring-neutral-400 disabled:pointer-events-none disabled:opacity-50 dark:border-neutral-600 dark:bg-neutral-700/30 dark:text-neutral-300 dark:placeholder:text-neutral-400 dark:focus:ring-1"
|
||||||
|
placeholder={label}
|
||||||
|
/>
|
||||||
|
</div>
|
Loading…
Add table
Reference in a new issue