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:
parent
04e8089294
commit
c2dda2165b
15 changed files with 142 additions and 83 deletions
|
@ -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
|
||||||
|
|
|
@ -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 -->
|
|
||||||
|
|
|
@ -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>
|
|
@ -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"
|
||||||
|
|
|
@ -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>
|
|
@ -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} />
|
||||||
|
|
|
@ -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}
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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">
|
||||||
|
<!-- Checkbox input -->
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<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">
|
<input
|
||||||
|
id={id}
|
||||||
|
name="remember-me"
|
||||||
|
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">
|
<div class="ms-3">
|
||||||
<label for={id} class="text-sm text-neutral-800 dark:text-neutral-200">{label} <slot /> </label>
|
<label for={id} class="text-sm text-neutral-800 dark:text-neutral-200"
|
||||||
</div>
|
>{label} <slot />
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
Loading…
Add table
Reference in a new issue