Add new UI components and sections
Added new UI components including Checkbox, StatsBig, and StatsSmall for forms and stats display. Additionally, new layout sections such as FeaturesStats, LeftSection, RightSection, MainSection were added. These various additions and improvements aim to enhance the website's interface and interaction for users.
72
src/components/FeaturesStats.astro
Normal file
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
import StatsBig from "../components/ui/blocks/StatsBig.astro";
|
||||
import StatsSmall from "../components/ui/blocks/StatsSmall.astro";
|
||||
|
||||
const { title, subTitle } = Astro.props;
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
subTitle: string;
|
||||
}
|
||||
|
||||
/* TypeScript type for testimonials. */
|
||||
type Stat = {
|
||||
stat: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
/* An array of testimonials, each being an object that conforms to the above `Testimonial` type. */
|
||||
const stats: Stat[] = [
|
||||
{
|
||||
stat: "99.8%",
|
||||
description: "project completion rate",
|
||||
},
|
||||
{
|
||||
stat: "5,000+",
|
||||
description: "successful installations",
|
||||
},
|
||||
{
|
||||
stat: "85%",
|
||||
description: "client growth year-over-year",
|
||||
},
|
||||
];
|
||||
---
|
||||
|
||||
<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="max-w-screen-md">
|
||||
<h2
|
||||
class="mb-4 text-balance text-3xl font-extrabold tracking-tight text-neutral-800 dark:text-neutral-200"
|
||||
>
|
||||
{title}
|
||||
</h2>
|
||||
<p
|
||||
class="mb-16 max-w-prose text-pretty font-light text-neutral-600 dark:text-neutral-400 sm:text-xl"
|
||||
>
|
||||
{subTitle}
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid items-center gap-6 lg:grid-cols-12 lg:gap-12">
|
||||
<div class="lg:col-span-4">
|
||||
<StatsBig
|
||||
title="96%"
|
||||
subTitle="of our clients rate their experience with ScrewFast as exceptional"
|
||||
/>
|
||||
|
||||
<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"
|
||||
>
|
||||
<div
|
||||
class="grid grid-cols-2 gap-6 sm:gap-8 md:grid-cols-4 lg:grid-cols-3"
|
||||
>
|
||||
{
|
||||
stats.map((stat) => (
|
||||
<StatsSmall title={stat.stat} subTitle={stat.description} />
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
41
src/components/ui/blocks/LeftSection.astro
Normal file
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
import { Image } from "astro:assets";
|
||||
import PrimaryCTA from "../buttons/PrimaryCTA.astro";
|
||||
|
||||
const { title, subTitle, btn, btnTitle, btnURL, img, imgAlt } =
|
||||
Astro.props;
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
subTitle: string;
|
||||
btn?: boolean;
|
||||
btnTitle?: string;
|
||||
btnURL?: string;
|
||||
img: any;
|
||||
imgAlt: any;
|
||||
}
|
||||
---
|
||||
|
||||
<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"
|
||||
>
|
||||
<Image
|
||||
class="w-full rounded-lg"
|
||||
src={img}
|
||||
alt={imgAlt}
|
||||
format={"avif"}
|
||||
/>
|
||||
<div class="mt-4 md:mt-0">
|
||||
<h2
|
||||
class="mb-4 text-balance text-4xl font-extrabold tracking-tight text-neutral-800 dark:text-neutral-200"
|
||||
>
|
||||
{title}
|
||||
</h2>
|
||||
<p
|
||||
class="mb-4 max-w-prose text-pretty font-light text-neutral-600 dark:text-neutral-400 sm:text-lg"
|
||||
>
|
||||
{subTitle}
|
||||
</p>
|
||||
{btn ? <PrimaryCTA title={btnTitle} url={btnURL} /> : null}
|
||||
</div>
|
||||
</section>
|
37
src/components/ui/blocks/MainSection.astro
Normal file
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
import PrimaryCTA from "../buttons/PrimaryCTA.astro";
|
||||
|
||||
const { title, subTitle, btn, btnTitle, btnURL } = Astro.props;
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
subTitle: string;
|
||||
btn?: boolean;
|
||||
btnTitle?: string;
|
||||
btnURL?: string;
|
||||
}
|
||||
---
|
||||
|
||||
<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"
|
||||
>
|
||||
<div class="max-w-screen-md">
|
||||
<h1
|
||||
class="mb-4 text-balance text-4xl font-extrabold tracking-tight text-neutral-800 dark:text-neutral-200"
|
||||
>
|
||||
{title}
|
||||
</h1>
|
||||
<p
|
||||
class="mb-8 max-w-prose text-pretty font-light text-neutral-600 dark:text-neutral-400 sm:text-xl"
|
||||
>
|
||||
{subTitle}
|
||||
</p>
|
||||
{
|
||||
btn ? (
|
||||
<div class="flex flex-col space-y-4 sm:flex-row sm:space-x-4 sm:space-y-0">
|
||||
<PrimaryCTA title={btnTitle} url={btnURL} />
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
</div>
|
||||
</section>
|
75
src/components/ui/blocks/RightSection.astro
Normal file
|
@ -0,0 +1,75 @@
|
|||
---
|
||||
import { Image } from "astro:assets";
|
||||
import PrimaryCTA from "../buttons/PrimaryCTA.astro";
|
||||
|
||||
const {
|
||||
title,
|
||||
subTitle,
|
||||
btn,
|
||||
btnTitle,
|
||||
btnURL,
|
||||
single,
|
||||
imgOne,
|
||||
imgOneAlt,
|
||||
imgTwo,
|
||||
imgTwoAlt,
|
||||
} = Astro.props;
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
subTitle: string;
|
||||
btn?: boolean;
|
||||
btnTitle?: string;
|
||||
btnURL?: string;
|
||||
single?: boolean;
|
||||
imgOne?: any;
|
||||
imgOneAlt?: any;
|
||||
imgTwo?: any;
|
||||
imgTwoAlt?: any;
|
||||
}
|
||||
---
|
||||
|
||||
<section
|
||||
class="mx-auto max-w-[85rem] items-center gap-16 px-4 py-10 sm:px-6 lg:grid lg:grid-cols-2 lg:px-8 lg:py-14 2xl:max-w-full"
|
||||
>
|
||||
<div>
|
||||
<h2
|
||||
class="mb-4 text-balance text-4xl font-extrabold tracking-tight text-neutral-800 dark:text-neutral-200"
|
||||
>
|
||||
{title}
|
||||
</h2>
|
||||
<p
|
||||
class="mb-4 max-w-prose text-pretty font-light text-neutral-600 dark:text-neutral-400 sm:text-lg"
|
||||
>
|
||||
{subTitle}
|
||||
</p>
|
||||
{btn ? <PrimaryCTA title={btnTitle} url={btnURL} /> : null}
|
||||
</div>
|
||||
{
|
||||
single ? (
|
||||
<div class="mt-8">
|
||||
<Image
|
||||
class="w-full rounded-lg"
|
||||
src={imgOne}
|
||||
alt={imgOneAlt}
|
||||
format={"avif"}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div class="mt-8 grid grid-cols-2 gap-4">
|
||||
<Image
|
||||
class="w-full rounded-lg"
|
||||
src={imgOne}
|
||||
alt={imgOneAlt}
|
||||
format={"avif"}
|
||||
/>
|
||||
<Image
|
||||
class="mt-4 w-full rounded-lg lg:mt-10"
|
||||
src={imgTwo}
|
||||
alt={imgTwoAlt}
|
||||
format={"avif"}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</section>
|
15
src/components/ui/blocks/StatsBig.astro
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
const { title, subTitle } = Astro.props;
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
subTitle: string;
|
||||
}
|
||||
---
|
||||
<div class="lg:pe-6 xl:pe-12">
|
||||
<p class="text-6xl font-bold leading-10 text-[#fa5a15] dark:text-[#fb713b]">
|
||||
{title}
|
||||
|
||||
</p>
|
||||
<p class="mt-2 sm:mt-3 text-neutral-600 dark:text-neutral-400">{subTitle}</p>
|
||||
</div>
|
13
src/components/ui/blocks/StatsSmall.astro
Normal file
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
const { title, subTitle } = Astro.props;
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
subTitle: string;
|
||||
}
|
||||
---
|
||||
|
||||
<div>
|
||||
<p class="text-3xl font-bold text-[#fa5a15] dark:text-[#fb713b]">{title}</p>
|
||||
<p class="mt-1 text-neutral-600 dark:text-neutral-400">{subTitle}</p>
|
||||
</div>
|
16
src/components/ui/forms/input/Checkbox.astro
Normal file
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
const { label = "Remember me", id } = Astro.props;
|
||||
|
||||
interface Props {
|
||||
label?: string;
|
||||
id?: string;
|
||||
}
|
||||
---
|
||||
<div class="flex items-center">
|
||||
<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">
|
||||
</div>
|
||||
<div class="ms-3">
|
||||
<label for={id} class="text-sm text-neutral-800 dark:text-neutral-200">{label} <slot /> </label>
|
||||
</div>
|
||||
</div>
|
BIN
src/images/aerial-view.avif
Normal file
After Width: | Height: | Size: 358 KiB |
BIN
src/images/before-after-1.avif
Normal file
After Width: | Height: | Size: 236 KiB |
BIN
src/images/before-after.avif
Normal file
After Width: | Height: | Size: 111 KiB |
BIN
src/images/blueprints-image.avif
Normal file
After Width: | Height: | Size: 97 KiB |
BIN
src/images/construction-worker.avif
Normal file
After Width: | Height: | Size: 122 KiB |
BIN
src/images/construction-workers.avif
Normal file
After Width: | Height: | Size: 365 KiB |
BIN
src/images/person-working.avif
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
src/images/progress-building.avif
Normal file
After Width: | Height: | Size: 515 KiB |
BIN
src/images/under-construction.avif
Normal file
After Width: | Height: | Size: 285 KiB |
BIN
src/images/using-tools.avif
Normal file
After Width: | Height: | Size: 69 KiB |