Fortune-PlayLogic/components/layout/site-header.tsx

293 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import Link from "next/link"
import { usePathname } from "next/navigation"
import { useState, useEffect } from "react"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
const allNavItems = [
{ href: "/", label: "SPORTS" },
{ href: "/today", label: "TODAY" },
{ href: "/live", label: "LIVE" },
{ href: "/virtual", label: "VIRTUAL" },
{ href: "/special-games", label: "SPECIAL G." },
{ href: "/multi-hot-5", label: "MULTI HOT 5" },
{ href: "/poker", label: "POKER", isNew: true },
{ href: "/race", label: "RACE", isNew: true },
{ href: "/promo", label: "PROMO" },
{ href: "/aviator", label: "AVIATOR" },
]
const drawerLinks = [
{ href: "/", label: "All Sports" },
{ href: "/live", label: "Live Betting" },
{ href: "/virtual", label: "Virtual" },
{ href: "/special-games", label: "Special Games" },
{ href: "/poker", label: "Poker" },
{ href: "/race", label: "Race" },
{ href: "/promo", label: "Promotions" },
{ href: "/deposit", label: "Deposit" },
{ href: "/bonus", label: "Bonus" },
{ href: "/rules", label: "Betting Rules" },
{ href: "/terms", label: "Terms & Conditions" },
]
interface SiteHeaderProps {
onLoginClick?: () => void
onRegisterClick?: () => void
}
export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
const pathname = usePathname()
const isLivePage = pathname === "/live"
const [time, setTime] = useState("")
const [prevPathname, setPrevPathname] = useState(pathname)
const [drawerOpen, setDrawerOpen] = useState(false)
// Adjust state during render when pathname changes
if (pathname !== prevPathname) {
setPrevPathname(pathname)
setDrawerOpen(false)
}
useEffect(() => {
const updateClock = () => {
setTime(new Date().toLocaleTimeString("en-GB", { hour12: false }))
}
const interval = setInterval(updateClock, 1000)
updateClock()
return () => clearInterval(interval)
}, [])
return (
<>
<header className="bg-brand-bg sticky top-0 z-50">
{/* ===== DESKTOP: Top bar (hidden on mobile) ===== */}
<div className="hidden md:flex bg-brand-surface px-3 py-1 items-center justify-between text-[11px] text-white">
<div className="flex items-center gap-4">
<button className="flex items-center gap-1.5 hover:text-primary transition-colors">
<img src="https://flagcdn.com/w20/gb.png" width="16" alt="English" className="rounded-sm" />
<span className="font-bold flex items-center gap-1">en <span className="text-[8px]"></span></span>
</button>
<div className="flex items-center gap-2 font-bold">
<span className="text-[14px]">🕒</span>
<span className="tabular-nums">{time || "00:00:00"}</span>
</div>
</div>
<div className="flex items-center gap-6">
<div className="flex items-center gap-3">
<span className="text-white font-bold tracking-tight">+251 (0) Number</span>
<Input type="password" placeholder="Password" className="bg-brand-surface-light border-none px-2 py-0.5 w-32 text-[11px] h-7 rounded-none shadow-none text-white placeholder:text-gray-500" />
</div>
<div className="flex items-center gap-1">
<Button onClick={onLoginClick} className="bg-[#e67e22] text-white hover:bg-[#d35400] px-5 h-7 text-[11px] font-bold rounded-none uppercase">
Login
</Button>
<Button onClick={onRegisterClick} className="bg-[#d35400] text-white hover:bg-[#c0392b] px-5 h-7 text-[11px] font-bold rounded-none uppercase">
Sign Up
</Button>
</div>
</div>
</div>
{/* ===== MOBILE: Top bar (hidden on desktop) ===== */}
<div className="flex md:hidden items-center h-12 bg-brand-bg border-b border-white/5 px-2 gap-2">
{/* Hamburger */}
<button
onClick={() => setDrawerOpen(true)}
className="flex flex-col justify-center gap-[5px] p-2 shrink-0"
aria-label="Menu"
>
<span className="w-5 h-0.5 bg-white block" />
<span className="w-5 h-[2px] bg-white block" />
<span className="w-5 h-[2px] bg-white block" />
</button>
{/* Logo (centered, grows to fill) */}
<Link href="/" className="flex-1 flex items-center justify-center">
<div className="flex items-center">
<div className="bg-brand-accent px-2 py-0.5 -skew-x-12 flex items-center h-[28px]">
<span className="text-xl font-black text-white italic tracking-tighter skew-x-12 leading-none">HARIF</span>
</div>
<span className="text-xl font-black text-brand-primary italic tracking-tighter ml-1 leading-none">SPORT</span>
</div>
</Link>
{/* LOGIN / SIGN UP */}
<div className="flex items-center gap-1 shrink-0">
<button
onClick={onLoginClick}
className="bg-[#e67e22] text-white px-3 h-8 text-[11px] font-bold uppercase"
>
LOGIN
</button>
<button
onClick={onRegisterClick}
className="bg-[#d35400] text-white px-3 h-8 text-[11px] font-bold uppercase"
>
SIGN UP
</button>
</div>
</div>
{/* ===== DESKTOP: Main header bar ===== */}
<div className="hidden md:flex items-center px-0 bg-[#333] h-[60px]">
<Link href="/" className="flex items-center shrink-0">
<div className="flex items-center bg-brand-surface h-[60px] px-4">
<div className="bg-brand-accent px-3 py-1 -skew-x-12 flex items-center h-[34px]">
<span className="text-2xl font-black text-white italic tracking-tighter skew-x-12 inline-block leading-none">HARIF</span>
</div>
<span className="text-2xl font-black text-brand-primary italic tracking-tighter ml-1 leading-none">SPORT</span>
</div>
</Link>
<div className="flex items-center flex-1 justify-end px-4 h-full gap-0">
<Link href="/" className="flex items-center justify-center bg-brand-primary h-[60px] w-[50px] shrink-0 hover:bg-brand-primary-hover transition-colors">
<svg viewBox="0 0 24 24" className="size-6 fill-black"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
</Link>
<nav className="flex items-center text-[10.5px] font-bold h-full">
{allNavItems.slice(0, 5).map((item) => {
const isActive = pathname === item.href
return (
<Link key={item.href} href={item.href}
className={cn(
"px-4 flex items-center h-full transition-colors uppercase",
isActive ? (item.label === "LIVE" ? "bg-brand-primary text-black" : "text-primary bg-black/10") : "text-white hover:text-primary"
)}
>
{item.label}
</Link>
)
})}
</nav>
<nav className="flex items-center text-[10.5px] font-bold h-full">
{allNavItems.slice(5).map((item) => {
const isActive = pathname === item.href
return (
<Link key={item.href} href={item.href}
className={cn(
"px-4 flex flex-col items-center justify-center h-full transition-colors relative uppercase",
isActive ? "text-primary bg-black/10" : "text-white hover:text-primary"
)}
>
{item.isNew && (
<span className="absolute top-3 text-[7px] text-primary font-black tracking-tighter leading-none">NEW</span>
)}
<span className={cn(item.isNew && "mt-1.5")}>{item.label}</span>
</Link>
)
})}
</nav>
</div>
</div>
{/* ===== MOBILE: Horizontally scrollable nav tabs ===== */}
<div className="flex md:hidden overflow-x-auto scrollbar-none bg-brand-surface-light border-t border-white/5">
<Link href="/" className="flex-none px-4 h-9 flex items-center bg-brand-primary">
<svg viewBox="0 0 24 24" className="size-5 fill-black"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
</Link>
{allNavItems.map((item) => {
const isActive = pathname === item.href
return (
<Link
key={item.href}
href={item.href}
className={cn(
"relative flex-none px-4 h-9 flex items-center text-[11px] font-bold uppercase whitespace-nowrap transition-colors",
isActive
? "text-brand-primary border-b-2 border-brand-primary"
: "text-white/70 hover:text-white"
)}
>
{item.isNew && (
<span className="absolute top-1 right-1 text-[7px] text-primary font-black leading-none">NEW</span>
)}
{item.label}
</Link>
)
})}
</div>
{/* ===== MOBILE: Sport Category Icons Row ===== */}
<div className="flex md:hidden overflow-x-auto scrollbar-none bg-[#333] border-t border-white/5 py-2 px-2 gap-4">
{[
{ label: "Check Bet", icon: (active: boolean) => <svg viewBox="0 0 24 24" className="size-5 fill-white/80"><path d="M20 4H4c-1.11 0-2 .89-2 2v12c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z"/></svg>, count: 99 },
{ label: "Live", icon: (active: boolean) => <div className="size-2 bg-brand-live rounded-full animate-pulse" />, count: 1247 },
{ label: "Football", icon: (active: boolean) => <svg viewBox="0 0 24 24" className="size-5 fill-white/80"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6z"/></svg>, count: 95 },
{ label: "Tennis", icon: (active: boolean) => <svg viewBox="0 0 24 24" className="size-5 fill-white/80"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></svg>, count: 384 },
{ label: "Basketball", icon: (active: boolean) => <svg viewBox="0 0 24 24" className="size-5 fill-white/80"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6z"/></svg>, count: 173 },
].map((item, idx) => (
<div key={idx} className="flex flex-col items-center gap-1 shrink-0 px-2 min-w-[60px] relative">
<span className="absolute -top-1 right-0 bg-white/20 text-white text-[9px] px-1 rounded-sm font-bold">{item.count}</span>
<div className="size-10 rounded-full bg-white/5 flex items-center justify-center border border-white/5">
{typeof item.icon === 'function' ? item.icon(false) : item.icon}
</div>
<span className="text-[9px] text-white/60 font-medium uppercase tracking-tighter">{item.label}</span>
</div>
))}
</div>
{/* ===== DESKTOP: Secondary sub-header ===== */}
<div className="hidden md:flex bg-brand-surface-light border-t border-white/5 h-8 px-3 items-center gap-6 text-[11px]">
{[
{ label: "Sport Home", href: "/" },
{ label: "General View", href: "/live", forceActive: isLivePage },
{ label: "Event View", href: "/live/event" },
].map((tab) => {
const isActive = tab.forceActive || pathname === tab.href
return (
<Link key={tab.label} href={tab.href}
className={cn(
"relative h-full flex items-center text-[10px] font-bold uppercase transition-colors tracking-tight px-1",
isActive ? "text-brand-primary" : "text-white/60 hover:text-white"
)}
>
{tab.label}
{isActive && tab.label !== "Sport Home" && (
<div className="absolute bottom-0 left-0 right-0 h-[2px] bg-brand-primary" />
)}
</Link>
)
})}
</div>
</header>
{/* ===== MOBILE Drawer ===== */}
{drawerOpen && (
<div className="fixed inset-0 z-[9998] flex md:hidden">
{/* Backdrop */}
<div className="absolute inset-0 bg-black/60" onClick={() => setDrawerOpen(false)} />
{/* Drawer panel */}
<div className="relative w-72 bg-brand-bg h-full flex flex-col shadow-2xl animate-slide-in-left overflow-y-auto">
{/* Drawer header */}
<div className="flex items-center justify-between px-4 py-3 bg-brand-surface border-b border-white/10">
<div className="flex items-center">
<div className="bg-brand-accent px-2 py-0.5 -skew-x-12 flex items-center h-[24px]">
<span className="text-base font-black text-white italic tracking-tighter skew-x-12 leading-none">HARIF</span>
</div>
<span className="text-base font-black text-brand-primary italic tracking-tighter ml-1 leading-none">SPORT</span>
</div>
<button onClick={() => setDrawerOpen(false)} className="text-white/60 hover:text-white text-2xl leading-none">×</button>
</div>
{/* Nav links */}
<nav className="flex-1 py-2">
{drawerLinks.map((link) => (
<Link
key={link.href}
href={link.href}
className={cn(
"flex items-center px-5 py-3 text-[13px] font-semibold border-b border-white/5 transition-colors",
pathname === link.href ? "text-brand-primary bg-white/5" : "text-white/80 hover:text-white hover:bg-white/5"
)}
>
{link.label}
</Link>
))}
</nav>
</div>
</div>
)}
</>
)
}