Skip to content

Commit 476c2e7

Browse files
committed
update
1 parent 18830f6 commit 476c2e7

File tree

1 file changed

+70
-4
lines changed

1 file changed

+70
-4
lines changed

src/components/Testimonial.jsx

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1-
import React, { useRef, useEffect } from 'react';
1+
import React, { useRef, useEffect, useState } from 'react';
22

33
const Testimonial = () => {
44
const scrollRef = useRef(null);
5+
const [isPaused, setIsPaused] = useState(false);
6+
const [currentIndex, setCurrentIndex] = useState(0);
57

68
useEffect(() => {
79
const scrollContainer = scrollRef.current;
810
let isDown = false;
911
let startX;
1012
let scrollLeft;
13+
let autoScrollInterval;
14+
let pauseTimeout;
1115

1216
const handleMouseDown = (e) => {
1317
isDown = true;
18+
setIsPaused(true);
1419
scrollContainer.classList.add('active');
1520
startX = e.pageX - scrollContainer.offsetLeft;
1621
scrollLeft = scrollContainer.scrollLeft;
@@ -19,11 +24,17 @@ const Testimonial = () => {
1924
const handleMouseLeave = () => {
2025
isDown = false;
2126
scrollContainer.classList.remove('active');
27+
// Resume auto-scroll after 2 seconds of no interaction
28+
clearTimeout(pauseTimeout);
29+
pauseTimeout = setTimeout(() => setIsPaused(false), 2000);
2230
};
2331

2432
const handleMouseUp = () => {
2533
isDown = false;
2634
scrollContainer.classList.remove('active');
35+
// Resume auto-scroll after 2 seconds of no interaction
36+
clearTimeout(pauseTimeout);
37+
pauseTimeout = setTimeout(() => setIsPaused(false), 2000);
2738
};
2839

2940
const handleMouseMove = (e) => {
@@ -34,11 +45,43 @@ const Testimonial = () => {
3445
scrollContainer.scrollLeft = scrollLeft - walk;
3546
};
3647

48+
const handleScroll = () => {
49+
if (!scrollContainer) return;
50+
setIsPaused(true);
51+
clearTimeout(pauseTimeout);
52+
pauseTimeout = setTimeout(() => setIsPaused(false), 2000);
53+
};
54+
55+
const autoScroll = () => {
56+
if (!scrollContainer || isPaused) return;
57+
58+
const cardWidth = 400; // Width of each testimonial card
59+
const gap = 32; // Gap between cards (8 * 4 = 32px from gap-8)
60+
const totalWidth = scrollContainer.scrollWidth;
61+
62+
setCurrentIndex((prevIndex) => {
63+
const nextIndex = (prevIndex + 1) % 4; // 4 is the number of testimonials
64+
const scrollPosition = (cardWidth + gap) * nextIndex;
65+
66+
scrollContainer.scrollTo({
67+
left: scrollPosition,
68+
behavior: 'smooth'
69+
});
70+
71+
return nextIndex;
72+
});
73+
};
74+
75+
// Set up event listeners
3776
if (scrollContainer) {
3877
scrollContainer.addEventListener('mousedown', handleMouseDown);
3978
scrollContainer.addEventListener('mouseleave', handleMouseLeave);
4079
scrollContainer.addEventListener('mouseup', handleMouseUp);
4180
scrollContainer.addEventListener('mousemove', handleMouseMove);
81+
scrollContainer.addEventListener('scroll', handleScroll);
82+
83+
// Start auto-scrolling
84+
autoScrollInterval = setInterval(autoScroll, 5000); // Scroll every 5 seconds
4285
}
4386

4487
return () => {
@@ -47,9 +90,12 @@ const Testimonial = () => {
4790
scrollContainer.removeEventListener('mouseleave', handleMouseLeave);
4891
scrollContainer.removeEventListener('mouseup', handleMouseUp);
4992
scrollContainer.removeEventListener('mousemove', handleMouseMove);
93+
scrollContainer.removeEventListener('scroll', handleScroll);
5094
}
95+
clearInterval(autoScrollInterval);
96+
clearTimeout(pauseTimeout);
5197
};
52-
}, []);
98+
}, [isPaused]);
5399

54100
return (
55101
<section className="py-16 bg-gradient-to-r from-gray-50 to-gray-100 overflow-hidden">
@@ -167,11 +213,31 @@ const Testimonial = () => {
167213
</div>
168214
</div>
169215

170-
{/* Scroll Indicator */}
171-
<div className="mt-8 flex justify-center">
216+
{/* Scroll Indicator and Navigation Dots */}
217+
<div className="mt-8 flex flex-col items-center gap-4">
172218
<div className="text-sm text-gray-500">
173219
← Scroll or drag to see more testimonials →
174220
</div>
221+
<div className="flex gap-2">
222+
{[0, 1, 2, 3].map((index) => (
223+
<button
224+
key={index}
225+
className={`w-2 h-2 rounded-full transition-all duration-300 ${
226+
currentIndex === index ? 'bg-gray-800 w-4' : 'bg-gray-300'
227+
}`}
228+
onClick={() => {
229+
setIsPaused(true);
230+
setCurrentIndex(index);
231+
scrollRef.current?.scrollTo({
232+
left: index * (400 + 32),
233+
behavior: 'smooth'
234+
});
235+
setTimeout(() => setIsPaused(false), 2000);
236+
}}
237+
aria-label={`Go to testimonial ${index + 1}`}
238+
/>
239+
))}
240+
</div>
175241
</div>
176242
</div>
177243

0 commit comments

Comments
 (0)