feat: enhance layout with mobile navigation and added themes var

This commit is contained in:
brooktewabe 2026-02-21 21:18:41 +03:00
parent 77944930d0
commit 6d475650da
6 changed files with 445 additions and 194 deletions

View File

@ -42,38 +42,52 @@
--radius-md: calc(var(--radius) - 2px); --radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius); --radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px); --radius-xl: calc(var(--radius) + 4px);
/* Brand Theme Parameters */
--color-brand-primary: var(--brand-primary);
--color-brand-primary-hover: var(--brand-primary-hover);
--color-brand-secondary: var(--brand-secondary);
--color-brand-bg: var(--brand-bg);
--color-brand-surface: var(--brand-surface);
--color-brand-surface-light: var(--brand-surface-light);
--color-brand-accent: var(--brand-accent);
--color-brand-live: var(--brand-live);
} }
:root { :root {
--radius: 0rem; --radius: 0rem;
/* HarifSport orange theme colors */
--background: #121212; /* Brand Colors (Black, Yellow, White theme) */
--brand-primary: #ff9800;
--brand-primary-hover: #e68900;
--brand-secondary: #ff9800;
/* Usually same as primary for now */
--brand-bg: #121212;
--brand-surface: #1a1a1a;
--brand-surface-light: #2a2a2a;
--brand-accent: #852222;
/* Maroon */
--brand-live: #ff3b3b;
/* Shadcn default mappings */
--background: var(--brand-bg);
--foreground: #ffffff; --foreground: #ffffff;
--card: #1e1e1e; --card: #1e1e1e;
--card-foreground: #ffffff; --card-foreground: #ffffff;
--popover: #1e1e1e; --popover: #1e1e1e;
--popover-foreground: #ffffff; --popover-foreground: #ffffff;
--primary: #ff9800; --primary: var(--brand-primary);
--primary-foreground: #ffffff; --primary-foreground: #ffffff;
--secondary: #222222; --secondary: #222222;
--secondary-foreground: #a0a0a0; --secondary-foreground: #a0a0a0;
--muted: #1a1a1a; --muted: #1a1a1a;
--muted-foreground: #808080; --muted-foreground: #808080;
--accent: #ff9800; --accent: var(--brand-primary);
--accent-foreground: #121212; --accent-foreground: #121212;
--destructive: #ef4444; --destructive: #ef4444;
--border: #2a2a2a; --border: #2a2a2a;
--input: #222222; --input: #222222;
--ring: #ff9800; --ring: var(--brand-primary);
/* HarifSport specific */
--hs-orange: #ff9800;
--hs-maroon: #852222;
--hs-dark-grey: #1a1a1a;
--hs-odds-bg: #2a2a2a;
--hs-odds-text: #ff9800;
--hs-header-bg: #121212;
--hs-live-red: #ff3b3b;
} }
.dark { .dark {
@ -169,6 +183,31 @@
animation: fade-in 0.18s ease-out both; animation: fade-in 0.18s ease-out both;
} }
/* Mobile drawer slide-in from left */
@keyframes slide-in-left {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
.animate-slide-in-left {
animation: slide-in-left 0.22s ease-out both;
}
/* Hide scrollbar for mobile nav */
.scrollbar-none {
-ms-overflow-style: none;
scrollbar-width: none;
}
.scrollbar-none::-webkit-scrollbar {
display: none;
}
/* Scrollbar */ /* Scrollbar */
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 4px; width: 4px;

View File

@ -15,13 +15,13 @@ function Logo() {
))} ))}
</div> </div>
{/* HARIF box */} {/* HARIF box */}
<div className="bg-[#852222] px-3 py-1 -skew-x-12 flex items-center h-[38px]"> <div className="bg-brand-accent px-3 py-1 -skew-x-12 flex items-center h-[38px]">
<span className="text-2xl font-black text-white italic tracking-tighter skew-x-12 inline-block leading-none"> <span className="text-2xl font-black text-white italic tracking-tighter skew-x-12 inline-block leading-none">
HARIF HARIF
</span> </span>
</div> </div>
{/* SPORT text */} {/* SPORT text */}
<span className="text-2xl font-black text-[#ff9800] italic tracking-tighter ml-1 leading-none"> <span className="text-2xl font-black text-brand-primary italic tracking-tighter ml-1 leading-none">
SPORT SPORT
</span> </span>
</div> </div>
@ -66,7 +66,7 @@ export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
onClick={onClose} onClick={onClose}
> >
<div <div
className="relative w-[420px] bg-[#3a3a3a] shadow-2xl animate-fade-in" className="relative w-[420px] bg-brand-surface-light shadow-2xl animate-fade-in"
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
{/* Close button */} {/* Close button */}
@ -79,7 +79,7 @@ export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
</button> </button>
{/* Logo */} {/* Logo */}
<div className="flex items-center justify-center py-5 border-b border-white/10 bg-[#2e2e2e]"> <div className="flex items-center justify-center py-5 border-b border-white/10 bg-brand-surface">
<Logo /> <Logo />
</div> </div>
@ -105,7 +105,7 @@ export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
type="tel" type="tel"
value={phone} value={phone}
onChange={(e) => setPhone(e.target.value)} onChange={(e) => setPhone(e.target.value)}
className="flex-1 bg-white border border-l-0 border-gray-300 px-3 py-2 text-sm text-[#333] placeholder:text-gray-400 focus:outline-none focus:border-[#ff9800]" className="flex-1 bg-white border border-l-0 border-gray-300 px-3 py-2 text-sm text-[#333] placeholder:text-gray-400 focus:outline-none focus:border-brand-primary"
/> />
</div> </div>
</div> </div>
@ -120,7 +120,7 @@ export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
value={password} value={password}
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
placeholder="Password" placeholder="Password"
className="w-full bg-white border border-gray-300 px-3 py-2 text-sm text-[#333] placeholder:text-gray-400 focus:outline-none focus:border-[#ff9800]" className="w-full bg-white border border-gray-300 px-3 py-2 text-sm text-[#333] placeholder:text-gray-400 focus:outline-none focus:border-brand-primary"
/> />
</div> </div>
@ -135,7 +135,7 @@ export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
value={repeatPassword} value={repeatPassword}
onChange={(e) => setRepeatPassword(e.target.value)} onChange={(e) => setRepeatPassword(e.target.value)}
placeholder="Repeat Password" placeholder="Repeat Password"
className="w-full bg-white border border-gray-300 px-3 py-2 text-sm text-[#333] placeholder:text-gray-400 focus:outline-none focus:border-[#ff9800]" className="w-full bg-white border border-gray-300 px-3 py-2 text-sm text-[#333] placeholder:text-gray-400 focus:outline-none focus:border-brand-primary"
/> />
</div> </div>
)} )}
@ -147,7 +147,7 @@ export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
type="checkbox" type="checkbox"
checked={ageConfirmed} checked={ageConfirmed}
onChange={(e) => setAgeConfirmed(e.target.checked)} onChange={(e) => setAgeConfirmed(e.target.checked)}
className="w-4 h-4 accent-[#ff9800]" className="w-4 h-4 accent-brand-primary"
/> />
<span className="text-[12px] text-white/80"> <span className="text-[12px] text-white/80">
I confirm I&apos;m over 21 years old I confirm I&apos;m over 21 years old
@ -160,7 +160,7 @@ export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
<div className="text-right -mt-2"> <div className="text-right -mt-2">
<Link <Link
href="/reset-password" href="/reset-password"
className="text-[11px] text-white/50 hover:text-[#ff9800] transition-colors" className="text-[11px] text-white/50 hover:text-brand-primary transition-colors"
onClick={onClose} onClick={onClose}
> >
Forgot password? Forgot password?
@ -169,7 +169,7 @@ export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
)} )}
{/* Submit button */} {/* Submit button */}
<button className="w-full bg-[#e6b800] hover:bg-[#ffcc00] text-black font-black py-3 uppercase text-sm tracking-widest transition-colors"> <button className="w-full bg-brand-primary hover:bg-brand-primary-hover text-black font-black py-3 uppercase text-sm tracking-widest transition-colors">
{mode === "login" ? "LOGIN" : "REGISTER"} {mode === "login" ? "LOGIN" : "REGISTER"}
</button> </button>
@ -190,7 +190,7 @@ export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
<> <>
Don&apos;t have an account?{" "} Don&apos;t have an account?{" "}
<button <button
className="text-[#ff9800] hover:underline font-semibold" className="text-brand-primary hover:underline font-semibold"
onClick={() => setMode("register")} onClick={() => setMode("register")}
> >
Register Register
@ -200,7 +200,7 @@ export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
<> <>
Already have an account?{" "} Already have an account?{" "}
<button <button
className="text-[#ff9800] hover:underline font-semibold" className="text-brand-primary hover:underline font-semibold"
onClick={() => setMode("login")} onClick={() => setMode("login")}
> >
Login Login

View File

@ -1,12 +1,13 @@
"use client" "use client"
import { usePathname } from "next/navigation" import { usePathname } from "next/navigation"
import { useState } from "react" import { useState, useCallback } from "react"
import { SiteHeader } from "@/components/layout/site-header" import { SiteHeader } from "@/components/layout/site-header"
import { SportsSidebar } from "@/components/layout/sports-sidebar" import { SportsSidebar } from "@/components/layout/sports-sidebar"
import { RightPanel } from "@/components/layout/right-panel" import { RightPanel } from "@/components/layout/right-panel"
import { SiteFooter } from "@/components/layout/site-footer" import { SiteFooter } from "@/components/layout/site-footer"
import { AuthModal } from "@/components/layout/auth-modal" import { AuthModal } from "@/components/layout/auth-modal"
import { MobileBottomNav } from "@/components/layout/mobile-bottom-nav"
type AuthMode = "login" | "register" type AuthMode = "login" | "register"
@ -17,24 +18,36 @@ export default function LayoutClientWrapper({ children }: { children: React.Reac
const [authOpen, setAuthOpen] = useState(false) const [authOpen, setAuthOpen] = useState(false)
const [authMode, setAuthMode] = useState<AuthMode>("login") const [authMode, setAuthMode] = useState<AuthMode>("login")
function openAuth(mode: AuthMode) { const openAuth = useCallback((mode: AuthMode) => {
setAuthMode(mode) setAuthMode(mode)
setAuthOpen(true) setAuthOpen(true)
} }, [])
return ( return (
<div className="flex min-h-screen flex-col"> <div className="flex min-h-screen flex-col pb-14 md:pb-0">
<SiteHeader <SiteHeader
onLoginClick={() => openAuth("login")} onLoginClick={() => openAuth("login")}
onRegisterClick={() => openAuth("register")} onRegisterClick={() => openAuth("register")}
/> />
<div className="flex w-full flex-1 gap-0"> <div className="flex w-full flex-1 gap-0">
{!isLivePage && <SportsSidebar />} {/* Sidebar: hidden on mobile */}
<main className="flex-1 px-2 py-3 min-w-0">{children}</main> {!isLivePage && (
<div className="hidden md:block">
<SportsSidebar />
</div>
)}
<main className="flex-1 min-w-0 px-2 py-3">{children}</main>
{/* Right panel: hidden on mobile */}
<div className="hidden md:block">
<RightPanel /> <RightPanel />
</div> </div>
</div>
<SiteFooter /> <SiteFooter />
{/* Mobile fixed bottom nav */}
<MobileBottomNav />
{/* Auth modal */}
<AuthModal <AuthModal
open={authOpen} open={authOpen}
defaultMode={authMode} defaultMode={authMode}

View File

@ -0,0 +1,80 @@
"use client"
import Link from "next/link"
import { usePathname } from "next/navigation"
import { cn } from "@/lib/utils"
const bottomNavItems = [
{
href: "/",
label: "Home",
icon: (active: boolean) => (
<svg viewBox="0 0 24 24" className={cn("size-6", active ? "fill-brand-primary" : "fill-white/60")}>
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
</svg>
),
},
{
href: "/sports",
label: "Sports",
icon: (active: boolean) => (
<svg viewBox="0 0 24 24" className={cn("size-6", active ? "fill-brand-primary" : "fill-white/60")}>
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 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>
),
},
{
href: "/betslip",
label: "Betslip",
icon: (active: boolean) => (
<svg viewBox="0 0 24 24" className={cn("size-6", active ? "fill-brand-primary" : "fill-white/60")}>
<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>
),
},
{
href: "/games",
label: "Casino",
icon: (active: boolean) => (
<svg viewBox="0 0 24 24" className={cn("size-6", active ? "fill-brand-primary" : "fill-white/60")}>
<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 14l-5-5 1.41-1.41L12 14.17l7.59-7.59L21 8l-9 9z"/>
</svg>
),
},
{
href: "/support",
label: "Help",
icon: (active: boolean) => (
<svg viewBox="0 0 24 24" className={cn("size-6", active ? "fill-brand-primary" : "fill-white/60")}>
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/>
</svg>
),
},
]
export function MobileBottomNav() {
const pathname = usePathname()
return (
<nav className="fixed bottom-0 left-0 right-0 z-50 flex md:hidden h-14 bg-brand-bg border-t border-white/10">
{bottomNavItems.map((item) => {
const isActive = pathname === item.href
return (
<Link
key={item.href}
href={item.href}
className="flex-1 flex flex-col items-center justify-center gap-0.5 transition-colors"
>
{item.icon(isActive)}
<span className={cn(
"text-[10px] font-semibold",
isActive ? "text-brand-primary" : "text-white/60"
)}>
{item.label}
</span>
</Link>
)
})}
</nav>
)
}

View File

@ -7,19 +7,31 @@ import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button" import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input" import { Input } from "@/components/ui/input"
const mainNavItems = [ const allNavItems = [
{ href: "/", label: "ALL SPORTS" }, { href: "/", label: "SPORTS" },
{ href: "/today", label: "TODAY" },
{ href: "/live", label: "LIVE" }, { href: "/live", label: "LIVE" },
{ href: "/virtual", label: "VIRTUAL" }, { href: "/virtual", label: "VIRTUAL" },
{ href: "/special-games", label: "SPECIAL GAMES" }, { href: "/special-games", label: "SPECIAL G." },
{ href: "/aviator", label: "AVIATOR" },
]
const extraNavItems = [
{ href: "/multi-hot-5", label: "MULTI HOT 5" }, { href: "/multi-hot-5", label: "MULTI HOT 5" },
{ href: "/poker", label: "POKER", isNew: true }, { href: "/poker", label: "POKER", isNew: true },
{ href: "/race", label: "RACE", isNew: true }, { href: "/race", label: "RACE", isNew: true },
{ href: "/promo", label: "PROMO" }, { 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 { interface SiteHeaderProps {
@ -31,21 +43,29 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
const pathname = usePathname() const pathname = usePathname()
const isLivePage = pathname === "/live" const isLivePage = pathname === "/live"
const [time, setTime] = useState("") 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(() => { useEffect(() => {
const updateClock = () => { const updateClock = () => {
const now = new Date() setTime(new Date().toLocaleTimeString("en-GB", { hour12: false }))
setTime(now.toLocaleTimeString("en-GB", { hour12: false }))
} }
updateClock()
const interval = setInterval(updateClock, 1000) const interval = setInterval(updateClock, 1000)
updateClock()
return () => clearInterval(interval) return () => clearInterval(interval)
}, []) }, [])
return ( return (
<header className="bg-[#121212] sticky top-0 z-50"> <>
{/* Top bar */} <header className="bg-brand-bg sticky top-0 z-50">
<div className="bg-[#1a1a1a] px-3 py-1 flex items-center justify-between text-[11px] text-white"> {/* ===== 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"> <div className="flex items-center gap-4">
<button className="flex items-center gap-1.5 hover:text-primary transition-colors"> <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" /> <img src="https://flagcdn.com/w20/gb.png" width="16" alt="English" className="rounded-sm" />
@ -59,57 +79,81 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
<div className="flex items-center gap-6"> <div className="flex items-center gap-6">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<span className="text-white font-bold tracking-tight">+251 (0) Number</span> <span className="text-white font-bold tracking-tight">+251 (0) Number</span>
<Input type="password" placeholder="Password" className="bg-[#2a2a2a] border-none px-2 py-0.5 w-32 text-[11px] h-7 rounded-none shadow-none text-white placeholder:text-gray-500" /> <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>
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
<Button <Button onClick={onLoginClick} className="bg-[#e67e22] text-white hover:bg-[#d35400] px-5 h-7 text-[11px] font-bold rounded-none uppercase">
onClick={onLoginClick}
className="bg-[#e67e22] text-white hover:bg-[#d35400] px-5 h-7 text-[11px] font-bold rounded-none uppercase"
>
Login Login
</Button> </Button>
<Button <Button onClick={onRegisterClick} className="bg-[#d35400] text-white hover:bg-[#c0392b] px-5 h-7 text-[11px] font-bold rounded-none uppercase">
onClick={onRegisterClick}
className="bg-[#d35400] text-white hover:bg-[#c0392b] px-5 h-7 text-[11px] font-bold rounded-none uppercase"
>
Sign Up Sign Up
</Button> </Button>
</div> </div>
</div> </div>
</div> </div>
{/* Main header */} {/* ===== MOBILE: Top bar (hidden on desktop) ===== */}
<div className="flex items-center px-0 bg-[#333] h-[60px]"> <div className="flex md:hidden items-center h-12 bg-brand-bg border-b border-white/5 px-2 gap-2">
{/* Logo Section */} {/* 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"> <Link href="/" className="flex items-center shrink-0">
<div className="flex items-center bg-[#1a1a1a] h-[60px] px-4"> <div className="flex items-center bg-brand-surface h-[60px] px-4">
<div className="bg-[#852222] px-3 py-1 -skew-x-12 flex items-center h-[34px]"> <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> <span className="text-2xl font-black text-white italic tracking-tighter skew-x-12 inline-block leading-none">HARIF</span>
</div> </div>
<span className="text-2xl font-black text-[#ff9800] italic tracking-tighter ml-1 leading-none">SPORT</span> <span className="text-2xl font-black text-brand-primary italic tracking-tighter ml-1 leading-none">SPORT</span>
</div> </div>
</Link> </Link>
{/* Navigation Wrapper - Pushed to Right */}
<div className="flex items-center flex-1 justify-end px-4 h-full gap-0"> <div className="flex items-center flex-1 justify-end px-4 h-full gap-0">
{/* Home icon as button */} <Link href="/" className="flex items-center justify-center bg-brand-primary h-[60px] w-[50px] shrink-0 hover:bg-brand-primary-hover transition-colors">
<Link href="/" className="flex items-center justify-center bg-[#ff9800] h-[60px] w-[50px] shrink-0 hover:bg-[#e68900] transition-colors">
<svg viewBox="0 0 24 24" className="size-6 fill-black"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg> <svg viewBox="0 0 24 24" className="size-6 fill-black"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
</Link> </Link>
{/* Main Nav Group */}
<nav className="flex items-center text-[10.5px] font-bold h-full"> <nav className="flex items-center text-[10.5px] font-bold h-full">
{mainNavItems.map((item) => { {allNavItems.slice(0, 5).map((item) => {
const isActive = pathname === item.href const isActive = pathname === item.href
return ( return (
<Link <Link key={item.href} href={item.href}
key={item.href}
href={item.href}
className={cn( className={cn(
"px-4 flex items-center h-full transition-colors uppercase border-white/5", "px-4 flex items-center h-full transition-colors uppercase",
isActive isActive ? (item.label === "LIVE" ? "bg-brand-primary text-black" : "text-primary bg-black/10") : "text-white hover:text-primary"
? (item.label === "LIVE" ? "bg-[#ff9800] text-black" : "text-primary bg-black/10")
: "text-white hover:text-primary"
)} )}
> >
{item.label} {item.label}
@ -117,17 +161,11 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
) )
})} })}
</nav> </nav>
{/* Spacing Gap between groups if needed, but the user says "All in the right" */}
{/* Extra Nav Group */}
<nav className="flex items-center text-[10.5px] font-bold h-full"> <nav className="flex items-center text-[10.5px] font-bold h-full">
{extraNavItems.map((item) => { {allNavItems.slice(5).map((item) => {
const isActive = pathname === item.href const isActive = pathname === item.href
return ( return (
<Link <Link key={item.href} href={item.href}
key={item.href}
href={item.href}
className={cn( className={cn(
"px-4 flex flex-col items-center justify-center h-full transition-colors relative uppercase", "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" isActive ? "text-primary bg-black/10" : "text-white hover:text-primary"
@ -144,8 +182,54 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
</div> </div>
</div> </div>
{/* Secondary Sub Header */} {/* ===== MOBILE: Horizontally scrollable nav tabs ===== */}
<div className="bg-[#2a2a2a] border-t border-white/5 h-8 px-3 flex items-center gap-6 text-[11px]"> <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: "Sport Home", href: "/" },
{ label: "General View", href: "/live", forceActive: isLivePage }, { label: "General View", href: "/live", forceActive: isLivePage },
@ -153,22 +237,57 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
].map((tab) => { ].map((tab) => {
const isActive = tab.forceActive || pathname === tab.href const isActive = tab.forceActive || pathname === tab.href
return ( return (
<Link <Link key={tab.label} href={tab.href}
key={tab.label}
href={tab.href}
className={cn( className={cn(
"relative h-full flex items-center text-[10px] font-bold uppercase transition-colors tracking-tight px-1", "relative h-full flex items-center text-[10px] font-bold uppercase transition-colors tracking-tight px-1",
isActive ? "text-[#ff9800]" : "text-white/60 hover:text-white" isActive ? "text-brand-primary" : "text-white/60 hover:text-white"
)} )}
> >
{tab.label} {tab.label}
{isActive && tab.label !== "Sport Home" && ( {isActive && tab.label !== "Sport Home" && (
<div className="absolute bottom-0 left-0 right-0 h-[2px] bg-[#ff9800]" /> <div className="absolute bottom-0 left-0 right-0 h-[2px] bg-brand-primary" />
)} )}
</Link> </Link>
) )
})} })}
</div> </div>
</header> </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>
)}
</>
) )
} }

View File

@ -25,15 +25,15 @@ export function SportsSidebar() {
const [activeSport, setActiveSport] = useState("football") const [activeSport, setActiveSport] = useState("football")
return ( return (
<aside className="hidden h-full w-[240px] shrink-0 bg-[#262626] lg:block overflow-y-auto border-r border-border/40 scrollbar-hide"> <aside className="hidden h-full w-[240px] shrink-0 bg-brand-surface-light lg:block overflow-y-auto border-r border-border/40 scrollbar-hide">
{/* Sports Menu Header */} {/* Sports Menu Header */}
<div className="bg-[#1a1a1a] px-3 py-2 text-[11px] font-black text-[#ff9800] uppercase tracking-tighter flex items-center justify-between border-b border-border/30"> <div className="bg-brand-surface px-3 py-2 text-[11px] font-black text-brand-primary uppercase tracking-tighter flex items-center justify-between border-b border-border/30">
Sports Menu Sports Menu
<svg viewBox="0 0 24 24" className="size-3.5 fill-current opacity-60"><path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"/></svg> <svg viewBox="0 0 24 24" className="size-3.5 fill-current opacity-60"><path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"/></svg>
</div> </div>
{/* Top Leagues Header */} {/* Top Leagues Header */}
<div className="bg-[#262626] px-3 py-2.5 text-[11px] font-black text-[#ff9800] uppercase text-center border-b border-border/20 flex items-center justify-center gap-2"> <div className="bg-brand-surface-light px-3 py-2.5 text-[11px] font-black text-brand-primary uppercase text-center border-b border-border/20 flex items-center justify-center gap-2">
Top Leagues Top Leagues
</div> </div>
@ -43,7 +43,7 @@ export function SportsSidebar() {
<Link <Link
key={league.id} key={league.id}
href={`/?league=${league.id}`} href={`/?league=${league.id}`}
className="w-full flex items-center justify-between px-3 py-2 text-left text-white/90 hover:bg-[#333] transition-colors border-b border-border/10 group h-9" className="w-full flex items-center justify-between px-3 py-2 text-left text-white/90 hover:bg-brand-surface transition-colors border-b border-border/10 group h-9"
> >
<div className="flex items-center gap-2.5 min-w-0"> <div className="flex items-center gap-2.5 min-w-0">
<div className="size-4 shrink-0 overflow-hidden rounded-sm flex items-center justify-center bg-white/10 group-hover:bg-white/20 transition-colors"> <div className="size-4 shrink-0 overflow-hidden rounded-sm flex items-center justify-center bg-white/10 group-hover:bg-white/20 transition-colors">
@ -55,8 +55,8 @@ export function SportsSidebar() {
</div> </div>
<span className="text-[10.5px] font-bold leading-tight truncate max-w-[150px]">{league.name}</span> <span className="text-[10.5px] font-bold leading-tight truncate max-w-[150px]">{league.name}</span>
</div> </div>
<div className="size-3.5 rounded-full border border-white/20 flex items-center justify-center group-hover:border-[#ff9800] transition-colors shrink-0"> <div className="size-3.5 rounded-full border border-white/20 flex items-center justify-center group-hover:border-brand-primary transition-colors shrink-0">
<div className="size-1.5 bg-white/40 rounded-full group-hover:bg-[#ff9800]" /> <div className="size-1.5 bg-white/40 rounded-full group-hover:bg-brand-primary" />
</div> </div>
</Link> </Link>
))} ))}
@ -69,8 +69,8 @@ export function SportsSidebar() {
</Button> </Button>
{/* Quick Filter Section */} {/* Quick Filter Section */}
<div className="bg-[#1a1a1a] p-3 border-b border-border/30"> <div className="bg-brand-surface p-3 border-b border-border/30">
<span className="text-[#ff9800] text-[10.5px] uppercase font-black block mb-2 tracking-tight">Quick Filter</span> <span className="text-brand-primary text-[10.5px] uppercase font-black block mb-2 tracking-tight">Quick Filter</span>
<div className="grid grid-cols-6 gap-[1px]"> <div className="grid grid-cols-6 gap-[1px]">
{["All", "Today", "3h", "6h", "9h", "12h"].map((t) => ( {["All", "Today", "3h", "6h", "9h", "12h"].map((t) => (
<button key={t} className={cn( <button key={t} className={cn(
@ -82,19 +82,19 @@ export function SportsSidebar() {
</div> </div>
{/* Search Event Section */} {/* Search Event Section */}
<div className="bg-[#1a1a1a] p-3 border-b border-border/40"> <div className="bg-brand-surface p-3 border-b border-border/40">
<span className="text-[#ff9800] text-[10.5px] uppercase font-black block mb-1 tracking-tight">Search Event</span> <span className="text-brand-primary text-[10.5px] uppercase font-black block mb-1 tracking-tight">Search Event</span>
<p className="text-[9px] text-white/30 mb-2 leading-tight font-medium uppercase">Insert the events name or at least one team in the form below</p> <p className="text-[9px] text-white/30 mb-2 leading-tight font-medium uppercase">Insert the events name or at least one team in the form below</p>
<div className="flex flex-col gap-1.5"> <div className="flex flex-col gap-1.5">
<div className="relative"> <div className="relative">
<input type="text" className="bg-[#2a2a2a] border-none text-white text-[11px] px-3 py-2 w-full focus:ring-0 placeholder:text-white/20" placeholder="Search" /> <input type="text" className="bg-brand-surface-light border-none text-white text-[11px] px-3 py-2 w-full focus:ring-0 placeholder:text-white/20" placeholder="Search" />
</div> </div>
<Button className="bg-[#ff9800] text-black hover:bg-[#e68900] py-2 h-auto rounded-none text-[11px] font-black uppercase tracking-wider">Search</Button> <Button className="bg-brand-primary text-black hover:bg-brand-primary-hover py-2 h-auto rounded-none text-[11px] font-black uppercase tracking-wider">Search</Button>
</div> </div>
</div> </div>
{/* Sport categories */} {/* Sport categories */}
<div className="divide-y divide-border/10 bg-[#262626]"> <div className="divide-y divide-border/10 bg-brand-surface-light">
{sportCategories.map((sport) => ( {sportCategories.map((sport) => (
<button <button
key={sport.id} key={sport.id}
@ -102,8 +102,8 @@ export function SportsSidebar() {
className={cn( className={cn(
"w-full flex items-center justify-between px-3 py-2 text-left transition-colors border-b border-border/10 h-9", "w-full flex items-center justify-between px-3 py-2 text-left transition-colors border-b border-border/10 h-9",
activeSport === sport.id activeSport === sport.id
? "bg-[#333] text-white" ? "bg-brand-surface text-white"
: "text-white/70 hover:bg-[#333] hover:text-white" : "text-white/70 hover:bg-brand-surface hover:text-white"
)} )}
> >
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
@ -119,43 +119,43 @@ export function SportsSidebar() {
</div> </div>
{/* Bet Services */} {/* Bet Services */}
<div className="mt-2 text-[11px] font-bold text-[#ff9800] px-3 py-2 uppercase border-y border-border/20 bg-[#1a1a1a]"> <div className="mt-2 text-[11px] font-bold text-brand-primary px-3 py-2 uppercase border-y border-border/20 bg-brand-surface">
Bet Services Bet Services
</div> </div>
<div className="grid grid-cols-3 gap-0 border-b border-border/10"> <div className="grid grid-cols-3 gap-0 border-b border-border/10">
<Button variant="ghost" className="flex flex-col items-center justify-center py-4 h-auto rounded-none border-r border-border/10 hover:bg-[#333] group"> <Button variant="ghost" className="flex flex-col items-center justify-center py-4 h-auto rounded-none border-r border-border/10 hover:bg-brand-surface group">
<svg viewBox="0 0 24 24" className="size-5 mb-1.5 fill-muted-foreground group-hover:fill-[#ff9800] transition-colors"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm3.3 14.71L11 12.41V7h2v4.59l3.71 3.71-1.42 1.41z"/></svg> <svg viewBox="0 0 24 24" className="size-5 mb-1.5 fill-muted-foreground group-hover:fill-brand-primary transition-colors"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm3.3 14.71L11 12.41V7h2v4.59l3.71 3.71-1.42 1.41z"/></svg>
<span className="text-[9px] text-white font-medium">Live Score</span> <span className="text-[9px] text-white font-medium">Live Score</span>
</Button> </Button>
<Button variant="ghost" className="flex flex-col items-center justify-center py-4 h-auto rounded-none border-r border-border/10 hover:bg-[#333] group"> <Button variant="ghost" className="flex flex-col items-center justify-center py-4 h-auto rounded-none border-r border-border/10 hover:bg-brand-surface group">
<svg viewBox="0 0 24 24" className="size-5 mb-1.5 fill-muted-foreground group-hover:fill-[#ff9800] transition-colors"><path d="M5 9.2h3V19H5zM10.6 5h2.8v14h-2.8zm5.6 8H19v6h-2.8z"/></svg> <svg viewBox="0 0 24 24" className="size-5 mb-1.5 fill-muted-foreground group-hover:fill-brand-primary transition-colors"><path d="M5 9.2h3V19H5zM10.6 5h2.8v14h-2.8zm5.6 8H19v6h-2.8z"/></svg>
<span className="text-[9px] text-white font-medium">Results</span> <span className="text-[9px] text-white font-medium">Results</span>
</Button> </Button>
<Button variant="ghost" className="flex flex-col items-center justify-center py-4 h-auto rounded-none hover:bg-[#333] group"> <Button variant="ghost" className="flex flex-col items-center justify-center py-4 h-auto rounded-none hover:bg-brand-surface group">
<svg viewBox="0 0 24 24" className="size-5 mb-1.5 fill-muted-foreground group-hover:fill-[#ff9800] transition-colors"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/></svg> <svg viewBox="0 0 24 24" className="size-5 mb-1.5 fill-muted-foreground group-hover:fill-brand-primary transition-colors"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/></svg>
<span className="text-[9px] text-white font-medium">Print Odds</span> <span className="text-[9px] text-white font-medium">Print Odds</span>
</Button> </Button>
</div> </div>
<div className="p-2 space-y-1"> <div className="p-2 space-y-1">
<Button className="w-full bg-[#004d40] text-[#00bfa5] hover:bg-[#003d33] border-none py-2 h-auto text-[11px] font-bold uppercase rounded-none tracking-widest"> <Button className="w-full bg-[#004d40] text-[#00bfa5] hover:bg-[#003d33] border-none py-2 h-auto text-[11px] font-bold uppercase rounded-none tracking-widest">
<span className="size-2 rounded-full bg-[#ff9800] mr-2 live-dot"></span> <span className="size-2 rounded-full bg-brand-primary mr-2 live-dot"></span>
IN-PLAY IN-PLAY
</Button> </Button>
<div className="bg-[#1a1a1a] p-3 border border-border/10"> <div className="bg-brand-surface p-3 border border-border/10">
<span className="text-[#ff9800] text-[10px] uppercase font-bold block mb-2">Quick Filter</span> <span className="text-brand-primary text-[10px] uppercase font-bold block mb-2">Quick Filter</span>
<div className="grid grid-cols-6 gap-0.5"> <div className="grid grid-cols-6 gap-0.5">
{["All", "Today", "3h", "6h", "9h", "12h"].map((t) => ( {["All", "Today", "3h", "6h", "9h", "12h"].map((t) => (
<button key={t} className="text-[9px] py-1 bg-[#2a2a2a] text-white/70 hover:bg-[#333] transition-colors">{t}</button> <button key={t} className="text-[9px] py-1 bg-brand-surface-light text-white/70 hover:bg-brand-surface transition-colors">{t}</button>
))} ))}
</div> </div>
</div> </div>
<div className="bg-[#1a1a1a] p-3 border border-border/10"> <div className="bg-brand-surface p-3 border border-border/10">
<span className="text-[#ff9800] text-[10px] uppercase font-bold block mb-2">Search Event</span> <span className="text-brand-primary text-[10px] uppercase font-bold block mb-2">Search Event</span>
<p className="text-[9px] text-white/40 mb-2 leading-tight">Insert the events name or at least one team in the form below</p> <p className="text-[9px] text-white/40 mb-2 leading-tight">Insert the events name or at least one team in the form below</p>
<div className="flex flex-col gap-1.5"> <div className="flex flex-col gap-1.5">
<input type="text" className="bg-[#2a2a2a] border-none text-white text-[10px] px-2 py-1.5 focus:ring-0" placeholder="Search" /> <input type="text" className="bg-brand-surface-light border-none text-white text-[10px] px-2 py-1.5 focus:ring-0" placeholder="Search" />
<Button className="bg-[#333] text-white hover:bg-[#444] py-1.5 h-auto rounded-none text-[10px] font-bold uppercase">Search</Button> <Button className="bg-brand-surface text-white hover:bg-brand-bg py-1.5 h-auto rounded-none text-[10px] font-bold uppercase transition-colors">Search</Button>
</div> </div>
</div> </div>
</div> </div>