Skip to content

Commit 51863e4

Browse files
committed
<refactor> fix caraousel buttons
1 parent fc44aae commit 51863e4

File tree

2 files changed

+191
-144
lines changed

2 files changed

+191
-144
lines changed

src/components/Sponsor.jsx

Lines changed: 76 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,68 +4,84 @@ import sponsors from "../config/sponsors";
44
import "./sponsor.css";
55

66
const SponsorsSection = () => {
7-
const scrollRef = useRef(null);
8-
const [isHovered, setIsHovered] = useState(false);
9-
const pageIndex = useRef(0);
10-
const [visibleCount, setVisibleCount] = useState(1);
7+
const containerRef = useRef(null);
8+
const [isPaused, setIsPaused] = useState(false);
9+
const currentIndex = useRef(0);
10+
const [itemsToShow, setItemsToShow] = useState(1);
1111

1212
useEffect(() => {
13-
const handleResize = () => {
14-
const width = window.innerWidth;
15-
if (width < 640) setVisibleCount(1);
16-
else if (width < 1024) setVisibleCount(2);
17-
else setVisibleCount(3);
13+
const updateItemsToShow = () => {
14+
if (window.innerWidth >= 1024) {
15+
setItemsToShow(3);
16+
} else if (window.innerWidth >= 640) {
17+
setItemsToShow(2);
18+
} else {
19+
setItemsToShow(1);
20+
}
1821
};
1922

20-
handleResize();
21-
window.addEventListener("resize", handleResize);
22-
return () => window.removeEventListener("resize", handleResize);
23+
updateItemsToShow();
24+
window.addEventListener("resize", updateItemsToShow);
25+
return () => window.removeEventListener("resize", updateItemsToShow);
2326
}, []);
2427

25-
const scrollToPage = (index) => {
26-
const container = scrollRef.current;
27-
if (!container) return;
28+
const scrollToIndex = (index) => {
29+
if (!containerRef.current) return;
2830

29-
const cardWidth = container.scrollWidth / sponsors.length;
30-
const scrollX = cardWidth * visibleCount * index;
31-
container.scrollTo({ left: scrollX, behavior: "smooth" });
31+
const itemWidth = containerRef.current.scrollWidth / sponsors.length;
32+
const scrollPosition = itemWidth * itemsToShow * index;
33+
34+
containerRef.current.scrollTo({
35+
left: scrollPosition,
36+
behavior: "smooth",
37+
});
38+
};
39+
40+
const getTotalPages = () => {
41+
return Math.ceil(sponsors.length / itemsToShow);
3242
};
3343

34-
const totalPages = () => {
35-
return Math.ceil(sponsors.length / visibleCount);
44+
const goToNext = () => {
45+
const totalPages = getTotalPages();
46+
currentIndex.current = (currentIndex.current + 1) % totalPages;
47+
scrollToIndex(currentIndex.current);
3648
};
3749

38-
const handleManualScroll = (direction) => {
39-
const pages = totalPages();
40-
if (direction === "left") {
41-
pageIndex.current =
42-
pageIndex.current === 0 ? pages - 1 : pageIndex.current - 1;
43-
} else {
44-
pageIndex.current = (pageIndex.current + 1) % pages;
45-
}
46-
scrollToPage(pageIndex.current);
50+
const goToPrevious = () => {
51+
const totalPages = getTotalPages();
52+
currentIndex.current =
53+
currentIndex.current === 0 ? totalPages - 1 : currentIndex.current - 1;
54+
scrollToIndex(currentIndex.current);
4755
};
4856

4957
useEffect(() => {
50-
const autoScroll = () => {
51-
const container = scrollRef.current;
52-
if (!container) return;
58+
if (isPaused) return;
5359

54-
const pages = totalPages();
55-
pageIndex.current = (pageIndex.current + 1) % pages;
56-
scrollToPage(pageIndex.current);
57-
};
60+
const autoPlay = setInterval(() => {
61+
goToNext();
62+
}, 5000);
63+
64+
return () => clearInterval(autoPlay);
65+
}, [isPaused, itemsToShow]);
5866

59-
let interval;
60-
if (!isHovered) {
61-
interval = setInterval(autoScroll, 5000);
62-
}
63-
return () => clearInterval(interval);
64-
}, [isHovered, visibleCount]);
67+
const handleMouseEnter = () => setIsPaused(true);
68+
const handleMouseLeave = () => setIsPaused(false);
69+
70+
const handlePrevClick = () => {
71+
goToPrevious();
72+
setIsPaused(true);
73+
setTimeout(() => setIsPaused(false), 200);
74+
};
75+
76+
const handleNextClick = () => {
77+
goToNext();
78+
setIsPaused(true);
79+
setTimeout(() => setIsPaused(false), 200);
80+
};
6581

6682
return (
67-
<section className="bg-white py-10 relative overflow-hidden">
68-
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:pl-0">
83+
<section className="bg-white py-10">
84+
<div className="max-w-6xl mx-auto px-4 sm:px-6">
6985
<div className="mb-8">
7086
<h2 className="text-3xl sm:text-4xl font-bold text-slate-900 mb-2">
7187
Our Sponsors and Partners
@@ -76,48 +92,47 @@ const SponsorsSection = () => {
7692
</div>
7793

7894
<div
79-
className="relative"
80-
onMouseEnter={() => setIsHovered(true)}
81-
onMouseLeave={() => setIsHovered(false)}
95+
className="relative px-12"
96+
onMouseEnter={handleMouseEnter}
97+
onMouseLeave={handleMouseLeave}
8298
>
83-
{/* Left Arrow */}
8499
<button
85-
onClick={() => handleManualScroll("left")}
86-
className="absolute left-0 sm:left-0 top-1/2 -translate-y-1/2 sm:-translate-x-3 bg-[#00163A] rounded-full p-2 sm:p-2.5 shadow z-10 cursor-pointer hover:bg-[#2563eb]"
100+
onClick={handlePrevClick}
101+
className="absolute left-0 top-1/2 -translate-y-1/2 z-10 bg-[#00163A] hover:bg-[#2563eb] rounded-full p-2 shadow cursor-pointer"
87102
>
88-
<ArrowLeft className="w-5 h-5 sm:w-6 sm:h-6 text-white" />
103+
<ArrowLeft className="w-6 h-6 text-white" />
89104
</button>
90105

91-
{/* Sponsor Scroll Area */}
92106
<div
93-
ref={scrollRef}
94-
className="flex overflow-x-auto scroll-smooth hide-scrollbar"
107+
ref={containerRef}
108+
className="flex overflow-x-auto scroll-smooth"
109+
style={{ scrollbarWidth: "none", msOverflowStyle: "none" }}
95110
>
96111
{sponsors.map((sponsor, index) => (
97112
<a
98113
key={index}
99114
href={sponsor.link}
100115
target="_blank"
101116
rel="noopener noreferrer"
102-
className="flex-shrink-0 px-2 box-border"
103-
style={{ width: `${100 / visibleCount}%` }}
117+
className="flex-shrink-0 px-2"
118+
style={{ width: `${100 / itemsToShow}%` }}
104119
>
105-
<div className="h-64 bg-white flex items-center justify-center rounded-xl transition duration-300 transform hover:shadow-xl cursor-pointer border-2">
120+
<div className="h-64 bg-white flex items-center justify-center rounded-xl hover:shadow-xl transition duration-300 border-2 cursor-pointer">
106121
<img
107122
src={sponsor.image}
108123
alt={sponsor.name}
109-
className="object-contain h-32 "
124+
className="object-contain h-32"
110125
/>
111126
</div>
112127
</a>
113128
))}
114129
</div>
115130

116131
<button
117-
onClick={() => handleManualScroll("right")}
118-
className="absolute right-0 sm:right-0 top-1/2 -translate-y-1/2 sm:translate-x-3 bg-[#00163A] cursor-pointer rounded-full p-2 sm:p-2.5 shadow z-10 hover:bg-[#2563eb]"
132+
onClick={handleNextClick}
133+
className="absolute right-0 top-1/2 -translate-y-1/2 z-10 bg-[#00163A] hover:bg-[#2563eb] rounded-full p-2 shadow cursor-pointer"
119134
>
120-
<ArrowRight className="w-5 h-5 sm:w-6 sm:h-6 text-white" />
135+
<ArrowRight className="w-6 h-6 text-white" />
121136
</button>
122137
</div>
123138
</div>

0 commit comments

Comments
 (0)