Update components/testimonials.tsx
This commit is contained in:
parent
a670c2623d
commit
df3b243dbb
|
|
@ -0,0 +1,325 @@
|
|||
"use client";
|
||||
|
||||
import { Heading } from "./heading";
|
||||
import { Subheading } from "./subheading";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { InViewDiv } from "./in-view-div";
|
||||
import { useMemo } from "react";
|
||||
import { TestimonialColumnContainer } from "./testimonial-column-container";
|
||||
import Image from "next/image";
|
||||
|
||||
export const Testimonials = () => {
|
||||
return (
|
||||
<div className="relative z-20 py-10 md:py-40">
|
||||
<Heading as="h2">Loved by people all over the universe</Heading>
|
||||
<Subheading className="text-center max-w-lg mx-auto">
|
||||
[App Name] is trusted by users worldwide. Join our growing community of
|
||||
satisfied customers.
|
||||
</Subheading>
|
||||
<TestimonialGrid />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface Testimonial {
|
||||
name: string;
|
||||
quote: string;
|
||||
src: string;
|
||||
designation?: string;
|
||||
}
|
||||
|
||||
const testimonials = [
|
||||
{
|
||||
name: "Manu Arora",
|
||||
quote:
|
||||
"[App Name] has completely transformed the way I approach problems and develop solutions. I absolutely love it!",
|
||||
src: "https://i.pravatar.cc/150?img=1",
|
||||
designation: "Tech Innovator & Entrepreneur",
|
||||
},
|
||||
{
|
||||
name: "Tyler Durden",
|
||||
quote:
|
||||
"I made a soap with the help of AI, it was so easy to use. I'm so glad this happened because it revolutionized my entire business model and production process.",
|
||||
src: "https://i.pravatar.cc/150?img=2",
|
||||
designation: "Creative Director & Business Owner",
|
||||
},
|
||||
{
|
||||
name: "Alice Johnson",
|
||||
quote:
|
||||
"This AI has transformed the way I work! It's like having a brilliant assistant who knows exactly what I need before I even ask.",
|
||||
src: "https://i.pravatar.cc/150?img=3",
|
||||
designation: "Senior Software Engineer",
|
||||
},
|
||||
{
|
||||
name: "Bob Smith",
|
||||
quote:
|
||||
"Absolutely revolutionary, a game-changer for our industry. It has streamlined our processes and enhanced our productivity dramatically.",
|
||||
src: "https://i.pravatar.cc/150?img=4",
|
||||
designation: "Industry Analyst",
|
||||
},
|
||||
{
|
||||
name: "Cathy Lee",
|
||||
quote:
|
||||
"I can't imagine going back to how things were before this AI. It has not only improved my work efficiency but also my daily life.",
|
||||
src: "https://i.pravatar.cc/150?img=5",
|
||||
designation: "Product Manager",
|
||||
},
|
||||
{
|
||||
name: "David Wright",
|
||||
quote:
|
||||
"It's like having a superpower! This AI tool has given us the ability to do things we never thought were possible in our field.",
|
||||
src: "https://i.pravatar.cc/150?img=6",
|
||||
designation: "Research Scientist",
|
||||
},
|
||||
{
|
||||
name: "Eva Green",
|
||||
quote:
|
||||
"The efficiency it brings is unmatched. It's a vital tool that has helped us cut costs and improve our end product significantly.",
|
||||
src: "https://i.pravatar.cc/150?img=7",
|
||||
designation: "Operations Director",
|
||||
},
|
||||
{
|
||||
name: "Frank Moore",
|
||||
quote:
|
||||
"A robust solution that fits perfectly into our workflow. It has enhanced our team's capabilities and allowed us to tackle more complex projects.",
|
||||
src: "https://i.pravatar.cc/150?img=8",
|
||||
designation: "Project Manager",
|
||||
},
|
||||
{
|
||||
name: "Grace Hall",
|
||||
quote:
|
||||
"It's incredibly intuitive and easy to use. Even those without technical expertise can leverage its power to improve their workflows.",
|
||||
src: "https://i.pravatar.cc/150?img=9",
|
||||
designation: "Marketing Specialist",
|
||||
},
|
||||
{
|
||||
name: "Henry Ford",
|
||||
quote:
|
||||
"It has saved us countless hours. Highly recommended for anyone looking to enhance their efficiency and productivity.",
|
||||
src: "https://i.pravatar.cc/150?img=10",
|
||||
designation: "Operations Analyst",
|
||||
},
|
||||
{
|
||||
name: "Ivy Wilson",
|
||||
quote:
|
||||
"A must-have tool for any professional. It's revolutionized the way we approach problem-solving and decision-making.",
|
||||
src: "https://i.pravatar.cc/150?img=11",
|
||||
designation: "Business Consultant",
|
||||
},
|
||||
{
|
||||
name: "Jack Brown",
|
||||
quote:
|
||||
"The results are always impressive. This AI has helped us to not only meet but exceed our performance targets.",
|
||||
src: "https://i.pravatar.cc/150?img=12",
|
||||
designation: "Performance Manager",
|
||||
},
|
||||
{
|
||||
name: "Kathy Adams",
|
||||
quote:
|
||||
"It helps us achieve what was once thought impossible. The AI's capabilities are groundbreaking and have opened new avenues for us.",
|
||||
src: "https://i.pravatar.cc/150?img=13",
|
||||
designation: "Innovation Lead",
|
||||
},
|
||||
{
|
||||
name: "Leo Carter",
|
||||
quote:
|
||||
"Transformative technology with real impact. It has streamlined our operations and brought unprecedented efficiency to our processes.",
|
||||
src: "https://i.pravatar.cc/150?img=14",
|
||||
designation: "Technology Strategist",
|
||||
},
|
||||
{
|
||||
name: "Mia Turner",
|
||||
quote:
|
||||
"It's simply revolutionary! The way it integrates with our existing systems and enhances them is nothing short of miraculous.",
|
||||
src: "https://i.pravatar.cc/150?img=15",
|
||||
designation: "Systems Integrator",
|
||||
},
|
||||
{
|
||||
name: "Nathan Hill",
|
||||
quote:
|
||||
"The best investment we've made in years. It's not just a tool; it's a game-changer that has propelled our business forward.",
|
||||
src: "https://i.pravatar.cc/150?img=16",
|
||||
designation: "Investment Analyst",
|
||||
},
|
||||
{
|
||||
name: "Olivia Scott",
|
||||
quote:
|
||||
"It consistently exceeds our expectations. Its adaptability and precision make it indispensable for our daily operations.",
|
||||
src: "https://i.pravatar.cc/150?img=17",
|
||||
designation: "Quality Assurance Manager",
|
||||
},
|
||||
{
|
||||
name: "Peter White",
|
||||
quote:
|
||||
"A seamless integration into our daily tasks. It has enhanced our productivity and allowed us to focus on more strategic initiatives.",
|
||||
src: "https://i.pravatar.cc/150?img=18",
|
||||
designation: "Strategic Planner",
|
||||
},
|
||||
{
|
||||
name: "Quinn Taylor",
|
||||
quote:
|
||||
"It's a game-changer for our business. The insights it provides are invaluable and have driven substantial growth for us.",
|
||||
src: "https://i.pravatar.cc/150?img=19",
|
||||
designation: "Growth Manager",
|
||||
},
|
||||
{
|
||||
name: "Rachel Black",
|
||||
quote:
|
||||
"The support team is as impressive as the technology itself. They ensure we maximize the utility of the AI in our operations.",
|
||||
src: "https://i.pravatar.cc/150?img=20",
|
||||
designation: "Client Support Coordinator",
|
||||
},
|
||||
{
|
||||
name: "Samuel Lee",
|
||||
quote:
|
||||
"It's the future, now. Adopting this AI has put us years ahead of the competition in terms of operational efficiency and innovation.",
|
||||
src: "https://i.pravatar.cc/150?img=21",
|
||||
designation: "Futurist",
|
||||
},
|
||||
{
|
||||
name: "Tina Brooks",
|
||||
quote:
|
||||
"It has completely changed the way we operate. The AI's ability to analyze and optimize our processes is phenomenal.",
|
||||
src: "https://i.pravatar.cc/150?img=22",
|
||||
designation: "Process Analyst",
|
||||
},
|
||||
];
|
||||
|
||||
function Testimonial({
|
||||
name,
|
||||
quote,
|
||||
src,
|
||||
designation,
|
||||
className,
|
||||
...props
|
||||
}: Omit<React.ComponentPropsWithoutRef<"figure">, keyof Testimonial> &
|
||||
Testimonial) {
|
||||
let animationDelay = useMemo(() => {
|
||||
let possibleAnimationDelays = [
|
||||
"0s",
|
||||
"0.1s",
|
||||
"0.2s",
|
||||
"0.3s",
|
||||
"0.4s",
|
||||
"0.5s",
|
||||
];
|
||||
return possibleAnimationDelays[
|
||||
Math.floor(Math.random() * possibleAnimationDelays.length)
|
||||
];
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<figure
|
||||
className={cn(
|
||||
"animate-fade-in rounded-3xl bg-transparent p-8 opacity-0 shadow-derek dark:bg-neutral-900",
|
||||
className,
|
||||
)}
|
||||
style={{
|
||||
animationDelay,
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
<div className="flex flex-col items-start">
|
||||
<div className="flex gap-2">
|
||||
<Image
|
||||
src={src}
|
||||
width={150}
|
||||
height={150}
|
||||
className="h-10 w-10 rounded-full"
|
||||
alt={name}
|
||||
/>
|
||||
<div>
|
||||
<h3 className="text-sm font-medium text-neutral-500 dark:text-neutral-300">
|
||||
{name}
|
||||
</h3>
|
||||
<p className="text-sm font-normal text-neutral-500 dark:text-neutral-300">
|
||||
{designation}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-base text-muted mt-4 dark:text-muted-dark">
|
||||
{quote}
|
||||
</p>
|
||||
</div>
|
||||
</figure>
|
||||
);
|
||||
}
|
||||
|
||||
function TestimonialColumn({
|
||||
testimonials,
|
||||
className,
|
||||
containerClassName,
|
||||
shift = 0,
|
||||
}: {
|
||||
testimonials: Testimonial[];
|
||||
className?: string;
|
||||
containerClassName?: (reviewIndex: number) => string;
|
||||
shift?: number;
|
||||
}) {
|
||||
return (
|
||||
<TestimonialColumnContainer className={cn(className)} shift={shift}>
|
||||
{testimonials
|
||||
.concat(testimonials)
|
||||
.map((testimonial, testimonialIndex) => (
|
||||
<Testimonial
|
||||
name={testimonial.name}
|
||||
quote={testimonial.quote}
|
||||
src={testimonial.src}
|
||||
designation={testimonial.designation}
|
||||
key={testimonialIndex}
|
||||
className={containerClassName?.(
|
||||
testimonialIndex % testimonials.length,
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</TestimonialColumnContainer>
|
||||
);
|
||||
}
|
||||
|
||||
function splitArray<T>(array: Array<T>, numParts: number) {
|
||||
let result: Array<Array<T>> = [];
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
let index = i % numParts;
|
||||
if (!result[index]) {
|
||||
result[index] = [];
|
||||
}
|
||||
result[index].push(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function TestimonialGrid() {
|
||||
let columns = splitArray(testimonials, 3);
|
||||
let column1 = columns[0];
|
||||
let column2 = columns[1];
|
||||
let column3 = splitArray(columns[2], 2);
|
||||
return (
|
||||
<InViewDiv className="relative -mx-4 mt-16 grid h-[49rem] max-h-[150vh] grid-cols-1 items-start gap-8 overflow-hidden px-4 sm:mt-20 md:grid-cols-2 lg:grid-cols-3">
|
||||
<TestimonialColumn
|
||||
testimonials={[...column1, ...column3.flat(), ...column2]}
|
||||
containerClassName={(tIndex) =>
|
||||
cn(
|
||||
tIndex >= column1.length + column3[0].length && "md:hidden",
|
||||
tIndex >= column1.length && "lg:hidden",
|
||||
)
|
||||
}
|
||||
shift={10}
|
||||
/>
|
||||
<TestimonialColumn
|
||||
testimonials={[...column2, ...column3[1]]}
|
||||
className="hidden md:block"
|
||||
containerClassName={(tIndex) =>
|
||||
tIndex >= column2.length ? "lg:hidden" : ""
|
||||
}
|
||||
shift={15}
|
||||
/>
|
||||
<TestimonialColumn
|
||||
testimonials={column3.flat()}
|
||||
className="hidden lg:block"
|
||||
shift={10}
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-x-0 top-0 h-32 bg-gradient-to-b from-white dark:from-black" />
|
||||
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-32 bg-gradient-to-t from-white dark:from-black" />
|
||||
</InViewDiv>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue