Fortune-PlayLogic/components/betting/match-detail-view.tsx

270 lines
9.5 KiB
TypeScript

"use client"
import { useState } from "react"
import Link from "next/link"
import { useBetslipStore } from "@/lib/store/betslip-store"
import {
getEventDetailMarkets,
getCardsBookingsMarkets,
type Event,
type DetailMarketSection,
} from "@/lib/mock-data"
import { cn } from "@/lib/utils"
import { ChevronDown, ChevronUp } from "lucide-react"
const MARKET_CATEGORIES = [
"Betbuilder",
"All",
"Main",
"Goals",
"Handicap",
"1st Half",
"2nd Half",
"Combo",
"Chance Mix",
"Home",
"Half Time / Full Time",
"Away",
"Correct Score",
"Asian Markets",
"Corners",
"Minutes",
"Cards/Bookings",
"Points Handicap",
"Total Points",
"Team 1",
"Team 2",
"Other",
"Handicap Goals",
"Total Goals",
"Combo",
"Specials",
]
function MarketSectionBlock({
section,
event,
marketName,
isExpanded,
onToggle,
}: {
section: DetailMarketSection
event: Event
marketName: string
isExpanded: boolean
onToggle: () => void
}) {
const { bets, addBet } = useBetslipStore()
const hasOutcomes = section.outcomes.length > 0
return (
<div className="bg-brand-surface-light border-b border-white/5">
<button
type="button"
onClick={onToggle}
className="w-full flex items-center justify-between px-3 py-2.5 text-left hover:bg-white/5 transition-colors"
>
<span className="text-[11px] font-bold text-white uppercase">
{section.title}
</span>
{isExpanded ? (
<ChevronUp className="size-4 text-white/60" />
) : (
<ChevronDown className="size-4 text-white/60" />
)}
</button>
{isExpanded && hasOutcomes && (
<div className="px-3 pb-3 space-y-1.5">
{section.outcomes.length > 2 && section.outcomes.length % 2 === 0 ? (
<div className="grid grid-cols-2 gap-x-4 gap-y-1.5">
{section.outcomes.map((outcome) => {
const betId = `${event.id}-${section.id}-${outcome.label.replace(/\s/g, "-").toLowerCase()}`
const isSelected = bets.some((b) => b.id === betId)
return (
<div key={outcome.label} className="flex items-center justify-between gap-2">
<span className="text-[11px] text-white/90 truncate">{outcome.label}</span>
<button
type="button"
onClick={() =>
addBet({
id: betId,
event: `${event.homeTeam} - ${event.awayTeam}`,
league: `${event.sport} - ${event.country} - ${event.league}`,
market: marketName,
selection: outcome.label,
odds: outcome.odds,
})
}
className={cn(
"min-w-[52px] px-2 py-1 rounded text-[11px] font-bold tabular-nums text-center transition-all shrink-0",
isSelected ? "bg-brand-primary text-black" : "text-brand-primary hover:bg-white/5"
)}
>
{outcome.odds.toFixed(2)}
</button>
</div>
)
})}
</div>
) : (
section.outcomes.map((outcome) => {
const betId = `${event.id}-${section.id}-${outcome.label.replace(/\s/g, "-").toLowerCase()}`
const isSelected = bets.some((b) => b.id === betId)
return (
<div
key={outcome.label}
className="flex items-center justify-between gap-3 py-1"
>
<span className="text-[11px] text-white/90">{outcome.label}</span>
<button
type="button"
onClick={() =>
addBet({
id: betId,
event: `${event.homeTeam} - ${event.awayTeam}`,
league: `${event.sport} - ${event.country} - ${event.league}`,
market: marketName,
selection: outcome.label,
odds: outcome.odds,
})
}
className={cn(
"min-w-[52px] px-2 py-1 rounded text-[11px] font-bold tabular-nums text-center transition-all shrink-0",
isSelected ? "bg-brand-primary text-black" : "text-brand-primary hover:bg-white/5"
)}
>
{outcome.odds.toFixed(2)}
</button>
</div>
)
})
)}
</div>
)}
</div>
)
}
export function MatchDetailView({ event }: { event: Event }) {
const [expandedSections, setExpandedSections] = useState<Record<string, boolean>>({
"bookings-1x2": true,
"sending-off": true,
"1st-booking": true,
"1st-half-bookings-1x2": true,
"booking-points-ou": true,
"1st-half-1st-booking": true,
})
const [activeCategory, setActiveCategory] = useState("Cards/Bookings")
const detailMarkets = getEventDetailMarkets(event.id)
const cardsBookings = getCardsBookingsMarkets(event.id)
const toggleSection = (id: string) => {
setExpandedSections((prev) => ({ ...prev, [id]: !prev[id] }))
}
const breadcrumbLeague =
event.league === "Premier League"
? "England - Premier League"
: `${event.country} - ${event.league}`
const isCardsBookings = activeCategory === "Cards/Bookings"
const leftSections = isCardsBookings ? cardsBookings.left : detailMarkets
const rightSections = isCardsBookings ? cardsBookings.right : []
return (
<div className="flex flex-col bg-brand-bg rounded overflow-hidden">
{/* Breadcrumb: back arrow, ellipsis, path */}
<div className="bg-brand-surface px-3 py-2 border-b border-border/20">
<Link
href="/"
className="flex items-center gap-2 text-[11px] font-bold text-white/70 hover:text-brand-primary transition-colors"
>
<span className="text-white/80">&lt;</span>
<span>...</span>
<span>Football {breadcrumbLeague} / {event.homeTeam} vs. {event.awayTeam}</span>
</Link>
<h1 className="text-[15px] font-bold text-white mt-2">
{breadcrumbLeague}
</h1>
</div>
{/* Match header */}
<div className="bg-brand-surface px-4 py-5 border-b border-border/20">
<div className="flex items-center justify-center gap-10">
<div className="flex flex-col items-center gap-2">
<div className="w-16 h-20 rounded-md bg-brand-bg border border-white/10 flex items-center justify-center">
<span className="text-[10px] font-black text-white/60 uppercase">
{event.homeTeam.slice(0, 2)}
</span>
</div>
<span className="text-[13px] font-bold text-white">{event.homeTeam}</span>
</div>
<span className="text-[12px] font-black text-white/50 uppercase">VS</span>
<div className="flex flex-col items-center gap-2">
<div className="w-16 h-20 rounded-md bg-brand-bg border border-white/10 flex items-center justify-center">
<span className="text-[10px] font-black text-white/60 uppercase">
{event.awayTeam.slice(0, 2)}
</span>
</div>
<span className="text-[13px] font-bold text-white">{event.awayTeam}</span>
</div>
</div>
</div>
{/* Category tabs: horizontal scroll, selected = darker grey */}
<div className="flex overflow-x-auto gap-1 p-2 bg-brand-bg border-b border-border/20 scrollbar-hide">
{MARKET_CATEGORIES.map((label) => (
<button
key={label}
type="button"
onClick={() => setActiveCategory(label)}
className={cn(
"px-3 py-1.5 text-[10px] font-bold uppercase whitespace-nowrap rounded transition-colors shrink-0",
activeCategory === label
? "bg-brand-surface-light text-white border border-white/10"
: "text-white/60 hover:text-white hover:bg-white/5"
)}
>
{label}
</button>
))}
</div>
{/* Two-column grid of market sections */}
<div className="flex-1 min-h-0 overflow-y-auto">
<div className="grid grid-cols-1 md:grid-cols-2 gap-0 bg-brand-surface-light">
{/* Left column */}
<div className="border-r border-white/5">
{leftSections.map((section) => (
<MarketSectionBlock
key={section.id}
section={section}
event={event}
marketName={section.title}
isExpanded={expandedSections[section.id] ?? false}
onToggle={() => toggleSection(section.id)}
/>
))}
</div>
{/* Right column (Cards/Bookings only) */}
{rightSections.length > 0 && (
<div>
{rightSections.map((section) => (
<MarketSectionBlock
key={section.id}
section={section}
event={event}
marketName={section.title}
isExpanded={expandedSections[section.id] ?? false}
onToggle={() => toggleSection(section.id)}
/>
))}
</div>
)}
</div>
</div>
</div>
)
}