Refactor code and enhance comments in multiple files

The changes made include code refactoring and reformatting in several files for better readability, and to adhere to best practices. Detailed and intuitive comments were added to the code, improving clarity and understanding of the codebase. There were also some class adjustments and minor changes in several files ranging from reordering class listings to updating element selections. Import statements were also modified for clarity. Accordion functionality was removed, potentially indicating a pending replacement or enhancement.
This commit is contained in:
Emil Gulamov 2024-02-18 07:40:53 +04:00
parent c2dda2165b
commit 03f0d73c45
18 changed files with 230 additions and 335 deletions

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,5 @@
--- ---
// import necessary dependencies // Import the necessary dependencies
import { Image } from "astro:assets"; import { Image } from "astro:assets";
import heroImage from "../images/hero-image.avif"; import heroImage from "../images/hero-image.avif";
import PrimaryCTA from "./ui/buttons/PrimaryCTA.astro"; import PrimaryCTA from "./ui/buttons/PrimaryCTA.astro";
@ -8,41 +8,29 @@ import Avatar from "./ui/avatars/Avatar.astro";
import FullStar from "./ui/stars/FullStar.astro"; import FullStar from "./ui/stars/FullStar.astro";
import HalfStar from "./ui/stars/HalfStar.astro"; import HalfStar from "./ui/stars/HalfStar.astro";
// Variables for customization of the HeroSection Component // Define the variables that will be used in this component
// Main heading const title: string = `Equip Your Projects with <span
const title:string = `Equip Your Projects with <span
class="text-yellow-500 dark:text-yellow-400">ScrewFast</span>`; class="text-yellow-500 dark:text-yellow-400">ScrewFast</span>`;
const subTitle: string =
// Main heading
const subTitle:string =
"Top-quality hardware tools and expert construction services for every project need."; "Top-quality hardware tools and expert construction services for every project need.";
const primaryBtn: string = "Start Exploring";
// Sub-heading text const primaryBtnURL: string = "/products";
const primaryBtn:string = "Start Exploring"; const secondaryBtn: string = "Contact Sales Team";
const primaryBtnURL:string = "/products"; const secondaryBtnURL: string = "/contact";
const rating: number = 4.8;
/* `secondaryBtn` and `secondaryBtnURL` variables used to customise the text and target link of the secondary button. */ const starCount: number = 4;
const secondaryBtn:string = "Contact Sales Team"; const reviews: string = "12.8k";
const secondaryBtnURL:string = "/contact";
/* `rating` variable used to customise the rating. */
const rating:number = 4.8;
/* `starCount` variable used to customise the star rating with the full stars. */
const starCount:number = 4;
/* `reviews` variable used to customise the number of reviews. */
const reviews:string = "12.8k";
--- ---
<!-- Defining a grid container that holds all the content -->
<div <div
class="mx-auto grid max-w-[85rem] gap-4 px-4 py-14 sm:px-6 md:grid-cols-2 md:items-center md:gap-8 lg:px-8 2xl:max-w-full" class="mx-auto grid max-w-[85rem] gap-4 px-4 py-14 sm:px-6 md:grid-cols-2 md:items-center md:gap-8 lg:px-8 2xl:max-w-full"
> >
<!-- Title and description --> <!-- Title and description -->
<div> <div>
<!-- Each h1 and p tag renders a portion of the title and subTitle defined above -->
<h1 <h1
class="text-balance block text-3xl font-bold tracking-tight text-neutral-800 dark:text-neutral-200 sm:text-4xl lg:text-6xl lg:leading-tight" class="block text-balance text-3xl font-bold tracking-tight text-neutral-800 dark:text-neutral-200 sm:text-4xl lg:text-6xl lg:leading-tight"
> >
<!-- About Fragment: https://docs.astro.build/en/basics/astro-syntax/#fragments --> <!-- About Fragment: https://docs.astro.build/en/basics/astro-syntax/#fragments -->
<Fragment set:html={title} /> <Fragment set:html={title} />
@ -53,13 +41,13 @@ const reviews:string = "12.8k";
{subTitle} {subTitle}
</p> </p>
<!-- Action buttons --> <!-- Action Button Section: This section includes two CTAs with their own styles and URL -->
<div class="mt-7 grid w-full gap-3 sm:inline-flex"> <div class="mt-7 grid w-full gap-3 sm:inline-flex">
<PrimaryCTA title={primaryBtn} url={primaryBtnURL} /> <PrimaryCTA title={primaryBtn} url={primaryBtnURL} />
<SecondaryCTA title={secondaryBtn} url={secondaryBtnURL} /> <SecondaryCTA title={secondaryBtn} url={secondaryBtnURL} />
</div> </div>
<!-- Review Section --> <!-- Review Section: This section presents avatars, review ratings and the number of reviews -->
<div class="mt-6 lg:mt-10"> <div class="mt-6 lg:mt-10">
<div class="py-5"> <div class="py-5">
<div class="text-center sm:flex sm:items-center sm:text-start"> <div class="text-center sm:flex sm:items-center sm:text-start">
@ -67,16 +55,20 @@ const reviews:string = "12.8k";
<!-- Avatar Group --> <!-- Avatar Group -->
<div class="flex justify-center -space-x-3"> <div class="flex justify-center -space-x-3">
<Avatar <Avatar
src="https://images.unsplash.com/photo-1568602471122-7832951cc4c5?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=2&w=300&h=300&q=80" alt="Image Description" src="https://images.unsplash.com/photo-1568602471122-7832951cc4c5?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=2&w=300&h=300&q=80"
alt="Image Description"
/> />
<Avatar <Avatar
src="https://images.unsplash.com/photo-1531927557220-a9e23c1e4794?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=2&w=300&h=300&q=80" alt="Image Description" src="https://images.unsplash.com/photo-1531927557220-a9e23c1e4794?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=2&w=300&h=300&q=80"
alt="Image Description"
/> />
<Avatar <Avatar
src="https://images.unsplash.com/photo-1541101767792-f9b2b1c4f127?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&&auto=format&fit=facearea&facepad=3&w=300&h=300&q=80" alt="Image Description" src="https://images.unsplash.com/photo-1541101767792-f9b2b1c4f127?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&&auto=format&fit=facearea&facepad=3&w=300&h=300&q=80"
alt="Image Description"
/> />
<Avatar <Avatar
src="https://images.unsplash.com/photo-1492562080023-ab3db95bfbce?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=2&w=300&h=300&q=80" alt="Image Description" src="https://images.unsplash.com/photo-1492562080023-ab3db95bfbce?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=2&w=300&h=300&q=80"
alt="Image Description"
/> />
<span <span
class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-zinc-800 ring-2 ring-white dark:bg-zinc-900 dark:ring-zinc-800" class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-zinc-800 ring-2 ring-white dark:bg-zinc-900 dark:ring-zinc-800"
@ -119,7 +111,7 @@ const reviews:string = "12.8k";
</div> </div>
</div> </div>
<!-- Hero Image --> <!-- Hero Image Section -->
<div class="flex w-full"> <div class="flex w-full">
<div class="top-12 overflow-hidden"> <div class="top-12 overflow-hidden">
<Image <Image

View file

@ -1,17 +1,15 @@
--- ---
// Import the necessary dependencies from individual component files // Import the necessary dependencies
import GithubBtn from "./ui/buttons/GithubBtn.astro"; import GithubBtn from "./ui/buttons/GithubBtn.astro";
// Variables for customization of the HeroSection2 Component // Define the variables that will be used in this component
// Main heading
const title: string = "Let's Build Together"; const title: string = "Let's Build Together";
// Sub-heading text
const subTitle: string = const subTitle: string =
"ScrewFast is an open-source template, meticulously crafted with Astro, Tailwind CSS, and Preline UI frameworks."; "ScrewFast is an open-source template, meticulously crafted with Astro, Tailwind CSS, and Preline UI frameworks.";
--- ---
<div class="relative mx-auto max-w-[85rem] px-4 pb-24 pt-10 sm:px-6 lg:px-8"> <div class="relative mx-auto max-w-[85rem] px-4 pb-24 pt-10 sm:px-6 lg:px-8">
<!-- Decorating SVG elements -->
<div <div
class="absolute left-0 top-[55%] scale-90 md:top-[20%] xl:left-[10%] xl:top-[25%]" class="absolute left-0 top-[55%] scale-90 md:top-[20%] xl:left-[10%] xl:top-[25%]"
> >
@ -112,21 +110,21 @@ const subTitle: string =
></path> ></path>
</svg> </svg>
</div> </div>
<!-- Hero Section Heading -->
<div class="mx-auto mt-5 max-w-xl text-center"> <div class="mx-auto mt-5 max-w-xl text-center">
<h1 <h2
class="block text-balance text-4xl font-bold leading-tight tracking-tight text-neutral-800 dark:text-neutral-200 md:text-5xl lg:text-6xl" class="block text-balance text-4xl font-bold leading-tight tracking-tight text-neutral-800 dark:text-neutral-200 md:text-5xl lg:text-6xl"
> >
{title} {title}
</h1> </h2>
</div> </div>
<!-- Hero Section Sub-heading -->
<div class="mx-auto mt-5 max-w-3xl text-center"> <div class="mx-auto mt-5 max-w-3xl text-center">
<p class="text-pretty text-lg text-neutral-600 dark:text-neutral-400"> <p class="text-pretty text-lg text-neutral-600 dark:text-neutral-400">
{subTitle} {subTitle}
</p> </p>
</div> </div>
<!-- Github Button -->
<div class="mt-8 flex justify-center gap-3"> <div class="mt-8 flex justify-center gap-3">
<GithubBtn url="https://github.com/mearashadowfax/ScrewFast" /> <GithubBtn url="https://github.com/mearashadowfax/ScrewFast" />
</div> </div>

View file

@ -1,72 +1,73 @@
--- ---
// Assign a description using the `meta` prop passed from the parent component, // Assign a description using the `meta` prop passed from the parent component,
// `meta` is used as a variable on each individual page by passing it as a prop to this component. // `meta` is used as a variable on each individual page by passing it as a prop to this component.
// For example, you can pass a meta description to the MainLayout component like this: <MainLayout title="Page title" meta="Page description"/> // For example, you can pass a meta description to the MainLayout component like this: <MainLayout meta="Page description"/>
const { meta: description } = Astro.props; const { meta: description } = Astro.props;
interface Props { interface Props {
meta?: string; meta?: string;
} }
// Customize the following metadata for your landing page // Define the metadata for your website and individual pages
const title: string = "ScrewFast"; // Set the website title
const title: string = "ScrewFast"; // Replace with your website title const ogTitle: string = "ScrewFast: Hardware Tools & Construction Services"; // Set the Open Graph title
const ogTitle: string = "ScrewFast: Hardware Tools & Construction Services"; // Replace with your Open Graph title const author: string = "Emil Gulamov"; // Set the author's name
const author:string = "Emil Gulamov" // Replace with the author's name const ogDescription: string =
const ogDescription: string = "Equip your projects with ScrewFast's top-quality hardware tools and expert construction services. Trusted by industry leaders, ScrewFast offers simplicity, affordability, and reliability. Experience the difference with user-centric design and cutting-edge tools. Start exploring now!"; // Replace with your site description for social media "Equip your projects with ScrewFast's top-quality hardware tools and expert construction services. Trusted by industry leaders, ScrewFast offers simplicity, affordability, and reliability. Experience the difference with user-centric design and cutting-edge tools. Start exploring now!"; // Set the Open Graph description
const URL:string = "https://screw-fast.vercel.app"; // Replace with your website URL const URL: string = "https://screw-fast.vercel.app"; // Set the website URL
const socialImage:string = "https://screw-fast.vercel.app/social.png"; // Replace with the URL to your social media image const socialImage: string = "https://screw-fast.vercel.app/social.png"; // Set the URL for the social media image
--- ---
<!-- JSON-LD structured data script for the website -->
<script type="application/ld+json"> <script type="application/ld+json">
{ {
"@context": "https://schema.org", "@context": "https://schema.org",
"@type": "WebSite", "@type": "WebSite",
"name": "ScrewFast", "name": "ScrewFast",
"url": "https://screw-fast.vercel.app", "url": "https://screw-fast.vercel.app",
"description": "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." "description": "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."
} }
</script> </script>
<!-- Define the character set, description, author, and viewport settings -->
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta content={description} name="description" />
<meta name="web_author" content={author} />
<meta <meta
content={description} name="viewport"
name="description" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0"
/> />
<meta name="web_author" content={author}/> <meta http-equiv="X-UA-Compatible" content="ie=edge" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- Facebook Meta Tags --> <!-- Facebook Meta Tags -->
<meta property="og:locale" content="en_US" /> <meta property="og:locale" content="en_US" />
<meta property="og:url" content={URL}> <meta property="og:url" content={URL} />
<meta property="og:type" content="website"> <meta property="og:type" content="website" />
<meta property="og:title" content={ogTitle}> <meta property="og:title" content={ogTitle} />
<meta property="og:site_name" content={title}/> <meta property="og:site_name" content={title} />
<meta property="og:description" content={ogDescription}> <meta property="og:description" content={ogDescription} />
<meta property="og:image" content={socialImage}> <meta property="og:image" content={socialImage} />
<meta content="1200" property="og:image:width"/> <meta content="1200" property="og:image:width" />
<meta content="600" property="og:image:height"/> <meta content="600" property="og:image:height" />
<meta content="image/png" property="og:image:type"/> <meta content="image/png" property="og:image:type" />
<!-- Twitter Meta Tags --> <!-- Twitter Meta Tags -->
<meta name="twitter:card" content="summary_large_image"> <meta name="twitter:card" content="summary_large_image" />
<meta property="twitter:domain" content={URL}> <meta property="twitter:domain" content={URL} />
<meta property="twitter:url" content={URL}> <meta property="twitter:url" content={URL} />
<meta name="twitter:title" content={ogTitle}> <meta name="twitter:title" content={ogTitle} />
<meta name="twitter:description" content={ogDescription}> <meta name="twitter:description" content={ogDescription} />
<meta name="twitter:image" content={socialImage}> <meta name="twitter:image" content={socialImage} />
<!-- Links to the webmanifest and sitemap -->
<link rel="manifest" href="/manifest.webmanifest" /> <link rel="manifest" href="/manifest.webmanifest" />
<!-- https://docs.astro.build/en/guides/integrations-guide/sitemap/ --> <!-- https://docs.astro.build/en/guides/integrations-guide/sitemap/ -->
<link rel="sitemap" href="/sitemap-index.xml" /> <link rel="sitemap" href="/sitemap-index.xml" />
<!-- Add your favicon and apple touch icon links --> <!-- Links for favicons -->
<link href="/favicon.ico" rel="icon" sizes="any" type="image/x-icon"/> <link href="/favicon.ico" rel="icon" sizes="any" type="image/x-icon" />
<link href="/icon.svg" rel="icon" type="image/svg+xml" sizes="any"/> <link href="/icon.svg" rel="icon" type="image/svg+xml" sizes="any" />
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes" />
<link href="/apple-touch-icon.png" rel="apple-touch-icon"/> <link href="/apple-touch-icon.png" rel="apple-touch-icon" />
<link href="/apple-touch-icon.png" rel="shortcut icon"/> <link href="/apple-touch-icon.png" rel="shortcut icon" />
<meta name="theme-color" content="#facc15"> <!-- Set theme color -->
<meta name="theme-color" content="#facc15" />

View file

@ -1,24 +1,26 @@
--- ---
// Import the necessary dependencies from individual component files //Import relevant dependencies
import ThemeIcon from "./ThemeIcon.astro"; import ThemeIcon from "./ThemeIcon.astro";
import NavLink from "./ui/links/NavLink.astro"; import NavLink from "./ui/links/NavLink.astro";
import Authentication from "./Authentication.astro"; import Authentication from "./Authentication.astro";
--- ---
<!-- Main header component -->
<header <header
class="sticky inset-x-0 top-4 z-50 flex w-full flex-wrap text-sm md:flex-nowrap md:justify-start" class="sticky inset-x-0 top-4 z-50 flex w-full flex-wrap text-sm md:flex-nowrap md:justify-start"
> >
<!-- Navigation container -->
<nav <nav
class="relative mx-2 w-full rounded-[36px] border border-yellow-100/40 bg-yellow-50/60 px-4 py-3 backdrop-blur-md dark:border-neutral-700/40 dark:bg-neutral-800/80 dark:backdrop-blur-md md:flex md:items-center md:justify-between md:px-6 md:py-0 lg:px-8 xl:mx-auto" class="relative mx-2 w-full rounded-[36px] border border-yellow-100/40 bg-yellow-50/60 px-4 py-3 backdrop-blur-md dark:border-neutral-700/40 dark:bg-neutral-800/80 dark:backdrop-blur-md md:flex md:items-center md:justify-between md:px-6 md:py-0 lg:px-8 xl:mx-auto"
aria-label="Global" aria-label="Global"
> >
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<!-- Brand logo -->
<a <a
class="flex-none text-xl outline-none rounded-lg font-bold dark:focus:outline-none ring-zinc-500 focus-visible:ring dark:ring-zinc-200" class="flex-none rounded-lg text-xl font-bold outline-none ring-zinc-500 focus-visible:ring dark:ring-zinc-200 dark:focus:outline-none"
href="/" href="/"
aria-label="Brand" aria-label="Brand"
> >
<!-- Brand Logo -->
<svg class="h-auto w-24" viewBox="0 0 521 226" fill="none"> <svg class="h-auto w-24" viewBox="0 0 521 226" fill="none">
<rect <rect
width="78.937" width="78.937"
@ -73,6 +75,7 @@ import Authentication from "./Authentication.astro";
></path> ></path>
</svg> </svg>
</a> </a>
<!-- Collapse toggle for smaller screens -->
<div class="ml-auto mr-5 md:hidden"> <div class="ml-auto mr-5 md:hidden">
<button <button
type="button" type="button"
@ -112,24 +115,29 @@ import Authentication from "./Authentication.astro";
</svg> </svg>
</button> </button>
</div> </div>
<!-- ThemeIcon component specifically for smaller screens -->
<span class="inline-block md:hidden"> <span class="inline-block md:hidden">
<ThemeIcon /> <ThemeIcon />
</span> </span>
</div> </div>
<!-- Contains navigation links -->
<div <div
id="navbar-collapse-with-animation" id="navbar-collapse-with-animation"
class="hs-collapse hidden grow basis-full overflow-hidden transition-all duration-300 md:block" class="hs-collapse hidden grow basis-full overflow-hidden transition-all duration-300 md:block"
> >
<!-- Navigation links container -->
<div <div
class="mt-5 flex flex-col gap-x-0 gap-y-4 md:mt-0 md:flex-row md:items-center md:justify-end md:gap-x-7 md:gap-y-0 md:ps-7" class="mt-5 flex flex-col gap-x-0 gap-y-4 md:mt-0 md:flex-row md:items-center md:justify-end md:gap-x-7 md:gap-y-0 md:ps-7"
> >
<!-- Navigation links and Authentication component -->
<NavLink url="/" name="Home" /> <NavLink url="/" name="Home" />
<NavLink url="/products" name="Products" /> <NavLink url="/products" name="Products" />
<NavLink url="/services" name="Services" /> <NavLink url="/services" name="Services" />
<NavLink url="/blog" name="Blog" /> <NavLink url="/blog" name="Blog" />
<NavLink url="/contact" name="Contact" /> <NavLink url="/contact" name="Contact" />
<Authentication /> <Authentication />
<!-- ThemeIcon component specifically for larger screens -->
<span class="hidden md:inline-block"> <span class="hidden md:inline-block">
<ThemeIcon /> <ThemeIcon />
</span> </span>
@ -137,7 +145,7 @@ import Authentication from "./Authentication.astro";
</div> </div>
</nav> </nav>
</header> </header>
<!-- Theme Appearance script to manage light/dark modes -->
<script is:inline> <script is:inline>
const HSThemeAppearance = { const HSThemeAppearance = {
init() { init() {
@ -242,5 +250,8 @@ import Authentication from "./Authentication.astro";
}); });
}); });
</script> </script>
<!--Import the necessary Collapse and Overlay plugins-->
<!--https://preline.co/plugins/html/collapse.html-->
<!--https://preline.co/plugins/html/overlay.html-->
<script is:inline src="/scripts/vendor/preline/collapse/index.js"></script> <script is:inline src="/scripts/vendor/preline/collapse/index.js"></script>
<script is:inline src="/scripts/vendor/preline/overlay/index.js"></script> <script is:inline src="/scripts/vendor/preline/overlay/index.js"></script>

View file

@ -1,23 +1,28 @@
--- ---
// Get heading and content from Astro props
const { heading, content } = Astro.props; const { heading, content } = Astro.props;
// Define TypeScript interface for props
interface Props { interface Props {
heading?: string; heading?: string;
content?: string; content?: string;
} }
// Define classes for heading and content
const headingClasses = const headingClasses =
"text-balance text-lg font-bold text-gray-800 dark:text-neutral-200"; "text-balance text-lg font-bold text-gray-800 dark:text-neutral-200";
const contentClasses = const contentClasses =
"mt-1 text-pretty text-neutral-700 dark:text-neutral-300"; "mt-1 text-pretty text-neutral-700 dark:text-neutral-300";
--- ---
<!-- The root container that arranges your slot and the heading/content -->
<div class="flex gap-x-5"> <div class="flex gap-x-5">
<!-- Slot to allow for extensibility of the component -->
<slot /> <slot />
<div class="grow"> <div class="grow">
<!-- Heading of the section -->
<h3 class={headingClasses}> <h3 class={headingClasses}>
{heading} {heading}
</h3> </h3>
<!-- Content text of the section -->
<p class={contentClasses}>{content}</p> <p class={contentClasses}>{content}</p>
</div> </div>
</div> </div>

View file

@ -1,10 +1,11 @@
--- ---
// Import the necessary modules
import { Image } from "astro:assets"; import { Image } from "astro:assets";
import PrimaryCTA from "../buttons/PrimaryCTA.astro"; import PrimaryCTA from "../buttons/PrimaryCTA.astro";
// Destructure the props passed to the Astro component
const { title, subTitle, btnExists, btnTitle, btnURL, img, imgAlt } = const { title, subTitle, btnExists, btnTitle, btnURL, img, imgAlt } =
Astro.props; Astro.props;
// Define TypeScript interface for props
interface Props { interface Props {
title: string; title: string;
subTitle: string; subTitle: string;
@ -16,9 +17,11 @@ interface Props {
} }
--- ---
<!-- The root section of the component -->
<section <section
class="mx-auto max-w-[85rem] items-center gap-8 px-4 py-10 sm:px-6 sm:py-16 md:grid md:grid-cols-2 lg:grid lg:grid-cols-2 lg:px-8 lg:py-14 xl:gap-16 2xl:max-w-full" class="mx-auto max-w-[85rem] items-center gap-8 px-4 py-10 sm:px-6 sm:py-16 md:grid md:grid-cols-2 lg:grid lg:grid-cols-2 lg:px-8 lg:py-14 xl:gap-16 2xl:max-w-full"
> >
<!-- The Image component which renders the image -->
<Image <Image
class="w-full rounded-xl" class="w-full rounded-xl"
src={img} src={img}
@ -26,17 +29,21 @@ interface Props {
draggable={"false"} draggable={"false"}
format={"avif"} format={"avif"}
/> />
<!-- The container for title, subtitle, and optional CTA button -->
<div class="mt-4 md:mt-0"> <div class="mt-4 md:mt-0">
<!-- The title of the section -->
<h2 <h2
class="mb-4 text-balance text-4xl font-extrabold tracking-tight text-neutral-800 dark:text-neutral-200" class="mb-4 text-balance text-4xl font-extrabold tracking-tight text-neutral-800 dark:text-neutral-200"
> >
{title} {title}
</h2> </h2>
<!-- The subtitle of the section -->
<p <p
class="mb-4 max-w-prose text-pretty font-light text-neutral-600 dark:text-neutral-400 sm:text-lg" class="mb-4 max-w-prose text-pretty font-light text-neutral-600 dark:text-neutral-400 sm:text-lg"
> >
{subTitle} {subTitle}
</p> </p>
<!-- Conditionally render the Primary CTA button if btnExists is true -->
{btnExists ? <PrimaryCTA title={btnTitle} url={btnURL} /> : null} {btnExists ? <PrimaryCTA title={btnTitle} url={btnURL} /> : null}
</div> </div>
</section> </section>

View file

@ -1,8 +1,10 @@
--- ---
// Import PrimaryCTA component
import PrimaryCTA from "../buttons/PrimaryCTA.astro"; import PrimaryCTA from "../buttons/PrimaryCTA.astro";
// Destructure the props passed to the Astro component
const { title, subTitle, btnExists, btnTitle, btnURL } = Astro.props; const { title, subTitle, btnExists, btnTitle, btnURL } = Astro.props;
// Define TypeScript interface for props
interface Props { interface Props {
title: string; title: string;
subTitle: string; subTitle: string;
@ -12,20 +14,24 @@ interface Props {
} }
--- ---
<!-- Root section of the component -->
<section <section
class="mx-auto mt-10 max-w-[85rem] px-4 py-10 sm:px-6 sm:py-16 lg:px-8 lg:py-14 2xl:max-w-full" class="mx-auto mt-10 max-w-[85rem] px-4 py-10 sm:px-6 sm:py-16 lg:px-8 lg:py-14 2xl:max-w-full"
> >
<div class="max-w-screen-md"> <div class="max-w-screen-md">
<!-- Section title -->
<h1 <h1
class="mb-4 text-balance text-4xl font-extrabold tracking-tight text-neutral-800 dark:text-neutral-200" class="mb-4 text-balance text-4xl font-extrabold tracking-tight text-neutral-800 dark:text-neutral-200"
> >
{title} {title}
</h1> </h1>
<!-- Section subtitle -->
<p <p
class="mb-8 max-w-prose text-pretty font-light text-neutral-600 dark:text-neutral-400 sm:text-xl" class="mb-8 max-w-prose text-pretty font-light text-neutral-600 dark:text-neutral-400 sm:text-xl"
> >
{subTitle} {subTitle}
</p> </p>
<!-- Conditional rendering of PrimaryCTA component if 'btnExists' property is truthy -->
{ {
btnExists ? ( btnExists ? (
<div class="flex flex-col space-y-4 sm:flex-row sm:space-x-4 sm:space-y-0"> <div class="flex flex-col space-y-4 sm:flex-row sm:space-x-4 sm:space-y-0">

View file

@ -6,10 +6,11 @@ interface Props {
url?: string; url?: string;
} }
const baseClasses = "group inline-flex items-center justify-center gap-x-3 rounded-full px-4 py-3 text-center text-sm font-medium text-neutral-700 ring-zinc-500 focus-visible:ring transition duration-300 outline-none"; const baseClasses =
"group inline-flex items-center justify-center gap-x-3 rounded-full px-4 py-3 text-center text-sm font-medium text-neutral-700 ring-zinc-500 focus-visible:ring transition duration-300 outline-none";
const borderClasses = "border border-transparent"; const borderClasses = "border border-transparent";
const bgColorClasses = "bg-yellow-400 dark:focus:outline-none"; const bgColorClasses = "bg-yellow-400 dark:focus:outline-none";
const hoverClasses = "hover:shadow-2xl hover:shadow-yellow-500" const hoverClasses = "hover:shadow-2xl hover:shadow-yellow-500";
const fontSizeClasses = "2xl:text-base"; const fontSizeClasses = "2xl:text-base";
const ringClasses = "dark:ring-zinc-200"; const ringClasses = "dark:ring-zinc-200";
const githubSVG = `<svg const githubSVG = `<svg
@ -27,11 +28,13 @@ const githubSVG = `<svg
--- ---
<a <a
class={`${baseClasses} ${borderClasses} ${bgColorClasses} ${hoverClasses} ${fontSizeClasses} ${ringClasses}`} class={`${baseClasses} ${borderClasses} ${bgColorClasses} ${hoverClasses} ${fontSizeClasses} ${ringClasses}`}
href={url} href={url}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
<!-- About Fragment: https://docs.astro.build/en/basics/astro-syntax/#fragments -->
<Fragment set:html={githubSVG} /> <Fragment set:html={githubSVG} />
{title} {title}
</a> </a>

View file

@ -5,9 +5,11 @@ interface Props {
title: string; title: string;
} }
const baseClasses = "inline-flex w-full items-center justify-center gap-x-2 rounded-lg px-4 py-3 text-sm dark:text-neutral-400 font-medium text-neutral-600 shadow-sm transition duration-300 focus-visible:ring outline-none"; const baseClasses =
"inline-flex w-full items-center justify-center gap-x-2 rounded-lg px-4 py-3 text-sm dark:text-neutral-400 font-medium text-neutral-600 shadow-sm transition duration-300 focus-visible:ring outline-none";
const borderClasses = "border border-neutral-200 dark:border-neutral-700"; const borderClasses = "border border-neutral-200 dark:border-neutral-700";
const bgColorClasses = "bg-neutral-50 dark:bg-neutral-800 hover:bg-neutral-200 dark:hover:bg-neutral-900"; const bgColorClasses =
"bg-neutral-50 dark:bg-neutral-800 hover:bg-neutral-200 dark:hover:bg-neutral-900";
const disableClasses = "disabled:pointer-events-none disabled:opacity-50"; const disableClasses = "disabled:pointer-events-none disabled:opacity-50";
const ringClasses = "ring-zinc-500 dark:ring-zinc-200"; const ringClasses = "ring-zinc-500 dark:ring-zinc-200";
const googleSVG = `<svg const googleSVG = `<svg
@ -36,6 +38,8 @@ const googleSVG = `<svg
type="button" type="button"
class={`${baseClasses} ${borderClasses} ${bgColorClasses} ${disableClasses} ${ringClasses}`} class={`${baseClasses} ${borderClasses} ${bgColorClasses} ${disableClasses} ${ringClasses}`}
> >
<!-- About Fragment: https://docs.astro.build/en/basics/astro-syntax/#fragments -->
<Fragment set:html={googleSVG} /> <Fragment set:html={googleSVG} />
{title} {title}
</button> </button>

View file

@ -5,9 +5,11 @@ interface Props {
title?: string; title?: string;
} }
const baseClasses = "flex items-center gap-x-2 text-base md:text-sm font-medium text-neutral-600 ring-zinc-500 transition duration-300 focus-visible:ring outline-none"; const baseClasses =
"flex items-center gap-x-2 text-base md:text-sm font-medium text-neutral-600 ring-zinc-500 transition duration-300 focus-visible:ring outline-none";
const hoverClasses = "hover:text-[#fa5a15] dark:hover:text-[#fb713b]"; const hoverClasses = "hover:text-[#fa5a15] dark:hover:text-[#fb713b]";
const darkClasses = "dark:border-neutral-700 dark:text-neutral-400 dark:ring-zinc-200 dark:focus:outline-none"; const darkClasses =
"dark:border-neutral-700 dark:text-neutral-400 dark:ring-zinc-200 dark:focus:outline-none";
const mdClasses = "md:my-6 md:border-s md:border-neutral-300 md:ps-6"; const mdClasses = "md:my-6 md:border-s md:border-neutral-300 md:ps-6";
const txtSizeClasses = "2xl:text-base"; const txtSizeClasses = "2xl:text-base";
const userSVG = `<svg const userSVG = `<svg
@ -27,10 +29,12 @@ const userSVG = `<svg
--- ---
<button <button
type="button" type="button"
class={`${baseClasses} ${hoverClasses} ${darkClasses} ${mdClasses} ${txtSizeClasses}`} class={`${baseClasses} ${hoverClasses} ${darkClasses} ${mdClasses} ${txtSizeClasses}`}
data-hs-overlay="#hs-toggle-between-modals-login-modal" data-hs-overlay="#hs-toggle-between-modals-login-modal"
> >
<!-- About Fragment: https://docs.astro.build/en/basics/astro-syntax/#fragments -->
<Fragment set:html={userSVG} /> <Fragment set:html={userSVG} />
{title} {title}
</button> </button>

View file

@ -1,5 +1,5 @@
--- ---
// Import the necessary dependencies from individual component files // Import necessary components from their individual files
import EmailInput from "./input/EmailInput.astro"; import EmailInput from "./input/EmailInput.astro";
import PasswordInput from "./input/PasswordInput.astro"; import PasswordInput from "./input/PasswordInput.astro";
import Checkbox from "./input/Checkbox.astro"; import Checkbox from "./input/Checkbox.astro";
@ -7,13 +7,13 @@ import AuthBtn from "../buttons/AuthBtn.astro";
import GoogleBtn from "../buttons/GoogleBtn.astro"; import GoogleBtn from "../buttons/GoogleBtn.astro";
// Variables for customization of the LoginModal Component // Variables for customization of the LoginModal Component
// Modal identifier, Main heading, Sub-heading text, Text for registration button, Target link for registration button
const config = { const config = {
id: "hs-toggle-between-modals-login-modal", id: "hs-toggle-between-modals-login-modal", // Modal IDENTIFIER
title: "Sign in", title: "Sign in", // Main HEADING
subTitle: "Don't have an account yet?", subTitle: "Don't have an account yet?", // Sub-Heading TEXT
registerBtn: "Sign up here", registerBtn: "Sign up here", // Text for REGISTRATION BUTTON
registerBtnDataHS: "#hs-toggle-between-modals-register-modal" registerBtnDataHS: "#hs-toggle-between-modals-register-modal", // TARGET LINK for registration button
}; };
--- ---
@ -30,11 +30,11 @@ const config = {
> >
<div class="p-4 sm:p-7"> <div class="p-4 sm:p-7">
<div class="text-center"> <div class="text-center">
<h1 <h2
class="block text-2xl font-bold text-neutral-800 dark:text-neutral-200" class="block text-2xl font-bold text-neutral-800 dark:text-neutral-200"
> >
{config.title} {config.title}
</h1> </h2>
<p class="mt-2 text-sm text-neutral-600 dark:text-neutral-400"> <p class="mt-2 text-sm text-neutral-600 dark:text-neutral-400">
{config.subTitle} {config.subTitle}
<button <button
@ -53,21 +53,23 @@ const config = {
> >
Or Or
</div> </div>
<!-- The container for the form -->
<form> <form>
<!-- A grid layout for the form fields -->
<div class="grid gap-y-4"> <div class="grid gap-y-4">
<!-- The email input field -->
<EmailInput id="login-email" /> <EmailInput id="login-email" />
<!-- The password input field -->
<PasswordInput <PasswordInput
forgot={true} forgot={true}
id="password" id="password"
; ;
errorId="password-error" errorId="login-password-error"
content="8+ characters required" content="8+ characters required"
/> />
<!-- The remember-me checkbox -->
<Checkbox id="remember-me" /> <Checkbox id="remember-me" />
<!-- The sign-in button -->
<AuthBtn title="Sign in" /> <AuthBtn title="Sign in" />
</div> </div>
</form> </form>

View file

@ -28,7 +28,7 @@ interface Props {
{ {
forgot ? ( forgot ? (
<button <button
class="text-sm font-medium text-[#fa5a15] decoration-2 rounded-lg 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" class="rounded-lg 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" data-hs-overlay="#hs-toggle-between-modals-recover-modal"
> >
Forgot password? Forgot password?

View file

@ -1,6 +1,8 @@
--- ---
// Destructure the properties from Astro.props
const { url, name } = Astro.props; const { url, name } = Astro.props;
// Define TypeScript interface for the properties
interface Props { interface Props {
url: string; url: string;
name: string; name: string;
@ -23,20 +25,20 @@ If URL is '/' (home page), assign ID as 'home'
</a> </a>
<script> <script>
window.onload = function () { window.onload = function () {
let url = window.location.pathname; let url = window.location.pathname;
let firstPathSegment = url.split('/')[1]; let firstPathSegment = url.split("/")[1];
let navId = firstPathSegment ? firstPathSegment : 'home'; let navId = firstPathSegment ? firstPathSegment : "home";
let nav = document.getElementById(navId); let nav = document.getElementById(navId);
if (nav) { if (nav) {
nav.classList.remove( nav.classList.remove(
'text-neutral-600', "text-neutral-600",
'dark:text-neutral-400', "dark:text-neutral-400",
'hover:text-neutral-500', "hover:text-neutral-500",
'dark:hover:text-neutral-500', "dark:hover:text-neutral-500",
); );
nav.classList.add('text-[#fa5a15]', 'dark:text-[#fb713b]'); nav.classList.add("text-[#fa5a15]", "dark:text-[#fb713b]");
nav.setAttribute('aria-current', 'page'); nav.setAttribute("aria-current", "page");
} }
}; };
</script> </script>

View file

@ -1,22 +1,31 @@
--- ---
// Importing necessary components
import Meta from "../components/Meta.astro"; import Meta from "../components/Meta.astro";
import Navbar from "../components/Navbar.astro"; import Navbar from "../components/Navbar.astro";
import FooterSection from "../components/FooterSection.astro"; import FooterSection from "../components/FooterSection.astro";
// Setting expected props - expecting 'title' and 'meta' as options with a default value for title
const { title = "ScrewFast", meta } = Astro.props; const { title = "ScrewFast", meta } = Astro.props;
// Interface to type-check the properties
interface Props { interface Props {
title?: string; title?: string;
meta?: string; meta?: string;
} }
--- ---
<!--
This is the main structure for the page.
We set the language of the page to English and add classes for scrollbar and scroll behavior.
-->
<html lang="en" class="scrollbar-hide scroll-pt-16"> <html lang="en" class="scrollbar-hide scroll-pt-16">
<head> <head>
<!-- Adding metadata to the HTML document -->
<Meta meta={meta} /> <Meta meta={meta} />
<!-- Define the title of the page -->
<title>{title}</title> <title>{title}</title>
<script is:inline> <script is:inline>
// This script is to handle theme according to user preference // Script to handle dark mode. It will check if the theme is stored in localStorage or if dark theme is preferred by system settings
if ( if (
localStorage.getItem("hs_theme") === "dark" || localStorage.getItem("hs_theme") === "dark" ||
(!("hs_theme" in localStorage) && (!("hs_theme" in localStorage) &&
@ -29,7 +38,7 @@ interface Props {
</script> </script>
<script is:inline src="/scripts/vendor/lenis/lenis.js"></script> <script is:inline src="/scripts/vendor/lenis/lenis.js"></script>
<script is:inline> <script is:inline>
// This script is to handle lenis library settings and behaviors, like the smooth scrolling // Script to handle Lenis library settings for smooth scrolling
const lenis = new Lenis({ smooth: true, smoothTouch: false }); const lenis = new Lenis({ smooth: true, smoothTouch: false });
function raf(time) { function raf(time) {
@ -43,13 +52,17 @@ interface Props {
<body <body
class="bg-neutral-200 selection:bg-yellow-400 selection:text-neutral-700 dark:bg-neutral-800" class="bg-neutral-200 selection:bg-yellow-400 selection:text-neutral-700 dark:bg-neutral-800"
> >
<!--
Setting up the main structure of the page.
The Navbar is placed at the top, with a slot for the main content and FooterSection at the bottom.
-->
<div class="mx-auto max-w-screen-2xl px-4 sm:px-6 lg:px-8"> <div class="mx-auto max-w-screen-2xl px-4 sm:px-6 lg:px-8">
<Navbar /> <Navbar />
<slot /> <slot />
</div> </div>
<FooterSection /> <FooterSection />
<style> <style>
// These css rules are for the page scrollbar and scrolling experience with lenis library // CSS rules for the page scrollbar and scrolling experience with lenis library
.scrollbar-hide::-webkit-scrollbar { .scrollbar-hide::-webkit-scrollbar {
display: none; display: none;
} }

View file

@ -1,32 +1,30 @@
--- ---
// Import section components // Import necessary components, modules and types
import MainLayout from "../../layouts/MainLayout.astro"; import MainLayout from "../../layouts/MainLayout.astro";
import CardBlog from "../../components/ui/cards/CardBlog.astro"; import CardBlog from "../../components/ui/cards/CardBlog.astro";
import CardBlogRecent from "../../components/ui/cards/CardBlogRecent.astro"; import CardBlogRecent from "../../components/ui/cards/CardBlogRecent.astro";
import CardInsight from "../../components/ui/cards/CardInsight.astro"; import CardInsight from "../../components/ui/cards/CardInsight.astro";
import { Image } from "astro:assets";
import { getCollection } from "astro:content"; import { getCollection } from "astro:content";
import type { CollectionEntry } from "astro:content"; import type { CollectionEntry } from "astro:content";
// Get all blogs post and sort them based on publish date
const blogPosts: CollectionEntry<"blog">[] = (await getCollection("blog")).sort( const blogPosts: CollectionEntry<"blog">[] = (await getCollection("blog")).sort(
(a: CollectionEntry<"blog">, b: CollectionEntry<"blog">) => (a: CollectionEntry<"blog">, b: CollectionEntry<"blog">) =>
b.data.pubDate.valueOf() - a.data.pubDate.valueOf(), b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
); );
// Get all insights posts
const insightPosts: CollectionEntry<"insights">[] = const insightPosts: CollectionEntry<"insights">[] =
await getCollection("insights"); await getCollection("insights");
// Separate the most recent post from others
const mostRecentPost: CollectionEntry<"blog"> = blogPosts[0]; const mostRecentPost: CollectionEntry<"blog"> = blogPosts[0];
const otherPosts: CollectionEntry<"blog">[] = blogPosts.slice(1); const otherPosts: CollectionEntry<"blog">[] = blogPosts.slice(1);
// Define variables for page content
const title: string = "Your Gateway to Construction Excellence"; const title: string = "Your Gateway to Construction Excellence";
const subTitle: string = const subTitle: string =
"Explore the latest news, tips, and insights from ScrewFast to enhance your construction projects. From product spotlights to project management strategies, our blog is your go-to resource for all things hardware and construction."; "Explore the latest news, tips, and insights from ScrewFast to enhance your construction projects. From product spotlights to project management strategies, our blog is your go-to resource for all things hardware and construction.";
const secondTitle: string = "Insights"; const secondTitle: string = "Insights";
const secondSubTitle: string = const secondSubTitle: string =
"Stay up-to-date with the latest trends and developments in the construction industry with insights from ScrewFast's team of industry experts. "; "Stay up-to-date with the latest trends and developments in the construction industry with insights from ScrewFast's team of industry experts. ";
--- ---
@ -38,6 +36,7 @@ const secondSubTitle: string =
<div <div
class="mx-auto max-w-[85rem] space-y-8 px-4 pt-16 sm:px-6 lg:px-8 2xl:max-w-full" class="mx-auto max-w-[85rem] space-y-8 px-4 pt-16 sm:px-6 lg:px-8 2xl:max-w-full"
> >
<!--Page header-->
<div class="mx-auto max-w-3xl text-center"> <div class="mx-auto max-w-3xl text-center">
<h1 <h1
class="block text-balance text-4xl font-bold tracking-tight text-neutral-800 dark:text-neutral-200 md:text-5xl lg:text-6xl" class="block text-balance text-4xl font-bold tracking-tight text-neutral-800 dark:text-neutral-200 md:text-5xl lg:text-6xl"
@ -56,17 +55,18 @@ const secondSubTitle: 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"
> >
<!--Blog posts grid-->
<div class="grid gap-6 lg:grid-cols-2"> <div class="grid gap-6 lg:grid-cols-2">
{otherPosts.map((blogEntry) => <CardBlog blogEntry={blogEntry} />)} {otherPosts.map((blogEntry) => <CardBlog blogEntry={blogEntry} />)}
</div> </div>
</div> </div>
<!--Most recent blog post-->
<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"
> >
<CardBlogRecent blogEntry={mostRecentPost} /> <CardBlogRecent blogEntry={mostRecentPost} />
</div> </div>
<!--Insights section-->
<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"
> >
@ -76,9 +76,10 @@ const secondSubTitle: string =
> >
{secondTitle} {secondTitle}
</h2> </h2>
<p class="mt-1 text-neutral-600 dark:text-neutral-400 text-pretty">{secondSubTitle}</p> <p class="mt-1 text-pretty text-neutral-600 dark:text-neutral-400">
{secondSubTitle}
</p>
</div> </div>
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3"> <div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{ {
insightPosts.map((insightEntry) => ( insightPosts.map((insightEntry) => (

View file

@ -1,8 +1,8 @@
--- ---
// Import section components // Import the necessary components
import MainLayout from "../layouts/MainLayout.astro"; import MainLayout from "../layouts/MainLayout.astro";
import HeroSection from "../components/HeroSection.astro"; import HeroSection from "../components/HeroSection.astro";
import HeroSection2 from "../components/HeroSection2.astro"; import HeroSectionAlt from "../components/HeroSectionAlt.astro";
import ClientsSection from "../components/ClientsSection.astro"; import ClientsSection from "../components/ClientsSection.astro";
import FeaturesGeneral from "../components/FeaturesGeneral.astro"; import FeaturesGeneral from "../components/FeaturesGeneral.astro";
import FeaturesNavs from "../components/FeaturesNavs.astro"; import FeaturesNavs from "../components/FeaturesNavs.astro";
@ -11,8 +11,10 @@ import PricingSection from "../components/PricingSection.astro";
import FAQ from "../components/FAQ.astro"; import FAQ from "../components/FAQ.astro";
--- ---
<MainLayout 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
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."
>
<HeroSection /> <HeroSection />
<ClientsSection /> <ClientsSection />
<FeaturesGeneral /> <FeaturesGeneral />
@ -20,5 +22,5 @@ import FAQ from "../components/FAQ.astro";
<TestimonialsSection /> <TestimonialsSection />
<PricingSection /> <PricingSection />
<FAQ /> <FAQ />
<HeroSection2 /> <HeroSectionAlt />
</MainLayout> </MainLayout>

View file

@ -1,28 +1,31 @@
--- ---
// Import section components // Importing necessary components
import MainLayout from "../../layouts/MainLayout.astro"; import MainLayout from "../../layouts/MainLayout.astro";
import PrimaryCTA from "../../components/ui/buttons/PrimaryCTA.astro"; import PrimaryCTA from "../../components/ui/buttons/PrimaryCTA.astro";
import CardSmall from "../../components/ui/cards/CardSmall.astro"; import CardSmall from "../../components/ui/cards/CardSmall.astro";
import CardWide from "../../components/ui/cards/CardWide.astro"; import CardWide from "../../components/ui/cards/CardWide.astro";
import FeaturesStats2 from "../../components/FeaturesStats2.astro"; import FeaturesStatsAlt from "../../components/FeaturesStatsAlt.astro";
import TestimonialsSection2 from "../../components/TestimonialsSection2.astro"; import TestimonialsSectionAlt from "../../components/TestimonialsSectionAlt.astro";
// Importing necessary functions from Astro
import { getCollection } from "astro:content"; import { getCollection } from "astro:content";
import type { CollectionEntry } from "astro:content"; import type { CollectionEntry } from "astro:content";
// Fetching all the product related content and sorting it by main.id
const product: CollectionEntry<"products">[] = ( const product: CollectionEntry<"products">[] = (
await getCollection("products") await getCollection("products")
).sort( ).sort(
(a: CollectionEntry<"products">, b: CollectionEntry<"products">) => (a: CollectionEntry<"products">, b: CollectionEntry<"products">) =>
a.data.main.id - b.data.main.id a.data.main.id - b.data.main.id,
); );
// Define variables for page content
const title: string = "Products"; const title: string = "Products";
const subTitle: string = const subTitle: string =
"Explore the durability and precision of ScrewFast tools, designed for both professionals and enthusiasts. Each of our products is crafted with precision and built to last, ensuring you have the right tool for every job."; "Explore the durability and precision of ScrewFast tools, designed for both professionals and enthusiasts. Each of our products is crafted with precision and built to last, ensuring you have the right tool for every job.";
--- ---
<!--Utilizing MainLayout for the outer layout of the page, and defining meta for SEO purposes-->
<MainLayout <MainLayout
title="Products | ScrewFast" title="Products | 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." 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."
@ -46,7 +49,8 @@ const subTitle: string =
</div> </div>
<PrimaryCTA title="Customer Stories" url="#testimonials" noArrow={true} /> <PrimaryCTA title="Customer Stories" url="#testimonials" noArrow={true} />
</div> </div>
<!--Displaying products in alternating styles. Alternative product gets different card styling.-->
<!--Maps through all product entries and displays them with either CardSmall or CardWide based on their position.-->
<div class="grid grid-cols-1 gap-4 sm:grid-cols-3 md:gap-6 xl:gap-8"> <div class="grid grid-cols-1 gap-4 sm:grid-cols-3 md:gap-6 xl:gap-8">
{ {
product.map((product, index) => { product.map((product, index) => {
@ -60,7 +64,8 @@ const subTitle: string =
} }
</div> </div>
</div> </div>
<!--Features statistics section-->
<FeaturesStats2 /> <FeaturesStatsAlt />
<TestimonialsSection2 /> <!--Testimonials section-->
<TestimonialsSectionAlt />
</MainLayout> </MainLayout>