mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
Implement scrolling testimonials component with improved layout and animation
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
import { useRef } from "react";
|
||||||
|
|
||||||
const testimonials = [
|
const testimonials = [
|
||||||
{
|
{
|
||||||
name: "$ user@dev.sh",
|
name: "$ user@dev.sh",
|
||||||
@@ -26,12 +28,20 @@ const testimonials = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const Testimonials = () => {
|
const Testimonials = () => {
|
||||||
|
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const duplicatedTestimonials = [
|
||||||
|
...testimonials,
|
||||||
|
...testimonials,
|
||||||
|
...testimonials,
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="py-20 relative dark:bg-black">
|
<section className="py-20 relative overflow-hidden w-screen">
|
||||||
<div className="absolute inset-0 opacity-90 z-0" />
|
<div className="absolute inset-0 opacity-90 z-0" />
|
||||||
|
|
||||||
<div className="max-w-6xl mx-auto relative z-10">
|
<div className="w-full mx-auto relative z-10">
|
||||||
<div className="text-center mb-16">
|
<div className="text-center mb-16 max-w-6xl mx-auto">
|
||||||
<h2 className="text-4xl font-bold text-gray-900 dark:text-white">
|
<h2 className="text-4xl font-bold text-gray-900 dark:text-white">
|
||||||
<span className="text-gray-600 dark:text-gray-400">$</span> cat
|
<span className="text-gray-600 dark:text-gray-400">$</span> cat
|
||||||
testimonials.log
|
testimonials.log
|
||||||
@@ -42,41 +52,53 @@ const Testimonials = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid md:grid-cols-3 gap-6">
|
<div className="w-full overflow-hidden relative">
|
||||||
{testimonials.map((testimonial) => (
|
<div className="absolute left-0 top-0 bottom-0 w-[100px] z-10 bg-gradient-to-r from-white to-transparent dark:from-black pointer-events-none" />
|
||||||
<div
|
<div
|
||||||
key={testimonial.name}
|
ref={scrollContainerRef}
|
||||||
className="group rounded-md border border-gray-200 dark:border-gray-800 bg-gray-50/50 dark:bg-black/30 p-6 hover:border-blue-500/30 transition-colors duration-200"
|
className="flex animate-scroll px-[5%]"
|
||||||
>
|
style={{
|
||||||
<div className="flex items-center space-x-4 mb-4">
|
animation: "scroll 30s linear infinite",
|
||||||
<div className="shrink-0">
|
willChange: "transform",
|
||||||
<div className="w-10 h-10 rounded-sm bg-gradient-to-r from-gray-100 to-gray-200 dark:from-gray-900 dark:to-gray-800 flex items-center justify-center text-gray-700 dark:text-gray-300 font-mono">
|
}}
|
||||||
{testimonial.avatar}
|
>
|
||||||
|
{duplicatedTestimonials.map((testimonial) => (
|
||||||
|
<div
|
||||||
|
key={testimonial.name}
|
||||||
|
className="group rounded-md border border-gray-200 dark:border-gray-800 bg-gray-50/50 dark:bg-black/10 p-6 hover:border-blue-500/30 transition-colors duration-200 w-[25%] md:w-[30%] mx-4 flex-shrink-0"
|
||||||
|
>
|
||||||
|
<div className="flex items-center space-x-4 mb-4">
|
||||||
|
<div className="shrink-0">
|
||||||
|
<div className="w-10 h-10 rounded-sm bg-gradient-to-r from-gray-100 to-gray-200 dark:from-gray-900 dark:to-gray-800 flex items-center justify-center text-gray-700 dark:text-gray-300 font-mono">
|
||||||
|
{testimonial.avatar}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="text-gray-900 dark:text-white font-mono">
|
||||||
|
{testimonial.name}
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm font-mono">
|
||||||
|
<span className="text-gray-600 dark:text-gray-400">
|
||||||
|
{testimonial.role}
|
||||||
|
</span>
|
||||||
|
<span className="text-gray-500 mx-1">@</span>
|
||||||
|
<span className="text-gray-600 dark:text-gray-400">
|
||||||
|
{testimonial.company}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<p className="text-gray-700 dark:text-gray-300 leading-relaxed font-mono border-l-2 border-blue-700 pl-4">
|
||||||
<h3 className="text-gray-900 dark:text-white font-mono">
|
{testimonial.content}
|
||||||
{testimonial.name}
|
</p>
|
||||||
</h3>
|
|
||||||
<p className="text-sm font-mono">
|
|
||||||
<span className="text-gray-600 dark:text-gray-400">
|
|
||||||
{testimonial.role}
|
|
||||||
</span>
|
|
||||||
<span className="text-gray-500 mx-1">@</span>
|
|
||||||
<span className="text-gray-600 dark:text-gray-400">
|
|
||||||
{testimonial.company}
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<p className="text-gray-700 dark:text-gray-300 leading-relaxed font-mono border-l-2 border-blue-700 pl-4">
|
))}
|
||||||
{testimonial.content}
|
</div>
|
||||||
</p>
|
|
||||||
</div>
|
<div className="absolute right-0 top-0 bottom-0 w-[100px] z-10 bg-gradient-to-l from-white to-transparent dark:from-black pointer-events-none" />
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-center mt-12">
|
<div className="text-center mt-12 max-w-6xl mx-auto">
|
||||||
<div className="inline-block py-2 px-4 bg-gray-50 dark:bg-black border border-gray-200 dark:border-gray-800 rounded-md">
|
<div className="inline-block py-2 px-4 bg-gray-50 dark:bg-black border border-gray-200 dark:border-gray-800 rounded-md">
|
||||||
<span className="text-blue-500 font-bold mr-2">$</span>
|
<span className="text-blue-500 font-bold mr-2">$</span>
|
||||||
<span className="text-gray-900 dark:text-white font-mono">
|
<span className="text-gray-900 dark:text-white font-mono">
|
||||||
@@ -85,6 +107,20 @@ const Testimonials = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style jsx>{`
|
||||||
|
@keyframes scroll {
|
||||||
|
0% {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateX(calc(-29% * ${testimonials.length}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.animate-scroll:hover {
|
||||||
|
animation-play-state: paused;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ import CodeContainer from "./_components/CodeContainer";
|
|||||||
import CustomizableSection from "./_components/CustomizableSection";
|
import CustomizableSection from "./_components/CustomizableSection";
|
||||||
import NpmPackage from "./_components/NpmPackage";
|
import NpmPackage from "./_components/NpmPackage";
|
||||||
import TechShowcase from "./_components/TechShowcase";
|
import TechShowcase from "./_components/TechShowcase";
|
||||||
// import TerminalDisplay from "./_components/Terminal";
|
import Testimonials from "./_components/Testimonials";
|
||||||
// import Testimonials from "./_components/Testimonials";
|
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
return (
|
return (
|
||||||
@@ -126,7 +125,7 @@ export default function HomePage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* <Testimonials /> */}
|
<Testimonials />
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user