Update component codebase for readability and maintenance

Several component files have been refactored to improve code clarity and ease of maintenance. This includes introducing comprehensive comments explaining the functionality and purpose of sections of the code, as well as leveraging Astro.js for more streamlined data sourcing. The commit also includes the removal of redundant files from the vendor scripts directory as part of a general clean-up, improving overall codebase organization.
This commit is contained in:
Emil Gulamov 2024-02-18 07:39:53 +04:00
parent 04e8089294
commit c2dda2165b
15 changed files with 142 additions and 83 deletions

View file

@ -1,9 +1,6 @@
--- ---
// Variables for customization of the LoginModal Component // Define the variables that will be used in this component
// Main heading
const title: string = "Trusted by Industry Leaders"; const title: string = "Trusted by Industry Leaders";
// Sub-heading text
const subTitle: string = const subTitle: string =
"Experience the reliability chosen by industry giants."; "Experience the reliability chosen by industry giants.";
--- ---
@ -12,19 +9,21 @@ const subTitle: string =
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full" class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
> >
<!-- Title and description --> <!-- Title and description -->
<div class="mx-auto mb-6 w-2/3 space-y-1 text-center sm:w-1/2 lg:w-1/3"> <div class="mx-auto mb-6 w-full space-y-1 text-center sm:w-1/2 lg:w-1/3">
<h2 <h2
class="text-balance text-xl font-bold text-neutral-800 dark:text-neutral-200 md:text-2xl leading-tight" class="text-balance text-xl font-bold leading-tight text-neutral-800 dark:text-neutral-200 md:text-2xl"
> >
{title} {title}
</h2> </h2>
<p class="text-pretty text-neutral-600 dark:text-neutral-400 leading-tight"> <p class="text-pretty leading-tight text-neutral-600 dark:text-neutral-400">
{subTitle} {subTitle}
</p> </p>
</div> </div>
<div class="flex justify-center gap-x-6 sm:gap-x-12 lg:gap-x-24"> <div
class="flex flex-col items-center justify-center gap-x-6 sm:flex-row sm:gap-x-12 lg:gap-x-24"
>
<!-- Clients Group SVGs --> <!-- Clients Group SVGs -->
<!-- First --> <!-- First -->
<svg <svg
@ -56,7 +55,7 @@ const subTitle: string =
d="m2.615 15.132 13.656 2.412 6.726-1.514c-1.617-7-7.482-11.59-13.095-10.326-4.36.98-6.705 4.619-7.287 9.428Z" d="m2.615 15.132 13.656 2.412 6.726-1.514c-1.617-7-7.482-11.59-13.095-10.326-4.36.98-6.705 4.619-7.287 9.428Z"
></path> ></path>
<mask <mask
id="b" id="p"
width="21" width="21"
height="26" height="26"
x="2" x="2"
@ -69,7 +68,7 @@ const subTitle: string =
d="M9.902 5.704c-5.296 1.193-7.616 6.323-7.42 12.667l13.79 11.881 6.726-14.222c-1.618-7-7.475-11.59-13.096-10.326Z" d="M9.902 5.704c-5.296 1.193-7.616 6.323-7.42 12.667l13.79 11.881 6.726-14.222c-1.618-7-7.475-11.59-13.096-10.326Z"
></path> ></path>
</mask> </mask>
<g mask="url(#b)"> <g mask="url(#p)">
<path fill="#626773" d="M16.267 17.685H0v.15h16.267v-.15Z"></path> <path fill="#626773" d="M16.267 17.685H0v.15h16.267v-.15Z"></path>
<path <path
fill="#626773" fill="#626773"
@ -2490,7 +2489,7 @@ const subTitle: string =
<!-- Fourth --> <!-- Fourth -->
<svg <svg
class="mx-auto h-auto w-24 py-3 sm:mx-0 md:w-32 lg:w-40 lg:py-5" class="mx-auto h-auto w-24 py-3 sm:mx-0 md:w-32 lg:w-40 lg:py-5"
viewBox="0 0 150 42" viewBox="0 0 100 42"
fill="none" fill="none"
> >
<path <path

View file

@ -1,5 +1,5 @@
--- ---
// Import the necessary dependencies from individual component files // Import the necessary dependencies.
import AuthBtn from "./ui/buttons/AuthBtn.astro"; import AuthBtn from "./ui/buttons/AuthBtn.astro";
import ContactIconBlock from "./ui/blocks/ContactIconBlock.astro"; import ContactIconBlock from "./ui/blocks/ContactIconBlock.astro";
import TextInput from "./ui/forms/input/TextInput.astro"; import TextInput from "./ui/forms/input/TextInput.astro";
@ -7,18 +7,13 @@ import EmailContactInput from "./ui/forms/input/EmailContactInput.astro";
import PhoneInput from "./ui/forms/input/PhoneInput.astro"; import PhoneInput from "./ui/forms/input/PhoneInput.astro";
import TextAreaInput from "./ui/forms/input/TextAreaInput.astro"; import TextAreaInput from "./ui/forms/input/TextAreaInput.astro";
// Variables for customization of the HeroSection2 Component // Define the variables that will be used in this component
// Main heading
const title: string = "Contact us"; const title: string = "Contact us";
// Sub-heading text
const subTitle: string = 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."; "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"; 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."; const formSubTitle: string = "We'll get back to you in 1-2 business days.";
--- ---
@ -37,14 +32,14 @@ const formSubTitle: string = "We'll get back to you in 1-2 business days.";
</div> </div>
<div class="mt-12 grid items-center gap-6 lg:grid-cols-2 lg:gap-16"> <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"> <div class="flex flex-col rounded-xl p-4 sm:p-6 lg:p-8">
<h2 <h2
class="mb-8 text-xl font-bold text-neutral-700 dark:text-neutral-300" class="mb-8 text-xl font-bold text-neutral-700 dark:text-neutral-300"
> >
{formTitle} {formTitle}
</h2> </h2>
<!-- Form for user input with various input fields.-->
<!-- Each field utilizes a different input component for the specific type of input (text, email, phone, and textarea)-->
<form> <form>
<div class="grid gap-4"> <div class="grid gap-4">
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
@ -79,8 +74,8 @@ const formSubTitle: string = "We'll get back to you in 1-2 business days.";
</div> </div>
</form> </form>
</div> </div>
<!-- End Card -->
<!--ContactIconBlocks are used to display different methods of contacting, including visiting office, email, browsing knowledgebase, and FAQ.-->
<div class="divide-y divide-neutral-300 dark:divide-neutral-700"> <div class="divide-y divide-neutral-300 dark:divide-neutral-700">
<ContactIconBlock <ContactIconBlock
heading="Knowledgebase" heading="Knowledgebase"
@ -174,4 +169,3 @@ const formSubTitle: string = "We'll get back to you in 1-2 business days.";
</div> </div>
</div> </div>
</div> </div>
<!-- End Contact Us -->

View file

@ -1,15 +1,16 @@
--- ---
// Import the necessary AccordionItem component
import AccordionItem from "./ui/blocks/AccordionItem.astro"; import AccordionItem from "./ui/blocks/AccordionItem.astro";
// Define the string variable `subTitle` to provide additional information.
const subTitle: string = const subTitle: string =
"Ask us anything about our brand and products, and get factual responses."; "Ask us anything about our brand and products, and get factual responses.";
// Helper function to generate ids // Define a helper function to generate ids dynamically.
const makeId = (base: any, index: any) => `${base}${index + 1}`; const makeId = (base: any, index: any) => `${base}${index + 1}`;
// Define an array `faqs` that holds the content for the Frequently Asked Questions.
const faqs = [ const faqs = [
// Content of each FAQ item goes here
{ {
heading: "What types of tools are included in the Starter Kit?", heading: "What types of tools are included in the Starter Kit?",
content: content:
@ -45,7 +46,10 @@ const faqs = [
]; ];
--- ---
<div class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"> <!-- Main container that holds all content. Customized for different viewport sizes. -->
<div
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
>
<div class="grid gap-10 md:grid-cols-5"> <div class="grid gap-10 md:grid-cols-5">
<div class="md:col-span-2"> <div class="md:col-span-2">
<div class="max-w-xs"> <div class="max-w-xs">
@ -59,21 +63,37 @@ const faqs = [
</p> </p>
</div> </div>
</div> </div>
<!-- FAQ accordion items -->
<div class="md:col-span-3"> <div class="md:col-span-3">
<div <div
class="hs-accordion-group divide-y divide-neutral-200 dark:divide-neutral-700" class="hs-accordion-group divide-y divide-neutral-200 dark:divide-neutral-700"
> >
{faqs.map((question, i) => { {
// Generate ids dynamically faqs.map((question, i) => {
let id = makeId("hs-basic-with-title-and-arrow-stretched-heading-", i); // Generate ids dynamically for each FAQ accordion item.
let collapseId = makeId("hs-basic-with-title-and-arrow-stretched-collapse", i); let id = makeId(
"hs-basic-with-title-and-arrow-stretched-heading-",
i,
);
let collapseId = makeId(
"hs-basic-with-title-and-arrow-stretched-collapse",
i,
);
return <AccordionItem {...question} id={id} collapseId={collapseId} first={i === 0} /> return (
})} <AccordionItem
{...question}
id={id}
collapseId={collapseId}
first={i === 0}
/>
);
})
}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!--Import the necessary Accordion plugin-->
<!--https://preline.co/plugins/html/accordion.html-->
<script is:inline src="/scripts/vendor/preline/accordion/index.js"></script> <script is:inline src="/scripts/vendor/preline/accordion/index.js"></script>

View file

@ -1,13 +1,11 @@
--- ---
// Import the necessary dependencies from individual component files // Import the necessary dependencies
import { Image } from "astro:assets"; import { Image } from "astro:assets";
import featureImage from "../images/features-image.avif"; import featureImage from "../images/features-image.avif";
import IconBlock from "./ui/blocks/IconBlock.astro"; import IconBlock from "./ui/blocks/IconBlock.astro";
// Main heading // Define the string variables `title` and `subTitle` for the main heading and sub-heading text respectively.
const title: string = "Meeting Industry Demands"; const title: string = "Meeting Industry Demands";
// Sub-heading text
const subTitle: string = const subTitle: string =
"At ScrewFast, we tackle the unique challenges encountered in the hardware and construction sectors. From cutting-edge tools to expert services, we're dedicated to helping you overcome obstacles and achieve your goals."; "At ScrewFast, we tackle the unique challenges encountered in the hardware and construction sectors. From cutting-edge tools to expert services, we're dedicated to helping you overcome obstacles and achieve your goals.";
--- ---
@ -15,7 +13,7 @@ const subTitle: string =
<div <div
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full" class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
> >
<!-- Showing an Image --> <!-- Block to display the feature image -->
<div class="relative mb-6 overflow-hidden md:mb-8"> <div class="relative mb-6 overflow-hidden md:mb-8">
<Image <Image
src={featureImage} src={featureImage}
@ -26,16 +24,17 @@ const subTitle: string =
/> />
</div> </div>
<!-- Render title, subtitle and the various IconBlock instances --> <!-- Displaying the main content consisting of title, subtitle, and several `IconBlock` components -->
<div class="mt-5 grid gap-8 lg:mt-16 lg:grid-cols-3 lg:gap-12"> <div class="mt-5 grid gap-8 lg:mt-16 lg:grid-cols-3 lg:gap-12">
<!-- Block for title and subtitle -->
<div class="lg:col-span-1"> <div class="lg:col-span-1">
<!-- Title Block --> <!-- Rendering title -->
<h2 <h2
class="text-balance text-2xl font-bold text-neutral-800 dark:text-neutral-200 md:text-3xl" class="text-balance text-2xl font-bold text-neutral-800 dark:text-neutral-200 md:text-3xl"
> >
{title} {title}
</h2> </h2>
<!-- Sub Title Block --> <!-- Rendering subtitle -->
<p <p
class="mt-2 text-pretty text-neutral-600 dark:text-neutral-400 md:mt-4" class="mt-2 text-pretty text-neutral-600 dark:text-neutral-400 md:mt-4"
> >
@ -43,9 +42,10 @@ const subTitle: string =
</p> </p>
</div> </div>
<!-- Render a grid of IconBlocks --> <!-- Block to display the IconBlock components -->
<div class="lg:col-span-2"> <div class="lg:col-span-2">
<div class="grid gap-8 sm:grid-cols-2 md:gap-12"> <div class="grid gap-8 sm:grid-cols-2 md:gap-12">
<!-- Injecting IconBlock components with different properties -->
<!-- IconBlock #1 --> <!-- IconBlock #1 -->
<IconBlock <IconBlock
heading="Dedicated Teams" heading="Dedicated Teams"

View file

@ -1,12 +1,12 @@
--- ---
// Import the necessary dependencies from individual component files // Import the necessary dependencies
import TabNav from "./ui/blocks/TabNav.astro"; import TabNav from "./ui/blocks/TabNav.astro";
import TabContent from "./ui/blocks/TabContent.astro"; import TabContent from "./ui/blocks/TabContent.astro";
import construction from "../images/construction-image.avif"; import construction from "../images/construction-image.avif";
import tools from "../images/automated-tools.avif"; import tools from "../images/automated-tools.avif";
import dashboard from "../images/dashboard-image.avif"; import dashboard from "../images/dashboard-image.avif";
// Main heading // Define the variable for the section's heading
const title: string = `Customize <span class="text-yellow-500 dark:text-yellow-400">ScrewFast</span>'s offerings to perfectly suit your hardware and construction needs.`; const title: string = `Customize <span class="text-yellow-500 dark:text-yellow-400">ScrewFast</span>'s offerings to perfectly suit your hardware and construction needs.`;
--- ---
@ -17,7 +17,7 @@ const title: string = `Customize <span class="text-yellow-500 dark:text-yellow-4
<div <div
class="relative z-10 lg:grid lg:grid-cols-12 lg:items-center lg:gap-16" class="relative z-10 lg:grid lg:grid-cols-12 lg:items-center lg:gap-16"
> >
<!-- Text contents of the section --> <!-- Section's heading and tab navigation -->
<div class="mb-10 lg:order-2 lg:col-span-6 lg:col-start-8 lg:mb-0"> <div class="mb-10 lg:order-2 lg:col-span-6 lg:col-start-8 lg:mb-0">
<h2 <h2
class="text-2xl font-bold text-neutral-800 dark:text-neutral-200 sm:text-3xl" class="text-2xl font-bold text-neutral-800 dark:text-neutral-200 sm:text-3xl"
@ -126,4 +126,6 @@ const title: string = `Customize <span class="text-yellow-500 dark:text-yellow-4
</div> </div>
</div> </div>
</div> </div>
<!--Import the necessary Tabs plugin-->
<!--https://preline.co/plugins/html/tabs.html-->
<script is:inline src="/scripts/vendor/preline/tabs/index.js"></script> <script is:inline src="/scripts/vendor/preline/tabs/index.js"></script>

View file

@ -1,21 +1,22 @@
--- ---
// Import the necessary components
import StatsBig from "../components/ui/blocks/StatsBig.astro"; import StatsBig from "../components/ui/blocks/StatsBig.astro";
import StatsSmall from "../components/ui/blocks/StatsSmall.astro"; import StatsSmall from "../components/ui/blocks/StatsSmall.astro";
// Get values from Astro's builtin props
const { title, subTitle } = Astro.props; const { title, subTitle } = Astro.props;
// TypeScript interface for the properties
interface Props { interface Props {
title: string; title: string;
subTitle: string; subTitle: string;
} }
/* TypeScript type for testimonials. */ // TypeScript type for the statistics
type Stat = { type Stat = {
stat: string; stat: string;
description: string; description: string;
}; };
/* An array of testimonials, each being an object that conforms to the above `Testimonial` type. */ // An array of statistics, each being an object that conforms to the above `Stat` type
const stats: Stat[] = [ const stats: Stat[] = [
{ {
stat: "99.8%", stat: "99.8%",
@ -36,30 +37,36 @@ const stats: Stat[] = [
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full" class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
> >
<div class="max-w-screen-md"> <div class="max-w-screen-md">
<!-- Main title -->
<h2 <h2
class="mb-4 text-balance text-3xl font-extrabold tracking-tight text-neutral-800 dark:text-neutral-200" class="mb-4 text-balance text-3xl font-extrabold tracking-tight text-neutral-800 dark:text-neutral-200"
> >
{title} {title}
</h2> </h2>
<!-- Subtitle -->
<p <p
class="mb-16 max-w-prose text-pretty font-light text-neutral-600 dark:text-neutral-400 sm:text-xl" class="mb-16 max-w-prose text-pretty font-light text-neutral-600 dark:text-neutral-400 sm:text-xl"
> >
{subTitle} {subTitle}
</p> </p>
</div> </div>
<!-- Grid container for statistics -->
<div class="grid items-center gap-6 lg:grid-cols-12 lg:gap-12"> <div class="grid items-center gap-6 lg:grid-cols-12 lg:gap-12">
<!-- First grid item, showing a big statistics -->
<div class="lg:col-span-4"> <div class="lg:col-span-4">
<StatsBig <StatsBig
title="96%" title="96%"
subTitle="of our clients rate their experience with ScrewFast as exceptional" subTitle="of our clients rate their experience with ScrewFast as exceptional"
/> />
</div> </div>
<!-- Second grid item, showing multiple small statistics -->
<div <div
class="relative lg:col-span-8 lg:before:absolute lg:before:-start-12 lg:before:top-0 lg:before:h-full lg:before:w-px lg:before:bg-neutral-300 lg:before:dark:bg-neutral-700" class="relative lg:col-span-8 lg:before:absolute lg:before:-start-12 lg:before:top-0 lg:before:h-full lg:before:w-px lg:before:bg-neutral-300 lg:before:dark:bg-neutral-700"
> >
<div <div
class="grid grid-cols-2 gap-6 sm:gap-8 md:grid-cols-4 lg:grid-cols-3" class="grid grid-cols-2 gap-6 sm:gap-8 md:grid-cols-4 lg:grid-cols-3"
> >
<!-- Iterate over the 'stats' array and create a 'StatsSmall' component for each object in the array -->
{ {
stats.map((stat) => ( stats.map((stat) => (
<StatsSmall title={stat.stat} subTitle={stat.description} /> <StatsSmall title={stat.stat} subTitle={stat.description} />

View file

@ -14,7 +14,7 @@ const benefits: string[] = [
"Customer support dedicated to your project's success.", "Customer support dedicated to your project's success.",
]; ];
const ListItemMarker:string = `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="mt-0.5 h-6 w-6 text-[#fa5a15] dark:text-[#fb713b]"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/></svg>`; const ListItemMarker: string = `<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="mt-0.5 h-6 w-6 text-[#fa5a15] dark:text-[#fb713b]"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/></svg>`;
--- ---
<div <div
@ -37,11 +37,11 @@ const ListItemMarker:string = `<svg fill="none" viewBox="0 0 24 24" stroke-widt
{subTitle} {subTitle}
</p> </p>
</div> </div>
<ul role="list" class="space-y-2 sm:space-y-4"> <ul class="space-y-2 sm:space-y-4">
{ {
benefits.map((item) => ( benefits.map((item) => (
<li class="flex space-x-3"> <li class="flex space-x-3">
<Fragment set:html={ListItemMarker}/> <Fragment set:html={ListItemMarker} />
<span class="text-pretty text-sm font-medium text-neutral-600 dark:text-neutral-400 sm:text-base"> <span class="text-pretty text-sm font-medium text-neutral-600 dark:text-neutral-400 sm:text-base">
{item} {item}

View file

@ -1,5 +1,5 @@
--- ---
// Import the necessary dependencies from individual component files // Import the necessary dependencies
import FooterSocialLink from "./ui/links/FooterSocialLink.astro"; import FooterSocialLink from "./ui/links/FooterSocialLink.astro";
import EmailFooterInput from "./ui/forms/input/EmailFooterInput.astro"; import EmailFooterInput from "./ui/forms/input/EmailFooterInput.astro";
@ -8,7 +8,7 @@ const sectionOne: string = "Product";
const sectionTwo: string = "Company"; const sectionTwo: string = "Company";
const sectionThree: string = "Stay up to date"; const sectionThree: string = "Stay up to date";
/* `content` variable used to customise the email subscription content text. */ // Define the variables that will be used in this component
const content: string = const content: string =
"Stay updated with the latest tools and exclusive deals."; "Stay updated with the latest tools and exclusive deals.";
@ -18,7 +18,7 @@ type Links = {
url: string; url: string;
}; };
/* An array of links, each being an object that conforms to the above `Links` type. */ // An array of links for Product section
const product: Links[] = [ const product: Links[] = [
{ {
title: "Tools & Equipment", title: "Tools & Equipment",
@ -34,7 +34,7 @@ const product: Links[] = [
}, },
]; ];
/* An array of links, each being an object that conforms to the above `Links` type. */ // An array of links for Company section
const company: Links[] = [ const company: Links[] = [
{ {
title: "About us", title: "About us",
@ -183,8 +183,7 @@ const company: Links[] = [
> >
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<p class="text-sm text-neutral-600 dark:text-neutral-400"> <p class="text-sm text-neutral-600 dark:text-neutral-400">
© <span id="current-year"></span> ScrewFast. Crafted © <span id="current-year"></span> ScrewFast. Crafted by
by
<a <a
class="font-medium underline underline-offset-2 outline-none ring-zinc-500 transition duration-300 hover:text-neutral-700 hover:decoration-dashed focus:outline-none focus-visible:ring dark:ring-zinc-200 dark:hover:text-neutral-300" class="font-medium underline underline-offset-2 outline-none ring-zinc-500 transition duration-300 hover:text-neutral-700 hover:decoration-dashed focus:outline-none focus-visible:ring dark:ring-zinc-200 dark:hover:text-neutral-300"
href="https://sobstvennoai.dev" href="https://sobstvennoai.dev"

View file

@ -1,4 +1,5 @@
--- ---
// Define props from Astro
const { const {
heading, heading,
content, content,
@ -10,6 +11,7 @@ const {
isArrowVisible, isArrowVisible,
} = Astro.props; } = Astro.props;
// Define TypeScript interface for props
interface Props { interface Props {
heading?: string; heading?: string;
content?: string; content?: string;
@ -21,24 +23,32 @@ interface Props {
isArrowVisible?: boolean; isArrowVisible?: boolean;
} }
// Define SVG arrow to be used in the component
const arrowSVG: string = `<svg const arrowSVG: string = `<svg
class="h-4 w-4 flex-shrink-0 transition ease-in-out group-hover:translate-x-1" 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" > 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>`; <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" /> </svg>`;
--- ---
<!-- Root container, which arranges the heading and content -->
<div class="flex gap-x-7 py-6"> <div class="flex gap-x-7 py-6">
<!-- Slot to allow for extensibility of the component -->
<slot /> <slot />
<div class="grow"> <div class="grow">
<!-- Heading of the section -->
<h3 class="font-bold text-neutral-700 dark:text-neutral-300"> <h3 class="font-bold text-neutral-700 dark:text-neutral-300">
{heading} {heading}
</h3> </h3>
<!-- Content of the section -->
<p class="mt-1 text-sm text-neutral-600 dark:text-neutral-400">{content}</p> <p class="mt-1 text-sm text-neutral-600 dark:text-neutral-400">{content}</p>
<!-- Conditional rendering of address content if isAddressVisible is true -->
{ {
isAddressVisible ? ( isAddressVisible ? (
<p class="mt-1 text-sm italic text-neutral-500">{addressContent}</p> <p class="mt-1 text-sm italic text-neutral-500">{addressContent}</p>
) : null ) : null
} }
<!-- Conditional rendering of a link if isLinkVisible is true.
The link also conditionally includes an arrow SVG if isArrowVisible is true -->
{ {
isLinkVisible ? ( isLinkVisible ? (
<a <a

View file

@ -1,16 +1,28 @@
--- ---
// Extract label and id from Astro.props with default value for label
const { label = "Remember me", id } = Astro.props; const { label = "Remember me", id } = Astro.props;
// Define TypeScript interface for the properties
interface Props { interface Props {
label?: string; label?: string;
id?: string; id?: string;
} }
--- ---
<!-- Container for the checkbox and its label -->
<div class="flex items-center"> <div class="flex items-center">
<div class="flex"> <!-- Checkbox input -->
<input id={id} name="remember-me" type="checkbox" class="shrink-0 mt-0.5 border-neutral-200 rounded text-neutral-600 pointer-events-none focus:ring-yellow-400 dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-yellow-400 dark:checked:border-yellow-400 dark:focus:ring-offset-neutral-800"> <div class="flex">
</div> <input
<div class="ms-3"> id={id}
<label for={id} class="text-sm text-neutral-800 dark:text-neutral-200">{label} <slot /> </label> name="remember-me"
</div> type="checkbox"
class="pointer-events-none mt-0.5 shrink-0 rounded border-neutral-200 text-neutral-600 focus:ring-yellow-400 dark:border-neutral-700 dark:bg-neutral-800 dark:checked:border-yellow-400 dark:checked:bg-yellow-400 dark:focus:ring-offset-neutral-800"
/>
</div> </div>
<!-- Label for the checkbox -->
<div class="ms-3">
<label for={id} class="text-sm text-neutral-800 dark:text-neutral-200"
>{label} <slot />
</label>
</div>
</div>

View file

@ -1,14 +1,18 @@
--- ---
// Destructure the properties from Astro.props, setting default value for label
const { label = "Email", id } = Astro.props; const { label = "Email", id } = Astro.props;
// Define TypeScript interface for the properties
interface Props { interface Props {
label?: string; label?: string;
id: string; id: string;
} }
--- ---
<!-- Container for the label and email input field -->
<div> <div>
<!-- Label for the email input field, visually hidden but accessible to screen readers -->
<label for={id} class="sr-only">{label}</label> <label for={id} class="sr-only">{label}</label>
<!-- Email input field -->
<input <input
type="email" type="email"
name="hs-email-contacts" name="hs-email-contacts"

View file

@ -1,5 +1,9 @@
--- ---
const { label = "Search", title = "Subscribe", id = "footer-input" } = Astro.props; const {
label = "Search",
title = "Subscribe",
id = "footer-input",
} = Astro.props;
interface Props { interface Props {
label?: string; label?: string;

View file

@ -1,19 +1,25 @@
--- ---
// Destructure the properties from Astro.props, setting default value for label
const { label = "Email address", id } = Astro.props; const { label = "Email address", id } = Astro.props;
// Define TypeScript interface for the properties
interface Props { interface Props {
label?: string; label?: string;
id: string; id: string;
} }
--- ---
<!-- Container for the label, input, and validation message -->
<div> <div>
<!-- Label for the email input field -->
<label <label
for={id} for={id}
class="mb-2 block text-sm text-neutral-800 dark:text-neutral-200" class="mb-2 block text-sm text-neutral-800 dark:text-neutral-200"
>{label}</label >{label}</label
> >
<!-- Label for the email input field -->
<div class="relative"> <div class="relative">
<!-- Email input field -->
<input <input
type="email" type="email"
id={id} id={id}
@ -23,6 +29,7 @@ interface Props {
required required
aria-describedby="email-error" aria-describedby="email-error"
/> />
<!-- Hidden error icon -->
<div class="pointer-events-none absolute inset-y-0 end-0 hidden pe-3"> <div class="pointer-events-none absolute inset-y-0 end-0 hidden pe-3">
<svg <svg
class="h-5 w-5 text-red-500" class="h-5 w-5 text-red-500"
@ -38,7 +45,8 @@ interface Props {
</svg> </svg>
</div> </div>
</div> </div>
<p class="mt-2 hidden text-xs text-red-600" id="email-error"> <!-- Validation message which is hidden by default -->
<p class="mt-2 hidden text-xs text-red-600" id="valid-email-error">
Please include a valid email address so we can get back to you Please include a valid email address so we can get back to you
</p> </p>
</div> </div>

View file

@ -3,13 +3,10 @@ const { url } = Astro.props;
interface Props { interface Props {
url: string; url: string;
} }
const linkClass = "inline-flex h-10 w-10 items-center justify-center gap-x-2 rounded-lg border border-transparent text-sm font-bold text-neutral-700 outline-none ring-zinc-500 hover:bg-neutral-500/10 focus:outline-none focus:ring-1 focus:ring-zinc-500 focus-visible:ring disabled:pointer-events-none disabled:opacity-50 dark:ring-zinc-200 dark:hover:bg-neutral-50/10 dark:focus:outline-none" const linkClass =
"inline-flex h-10 w-10 items-center justify-center gap-x-2 rounded-lg border border-transparent text-sm font-bold text-neutral-700 outline-none ring-zinc-500 hover:bg-neutral-500/10 focus:outline-none focus:ring-1 focus:ring-zinc-500 focus-visible:ring disabled:pointer-events-none disabled:opacity-50 dark:ring-zinc-200 dark:hover:bg-neutral-50/10 dark:focus:outline-none";
--- ---
<a
class={linkClass} <a class={linkClass} href={url} target="_blank" rel="noopener noreferrer">
href={url}
target="_blank"
rel="noopener noreferrer"
>
<slot /> <slot />
</a> </a>

View file

@ -1,10 +1,13 @@
--- ---
// Import section components // Import the necessary components
import MainLayout from "../layouts/MainLayout.astro"; import MainLayout from "../layouts/MainLayout.astro";
import ContactSection from "../components/ContactSection.astro"; import ContactSection from "../components/ContactSection.astro";
--- ---
<MainLayout title="Contact | ScrewFast" meta="ScrewFast offers top-tier hardware tools and expert construction services to meet all your project needs. Start exploring and contact our sales team for superior quality and reliability."> <!--Utilizing MainLayout for the outer layout of the page, and defining meta for SEO purposes-->
<MainLayout
title="Contact | ScrewFast"
meta="ScrewFast offers top-tier hardware tools and expert construction services to meet all your project needs. Start exploring and contact our sales team for superior quality and reliability."
>
<ContactSection /> <ContactSection />
</MainLayout> </MainLayout>