Add TestimonialItem and StatsGrid components
This commit introduces two new components (TestimonialItem and StatsGrid) to modularize the display of testimonial and statistics information. It also updates the TestimonialsSection to utilize these new components and receive parameters through its props. The MainPage's data source has been adjusted to send the required props for these changes.
This commit is contained in:
parent
2ec0e1975f
commit
041ed7d55a
4 changed files with 156 additions and 106 deletions
52
src/components/sections/testimonials/TestimonialItem.astro
Normal file
52
src/components/sections/testimonials/TestimonialItem.astro
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
import { Image } from "astro:assets";
|
||||||
|
|
||||||
|
const { content, author, role, avatarSrc } = Astro.props;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
content: string;
|
||||||
|
author: string;
|
||||||
|
role: string;
|
||||||
|
avatarSrc: string;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<blockquote class="relative">
|
||||||
|
<svg
|
||||||
|
class="absolute start-0 top-0 h-16 w-16 -translate-x-6 -translate-y-8 transform text-neutral-300 dark:text-neutral-700"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
fill="none"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M7.39762 10.3C7.39762 11.0733 7.14888 11.7 6.6514 12.18C6.15392 12.6333 5.52552 12.86 4.76621 12.86C3.84979 12.86 3.09047 12.5533 2.48825 11.94C1.91222 11.3266 1.62421 10.4467 1.62421 9.29999C1.62421 8.07332 1.96459 6.87332 2.64535 5.69999C3.35231 4.49999 4.33418 3.55332 5.59098 2.85999L6.4943 4.25999C5.81354 4.73999 5.26369 5.27332 4.84476 5.85999C4.45201 6.44666 4.19017 7.12666 4.05926 7.89999C4.29491 7.79332 4.56983 7.73999 4.88403 7.73999C5.61716 7.73999 6.21938 7.97999 6.69067 8.45999C7.16197 8.93999 7.39762 9.55333 7.39762 10.3ZM14.6242 10.3C14.6242 11.0733 14.3755 11.7 13.878 12.18C13.3805 12.6333 12.7521 12.86 11.9928 12.86C11.0764 12.86 10.3171 12.5533 9.71484 11.94C9.13881 11.3266 8.85079 10.4467 8.85079 9.29999C8.85079 8.07332 9.19117 6.87332 9.87194 5.69999C10.5789 4.49999 11.5608 3.55332 12.8176 2.85999L13.7209 4.25999C13.0401 4.73999 12.4903 5.27332 12.0713 5.85999C11.6786 6.44666 11.4168 7.12666 11.2858 7.89999C11.5215 7.79332 11.7964 7.73999 12.1106 7.73999C12.8437 7.73999 13.446 7.97999 13.9173 8.45999C14.3886 8.93999 14.6242 9.55333 14.6242 10.3Z"
|
||||||
|
fill="currentColor"></path>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<div class="relative z-10">
|
||||||
|
<p class="text-xl italic text-neutral-800 dark:text-neutral-200">
|
||||||
|
{content}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-6">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<Image
|
||||||
|
class="h-8 w-8 rounded-full"
|
||||||
|
src={avatarSrc}
|
||||||
|
alt="Avatar Description"
|
||||||
|
inferSize
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="ms-4 grow">
|
||||||
|
<div class="font-bold text-neutral-800 dark:text-neutral-200">
|
||||||
|
{author}
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-neutral-500">{role}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</blockquote>
|
|
@ -1,9 +1,20 @@
|
||||||
---
|
---
|
||||||
import { Image } from "astro:assets";
|
import TestimonialItem from "./TestimonialItem.astro";
|
||||||
// Define constants for content
|
import StatsGrid from "../../ui/blocks/StatsGrid.astro";
|
||||||
const title: string = "Fast-Track Your Projects";
|
|
||||||
const subTitle: string =
|
const {
|
||||||
"At ScrewFast, we ensure a swift start with instant account setup. Experience the speed of construction redefined.";
|
title,
|
||||||
|
subTitle,
|
||||||
|
testimonials,
|
||||||
|
statistics
|
||||||
|
} = Astro.props;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
title: string;
|
||||||
|
subTitle?: string;
|
||||||
|
testimonials?: Testimonial[];
|
||||||
|
statistics?: StatProps[];
|
||||||
|
}
|
||||||
|
|
||||||
// TypeScript type for testimonials
|
// TypeScript type for testimonials
|
||||||
type Testimonial = {
|
type Testimonial = {
|
||||||
|
@ -13,44 +24,11 @@ type Testimonial = {
|
||||||
avatarSrc: string;
|
avatarSrc: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// An array of testimonials
|
|
||||||
const testimonials: Testimonial[] = [
|
|
||||||
{
|
|
||||||
content:
|
|
||||||
"ScrewFast dramatically boosted our project efficiency. Setup was instant, and their rapid response times are phenomenal. Truly a game-changer in hardware and construction support!",
|
|
||||||
author: "Samantha Ruiz",
|
|
||||||
role: "Chief Operating Officer | ConstructIt Inc.",
|
|
||||||
avatarSrc:
|
|
||||||
"https://images.unsplash.com/photo-1593104547489-5cfb3839a3b5?q=80&w=1453&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D8&auto=format&fit=facearea&facepad=2&w=320&h=320&q=80",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// TypeScript type for stats.
|
// TypeScript type for stats.
|
||||||
type StatProps = {
|
type StatProps = {
|
||||||
count: string;
|
count: string;
|
||||||
description: string;
|
description: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// An array of stats
|
|
||||||
const statistics: StatProps[] = [
|
|
||||||
{
|
|
||||||
count: "70k+",
|
|
||||||
description: "customers equipped — from DIY to major construction firms",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
count: "35%",
|
|
||||||
description:
|
|
||||||
"uptick in project efficiency with ScrewFast tools and services",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
count: "15.3%",
|
|
||||||
description: "reduction in maintenance costs reported by long-term clients",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
count: "2x",
|
|
||||||
description: "quicker assembly using innovative fastening solutions",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<section
|
<section
|
||||||
|
@ -68,58 +46,21 @@ const statistics: StatProps[] = [
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
</h2>
|
</h2>
|
||||||
|
{subTitle &&
|
||||||
<p class="text-neutral-600 dark:text-neutral-400">
|
<p class="text-neutral-600 dark:text-neutral-400">
|
||||||
{subTitle}
|
{subTitle}
|
||||||
</p>
|
</p>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Generate a blockquote for each testimonial in the testimonials array by mapping over the array. -->
|
<!-- Generate a blockquote for each testimonial in the testimonials array by mapping over the array. -->
|
||||||
{
|
{ testimonials &&
|
||||||
testimonials.map((testimonial) => (
|
testimonials.map((testimonial) => (
|
||||||
<blockquote class="relative">
|
<TestimonialItem content={testimonial.content} author={testimonial.author} role={testimonial.role} avatarSrc={testimonial.avatarSrc} />
|
||||||
<svg
|
|
||||||
class="absolute start-0 top-0 h-16 w-16 -translate-x-6 -translate-y-8 transform text-neutral-300 dark:text-neutral-700"
|
|
||||||
width="16"
|
|
||||||
height="16"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
fill="none"
|
|
||||||
aria-hidden="true"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M7.39762 10.3C7.39762 11.0733 7.14888 11.7 6.6514 12.18C6.15392 12.6333 5.52552 12.86 4.76621 12.86C3.84979 12.86 3.09047 12.5533 2.48825 11.94C1.91222 11.3266 1.62421 10.4467 1.62421 9.29999C1.62421 8.07332 1.96459 6.87332 2.64535 5.69999C3.35231 4.49999 4.33418 3.55332 5.59098 2.85999L6.4943 4.25999C5.81354 4.73999 5.26369 5.27332 4.84476 5.85999C4.45201 6.44666 4.19017 7.12666 4.05926 7.89999C4.29491 7.79332 4.56983 7.73999 4.88403 7.73999C5.61716 7.73999 6.21938 7.97999 6.69067 8.45999C7.16197 8.93999 7.39762 9.55333 7.39762 10.3ZM14.6242 10.3C14.6242 11.0733 14.3755 11.7 13.878 12.18C13.3805 12.6333 12.7521 12.86 11.9928 12.86C11.0764 12.86 10.3171 12.5533 9.71484 11.94C9.13881 11.3266 8.85079 10.4467 8.85079 9.29999C8.85079 8.07332 9.19117 6.87332 9.87194 5.69999C10.5789 4.49999 11.5608 3.55332 12.8176 2.85999L13.7209 4.25999C13.0401 4.73999 12.4903 5.27332 12.0713 5.85999C11.6786 6.44666 11.4168 7.12666 11.2858 7.89999C11.5215 7.79332 11.7964 7.73999 12.1106 7.73999C12.8437 7.73999 13.446 7.97999 13.9173 8.45999C14.3886 8.93999 14.6242 9.55333 14.6242 10.3Z"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<div class="relative z-10">
|
|
||||||
<p class="text-xl italic text-neutral-800 dark:text-neutral-200">
|
|
||||||
{testimonial.content}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer class="mt-6">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<div class="flex-shrink-0">
|
|
||||||
<Image
|
|
||||||
class="h-8 w-8 rounded-full"
|
|
||||||
src={testimonial.avatarSrc}
|
|
||||||
alt="Avatar Description"
|
|
||||||
inferSize
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="ms-4 grow">
|
|
||||||
<div class="font-bold text-neutral-800 dark:text-neutral-200">
|
|
||||||
{testimonial.author}
|
|
||||||
</div>
|
|
||||||
<div class="text-xs text-neutral-500">{testimonial.role}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</blockquote>
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
{ statistics &&
|
||||||
<div class="mt-10 lg:col-span-6 lg:col-end-13 lg:mt-0">
|
<div class="mt-10 lg:col-span-6 lg:col-end-13 lg:mt-0">
|
||||||
<div class="space-y-6 sm:space-y-8">
|
<div class="space-y-6 sm:space-y-8">
|
||||||
<ul
|
<ul
|
||||||
|
@ -128,34 +69,12 @@ const statistics: StatProps[] = [
|
||||||
<!-- Generate a list item for each stat in the statistics array by mapping over the array. -->
|
<!-- Generate a list item for each stat in the statistics array by mapping over the array. -->
|
||||||
{
|
{
|
||||||
statistics.map((stat, index) => (
|
statistics.map((stat, index) => (
|
||||||
<li class="-m-0.5 flex flex-col p-4 sm:p-8">
|
<StatsGrid count={stat.count} description={stat.description} index={index}/>
|
||||||
<div class="mb-2 flex items-end gap-x-2 text-3xl font-bold text-neutral-800 dark:text-neutral-200 sm:text-5xl">
|
|
||||||
{index === 1 || index === 2 ? (
|
|
||||||
<svg
|
|
||||||
class="h-5 w-5 flex-shrink-0 text-[#fa5a15] dark:text-[#fb713b]"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path d="m5 12 7-7 7 7" />
|
|
||||||
<path d="M12 19V5" />
|
|
||||||
</svg>
|
|
||||||
) : null}
|
|
||||||
{stat.count}
|
|
||||||
</div>
|
|
||||||
<p class="text-sm text-neutral-600 dark:text-neutral-400 sm:text-base">
|
|
||||||
{stat.description}
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
38
src/components/ui/blocks/StatsGrid.astro
Normal file
38
src/components/ui/blocks/StatsGrid.astro
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
const { count, description, index } = Astro.props;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
count: string;
|
||||||
|
description: string;
|
||||||
|
index: number;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<li class="-m-0.5 flex flex-col p-4 sm:p-8">
|
||||||
|
<div
|
||||||
|
class="mb-2 flex items-end gap-x-2 text-3xl font-bold text-neutral-800 dark:text-neutral-200 sm:text-5xl"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
index === 1 || index === 2 ? (
|
||||||
|
<svg
|
||||||
|
class="h-5 w-5 flex-shrink-0 text-[#fa5a15] dark:text-[#fb713b]"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path d="m5 12 7-7 7 7" />
|
||||||
|
<path d="M12 19V5" />
|
||||||
|
</svg>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
{count}
|
||||||
|
</div>
|
||||||
|
<p class="text-sm text-neutral-600 dark:text-neutral-400 sm:text-base">
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
</li>
|
|
@ -14,7 +14,7 @@ const avatarSrcs: Array<string> = [
|
||||||
"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",
|
"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",
|
||||||
"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",
|
"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",
|
||||||
"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",
|
"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",
|
||||||
"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"
|
"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",
|
||||||
];
|
];
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -38,11 +38,52 @@ const avatarSrcs: Array<string> = [
|
||||||
title="Trusted by Industry Leaders"
|
title="Trusted by Industry Leaders"
|
||||||
subTitle="Experience the reliability chosen by industry giants."
|
subTitle="Experience the reliability chosen by industry giants."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FeaturesGeneral />
|
<FeaturesGeneral />
|
||||||
|
|
||||||
<FeaturesNavs />
|
<FeaturesNavs />
|
||||||
<TestimonialsSection />
|
|
||||||
|
<TestimonialsSection
|
||||||
|
title="Fast-Track Your Projects"
|
||||||
|
subTitle="At ScrewFast, we ensure a swift start with instant account setup. Experience the speed of construction redefined."
|
||||||
|
;
|
||||||
|
testimonials={[
|
||||||
|
{
|
||||||
|
content:
|
||||||
|
"ScrewFast dramatically boosted our project efficiency. Setup was instant, and their rapid response times are phenomenal. Truly a game-changer in hardware and construction support!",
|
||||||
|
author: "Samantha Ruiz",
|
||||||
|
role: "Chief Operating Officer | ConstructIt Inc.",
|
||||||
|
avatarSrc:
|
||||||
|
"https://images.unsplash.com/photo-1593104547489-5cfb3839a3b5?q=80&w=1453&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D8&auto=format&fit=facearea&facepad=2&w=320&h=320&q=80",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
statistics={[
|
||||||
|
{
|
||||||
|
count: "70k+",
|
||||||
|
description:
|
||||||
|
"customers equipped — from DIY to major construction firms",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
count: "35%",
|
||||||
|
description:
|
||||||
|
"uptick in project efficiency with ScrewFast tools and services",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
count: "15.3%",
|
||||||
|
description:
|
||||||
|
"reduction in maintenance costs reported by long-term clients",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
count: "2x",
|
||||||
|
description: "quicker assembly using innovative fastening solutions",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
<PricingSection />
|
<PricingSection />
|
||||||
|
|
||||||
<FAQ />
|
<FAQ />
|
||||||
|
|
||||||
<HeroSectionAlt
|
<HeroSectionAlt
|
||||||
title="Let's Build Together"
|
title="Let's Build Together"
|
||||||
subTitle="ScrewFast is an open-source template, meticulously crafted with Astro, Tailwind CSS, and Preline UI frameworks."
|
subTitle="ScrewFast is an open-source template, meticulously crafted with Astro, Tailwind CSS, and Preline UI frameworks."
|
||||||
|
|
Loading…
Add table
Reference in a new issue