'use client' import React, { useState, useEffect, ReactElement } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Inter } from 'next/font/google'; import Image from 'next/image'; import { IconType } from 'react-icons'; const inter = Inter({ subsets: ['latin'] }); type BrandType = { name: string; logo: string | IconType; }; interface BrandSectionProps { brands: BrandType[]; scrollSpeed?: number; scrollInterval?: number; } const BrandCard: React.FC<{ brand: BrandType; onHover: (isHovered: boolean) => void; className?: string }> = React.memo( ({ brand, onHover, className }) => ( onHover(true)} onMouseLeave={() => onHover(false)} >
{typeof brand.logo === 'string' ? ( {brand.name} ) : typeof brand.logo === 'function' ? ( React.createElement(brand.logo, { className: 'text-3xl text-white' }) ) : ( React.cloneElement(brand.logo, { className: 'text-3xl text-white' }) )}

{brand.name}

) ); BrandCard.displayName = 'BrandCard'; const useMediaQuery = (query: string) => { const [matches, setMatches] = useState(false); useEffect(() => { if (typeof window !== 'undefined') { const media = window.matchMedia(query); setMatches(media.matches); const listener = () => setMatches(media.matches); media.addEventListener('change', listener); return () => media.removeEventListener('change', listener); } }, [query]); return matches; }; const BrandSection: React.FC = ({ brands, scrollSpeed = 0.1, scrollInterval = 30, }) => { const isMobile = useMediaQuery('(max-width: 768px)'); const [scrollPosition, setScrollPosition] = useState(0); const [isPaused, setIsPaused] = useState(false); const effectiveScrollSpeed = isMobile ? scrollSpeed * 2 : scrollSpeed; const effectiveScrollInterval = isMobile ? scrollInterval / 2 : scrollInterval; useEffect(() => { let interval: NodeJS.Timeout; if (!isPaused) { interval = setInterval(() => { setScrollPosition((prevPosition) => (prevPosition + effectiveScrollSpeed) % 100); }, effectiveScrollInterval); } return () => clearInterval(interval); }, [isPaused, effectiveScrollSpeed, effectiveScrollInterval]); const handleHover = (isHovered: boolean) => { setIsPaused(isHovered); }; return (
{brands.concat(brands).map((brand, index) => ( ))}
); }; export default BrandSection;