96 lines
2.9 KiB
TypeScript
96 lines
2.9 KiB
TypeScript
"use client"
|
|
|
|
import { useRef } from "react"
|
|
import { ChevronLeft, ChevronRight } from "lucide-react"
|
|
import { GameCard } from "./game-card"
|
|
import { cn } from "@/lib/utils"
|
|
|
|
interface GameRowProps {
|
|
title: string
|
|
games: any[]
|
|
showSeeMore?: boolean
|
|
rows?: 1 | 2 | 3
|
|
}
|
|
|
|
export function GameRow({ title, games, showSeeMore = true, rows = 1 }: GameRowProps) {
|
|
const scrollRef = useRef<HTMLDivElement>(null)
|
|
|
|
const scroll = (direction: "left" | "right") => {
|
|
if (scrollRef.current) {
|
|
const scrollAmount = direction === "left" ? -600 : 600
|
|
scrollRef.current.scrollBy({ left: scrollAmount, behavior: "smooth" })
|
|
}
|
|
}
|
|
|
|
// Chunk games into rows if rows > 1
|
|
const renderGames = () => {
|
|
if (rows === 1) {
|
|
return games.map((game, idx) => (
|
|
<div key={idx} style={{ scrollSnapAlign: "start" }}>
|
|
<GameCard {...game} />
|
|
</div>
|
|
))
|
|
}
|
|
|
|
// For multi-row, we can use a grid with horizontal scroll on the container
|
|
// or wrap items. The requirement "3*6 horizontally scrollable" suggests
|
|
// a grid that moves as a block or multi-row horizontal layout.
|
|
return (
|
|
<div className={cn(
|
|
"grid grid-flow-col gap-4 pb-2",
|
|
rows === 2 ? "grid-rows-2" : rows === 3 ? "grid-rows-3" : ""
|
|
)}>
|
|
{games.map((game, idx) => (
|
|
<div key={idx} style={{ scrollSnapAlign: "start" }}>
|
|
<GameCard {...game} />
|
|
</div>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className="flex flex-col gap-3 py-4">
|
|
<div className="flex items-center justify-between px-4">
|
|
<h2 className="text-sm font-bold text-white/90 border-l-4 border-brand-primary pl-3 uppercase tracking-tight">
|
|
{title}
|
|
</h2>
|
|
<div className="flex items-center gap-3">
|
|
{showSeeMore && (
|
|
<button className="text-[10px] text-white/40 hover:text-white uppercase font-bold transition-colors">
|
|
See More
|
|
</button>
|
|
)}
|
|
<div className="flex items-center gap-1">
|
|
<button
|
|
onClick={() => scroll("left")}
|
|
className="size-6 flex items-center justify-center bg-white/5 hover:bg-white/10 text-white/60 hover:text-white transition-colors"
|
|
>
|
|
<ChevronLeft className="size-4" />
|
|
</button>
|
|
<button
|
|
onClick={() => scroll("right")}
|
|
className="size-6 flex items-center justify-center bg-white/5 hover:bg-white/10 text-white/60 hover:text-white transition-colors"
|
|
>
|
|
<ChevronRight className="size-4" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
ref={scrollRef}
|
|
className="flex overflow-x-auto scrollbar-none px-4 pb-2 snap-x snap-mandatory"
|
|
>
|
|
{rows === 1 ? (
|
|
<div className="flex gap-4">
|
|
{renderGames()}
|
|
</div>
|
|
) : (
|
|
renderGames()
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|