Create Testimonials component with dynamic content

This commit adds a new Testimonials component for the ScrewFast project. The component includes the implementation of `Testimonial` and `StatProps` data types, which are used to display dynamic content. Testimonials and statistics are provided through arrays, which are then mapped to generate respective page elements.
This commit is contained in:
Emil Gulamov 2024-02-12 04:13:57 +04:00
parent d19d0d799d
commit 4c434628e1

View file

@ -0,0 +1,158 @@
---
/* `title` variable used to customise the main heading. */
const title: string = "Fast-Track Your Projects";
/* `subTitle` variable used to customise the sub-heading text. */
const subTitle: string =
"At ScrewFast, we ensure a swift start with instant account setup. Experience the speed of construction redefined.";
/* TypeScript type for testimonials. */
type Testimonial = {
content: string;
author: string;
role: string;
avatarSrc: string;
};
/* An array of testimonials, each being an object that conforms to the above `Testimonial` type. */
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-1542206395-9feb3edaa68d?q=80&w=1528&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
},
];
/* TypeScript type for stats. */
type StatProps = {
count: string;
description: string;
};
/* An array of stats, each being an object that conforms to the above `StatProps` type. */
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",
},
];
---
<div class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14">
<div
class="lg:grid lg:grid-cols-12 lg:items-center lg:justify-between lg:gap-16"
>
<div class="lg:col-span-5 lg:col-start-1">
<!-- Title and description -->
<div class="mb-8">
<h2
class="mb-2 text-3xl font-bold text-neutral-800 dark:text-neutral-200 lg:text-4xl"
>
{title}
</h2>
<p class="text-neutral-600 dark:text-neutral-400">
{subTitle}
</p>
</div>
<!-- Generate a blockquote for each testimonial in the testimonials array by mapping over the array. -->
{
testimonials.map((testimonial) => (
<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"
/>
</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">
<img
class="h-8 w-8 rounded-full"
src={testimonial.avatarSrc}
alt="Image Description"
/>
</div>
<div class="ms-4 grow">
<div class="font-semibold 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 class="mt-10 lg:col-span-6 lg:col-end-13 lg:mt-0">
<div class="space-y-6 sm:space-y-8">
<ul
class="grid grid-cols-2 divide-x-2 divide-y-2 divide-neutral-300 overflow-hidden dark:divide-neutral-700"
>
<!-- Generate a list item for each stat in the statistics array by mapping over the array. -->
{
statistics.map((stat, index) => (
<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}
{stat.count}
</div>
<p class="text-sm text-neutral-600 dark:text-neutral-400 sm:text-base">
{stat.description}
</p>
</li>
))
}
</ul>
</div>
</div>
</div>
</div>