Files
whispering-tree/sections/Testimonial.tsx
2025-11-10 17:10:34 +05:30

187 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { Marquee } from "@/components/ui/logo-marquee";
import { TestimonialCard } from "@/components/ui/testimonial-marquee";
import { useEffect, useRef } from "react";
import gsap from "gsap";
import SplitText from "gsap/SplitText";
import ScrollTrigger from "gsap/ScrollTrigger";
import Headline from "@/components/ui/headline";
import { useSplitHeading } from "@/lib/useTextRevealHeading";
gsap.registerPlugin(SplitText, ScrollTrigger);
const testimonials = [
{
id: 1,
name: "Dazzle Healer",
role: "Front End Developer",
avatar: "/images/png/Avatar.png",
message:
"I've used other kits, but this one is the best. The attention to detail and usability are truly amazing for all designers. I highly recommend it for any type of project.",
},
{
id: 2,
name: "Ammy Johnson",
role: "Scientific Advisor",
avatar: "/images/png/Avatar (2).png",
message:
"The level of accuracy and precision in the data analytics blew me away. Whispering Tree makes environmental monitoring so much easier for our teams.",
},
{
id: 3,
name: "Leo Smith",
role: "Urban Planner",
avatar: "/images/png/Avatar (1).png",
message:
"Integrating the IoT sensors into our citys green spaces helped us reduce water usage by over 30%. Its a game-changer for sustainable urban development.",
},
{
id: 4,
name: "Sofia Martins",
role: "Research Scientist",
avatar: "/images/png/Avatar (3).png",
message:
"Real-time health insights from trees have opened a whole new perspective for environmental research. Its efficient, reliable, and visually elegant.",
},
{
id: 5,
name: "Michael Chen",
role: "Environmental Engineer",
avatar: "/images/png/Avatar (4).png",
message:
"Our city parks have become smarter and greener since adopting Whispering Tree. The platforms clarity in reports is unmatched.",
},
{
id: 6,
name: "Laura Green",
role: "Sustainability Consultant",
avatar: "/images/png/Avatar (1).png",
message:
"Its refreshing to see technology being used for natures benefit. The dashboards are intuitive and provide deep insights for eco-management.",
},
{
id: 7,
name: "David Kim",
role: "IoT Solutions Architect",
avatar: "/images/png/Avatar (4).png",
message:
"The ease of integrating sensors into existing infrastructure made implementation seamless. Great work by the Whispering Tree team!",
},
{
id: 8,
name: "Priya Nair",
role: "Climate Research Analyst",
avatar: "/images/png/Avatar.png",
message:
"This platform allows us to visualize and act on real environmental data in real time. The insights are helping cities adapt sustainably.",
},
];
const Testimonial = () => {
const headingRef = useRef<HTMLHeadingElement | null>(null);
const paraRef = useRef<HTMLParagraphElement | null>(null);
const containerRef = useRef<HTMLDivElement | null>(null);
useSplitHeading(headingRef, paraRef);
const middleIndex = Math.ceil(testimonials.length / 2);
const firstHalf = testimonials.slice(0, middleIndex);
const secondHalf = testimonials.slice(middleIndex);
useEffect(() => {
gsap.registerPlugin(ScrollTrigger);
const cards = gsap.utils.toArray<HTMLDivElement>(".test-card");
gsap.from(cards, {
y: 100,
opacity: 0,
duration: 1.2,
ease: "power3.out",
stagger: 0.19,
scrollTrigger: {
trigger: ".test-wrapper",
start: "top 80%",
end: "bottom 60%",
toggleActions: "play none none none",
},
});
return () => {
ScrollTrigger.getAll().forEach((st) => st.kill());
};
}, []);
return (
<section
ref={containerRef}
className="tab:px-6 mx-auto flex h-full w-full max-w-[1420px] flex-col items-center justify-start gap-12 py-8 sm:px-2.5 lg:px-0"
>
<div className="tab:w-9/12 flex flex-col items-center justify-center gap-4 sm:w-full md:w-6/12">
<Headline text="Feedback" />
<h1
ref={headingRef}
className="font-switzer text-h-mobile-30 leading-h5 tab:text-h-2-60 tab:leading-h2 text-center font-semibold text-black"
>
Powered by{" "}
<span className="font-playfair text-brand font-semibold italic">
Trust.
</span>
<br />
Proven by{" "}
<span className="font-playfair text-brand font-semibold italic">
Nature.
</span>
</h1>
<p
ref={paraRef}
className="text-b-3-16 leading-b3 font-mium-reg text-center tracking-[-0.8px] text-black"
>
See how municipalities and partners use FalktronTrees to make smarter,
data-driven decisions for urban green spaces.
</p>
</div>
<div className="test-wrapper relative w-full overflow-hidden">
<Marquee gap="1rem" className="test-card max-w-full [--duration:120s]">
{firstHalf.map((test, idx) => (
<TestimonialCard
key={idx}
img={test.avatar}
id={idx + 1}
name={test.name}
title={test.role}
body={test.message}
/>
))}
</Marquee>
<Marquee
gap="1rem"
className="test-card max-w-full [--duration:120s]"
reverse
pauseOnHover
>
{secondHalf.map((test, idx) => (
<TestimonialCard
key={idx}
img={test.avatar}
id={idx + 1}
name={test.name}
title={test.role}
body={test.message}
/>
))}
</Marquee>
{/* left gradient fade */}
<div className="pointer-events-none absolute inset-y-0 left-0 h-full w-1/4 bg-gradient-to-r from-white to-transparent"></div>
{/* right gradient fade */}
<div className="pointer-events-none absolute inset-y-0 right-0 h-full w-1/4 bg-gradient-to-l from-white to-transparent"></div>
</div>
</section>
);
};
export default Testimonial;