dptxa-proxy / src /components /TopTenSection.jsx
TXAVLOG
Deploy DPTXA to Hugging Face Spaces
4bea261
Raw
History Blame Contribute Delete
4.63 kB
import { useRef, useState, useEffect } from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import TopTenCard from './TopTenCard';
export default function TopTenSection({ series = [], rated = [], favorited = [] }) {
const [activeTab, setActiveTab] = useState('series');
const scrollRef = useRef(null);
const [showLeft, setShowLeft] = useState(false);
const [showRight, setShowRight] = useState(true);
const getMoviesForTab = () => {
switch (activeTab) {
case 'rated': return rated;
case 'favorited': return favorited;
case 'series':
default: return series;
}
};
const movies = getMoviesForTab();
const handleScroll = () => {
if (!scrollRef.current) return;
const { scrollLeft, scrollWidth, clientWidth } = scrollRef.current;
setShowLeft(scrollLeft > 10);
setShowRight(scrollLeft < scrollWidth - clientWidth - 10);
};
const scroll = (dir) => {
if (!scrollRef.current) return;
const amount = scrollRef.current.clientWidth * 0.8;
scrollRef.current.scrollBy({ left: dir * amount, behavior: 'smooth' });
};
// Reset scroll position on tab change
useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollLeft = 0;
handleScroll();
}
}, [activeTab]);
if (!movies?.length) return null;
return (
<section className="mx-auto max-w-7xl px-4 py-10 md:px-8 overflow-hidden">
{/* Header Tabs */}
<div className="mb-10 flex flex-col md:flex-row md:items-center justify-between gap-6 border-b border-white/5 pb-5">
<div className="flex items-center gap-3">
<span className="h-8 w-2 rounded-full bg-primary shadow-[0_0_20px_rgba(229,9,20,0.6)]" />
<h2 className="text-2xl font-black uppercase tracking-tight text-white">
Bảng Xếp Hạng
</h2>
</div>
{/* Premium Tab Buttons */}
<div className="flex flex-wrap gap-2 bg-white/5 p-1 rounded-2xl border border-white/5 backdrop-blur-md self-start md:self-auto">
{[
{ id: 'series', name: 'Top Phim Bộ', icon: 'fa-fire' },
{ id: 'rated', name: 'Đánh Giá Cao', icon: 'fa-star' },
{ id: 'favorited', name: 'Yêu Thích Nhất', icon: 'fa-heart' }
].map(tab => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`flex items-center gap-2 px-5 py-2.5 rounded-xl text-[10px] font-black uppercase tracking-widest transition-all duration-300 cursor-pointer ${
activeTab === tab.id
? 'bg-primary text-white shadow-[0_0_20px_rgba(229,9,20,0.3)] scale-[1.02]'
: 'text-gray-400 hover:text-white hover:bg-white/5'
}`}
>
<i className={`fas ${tab.icon} text-[9px] ${activeTab === tab.id ? 'text-white' : 'text-gray-500'}`}></i>
{tab.name}
</button>
))}
</div>
</div>
{/* Row có scroll ngang */}
<div className="relative group/section">
{/* Nút trái */}
{showLeft && (
<button
onClick={() => scroll(-1)}
className="absolute left-1 top-[42%] z-40 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full bg-black/80 text-white backdrop-blur-sm opacity-0 transition-all duration-300 group-hover/section:opacity-100 hover:bg-primary border border-white/10 shadow-lg cursor-pointer"
>
<ChevronLeft size={20} />
</button>
)}
{/* Nút phải */}
{showRight && (
<button
onClick={() => scroll(1)}
className="absolute right-1 top-[42%] z-40 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full bg-black/80 text-white backdrop-blur-sm opacity-0 transition-all duration-300 group-hover/section:opacity-100 hover:bg-primary border border-white/10 shadow-lg cursor-pointer"
>
<ChevronRight size={20} />
</button>
)}
{/* Track */}
<div
ref={scrollRef}
onScroll={handleScroll}
className="scrollbar-hide flex overflow-x-auto pb-16 pt-2 px-4 md:px-8 gap-6 md:gap-8"
>
{movies.slice(0, 10).map((movie, idx) => (
<div
key={`${movie._id || movie.slug}-${activeTab}-${idx}`}
className="w-[180px] md:w-[240px] flex-shrink-0"
>
<TopTenCard movie={movie} index={idx} />
</div>
))}
</div>
</div>
</section>
);
}