layout
This commit is contained in:
parent
bad08b229e
commit
463cabbdd0
|
|
@ -66,39 +66,41 @@ export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="relative w-[420px] bg-brand-surface-light shadow-2xl animate-fade-in"
|
className="relative w-[280px] bg-brand-surface-light shadow-2xl animate-fade-in"
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
{/* Close button */}
|
{/* Close button */}
|
||||||
<button
|
<button
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="absolute top-2 right-3 text-white/60 hover:text-white text-xl leading-none transition-colors z-10"
|
className="absolute top-1 right-2 text-white/60 hover:text-white text-lg leading-none transition-colors z-10"
|
||||||
aria-label="Close"
|
aria-label="Close"
|
||||||
>
|
>
|
||||||
×
|
×
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<div className="flex items-center justify-center py-5 border-b border-white/10 bg-brand-surface">
|
<div className="flex items-center justify-center py-4 border-b border-white/10 bg-brand-surface">
|
||||||
|
<div className="scale-75 origin-center">
|
||||||
<Logo />
|
<Logo />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
<div className="text-center py-4">
|
<div className="text-center py-3">
|
||||||
<h2 className="text-sm font-black text-white uppercase tracking-widest">
|
<h2 className="text-[12px] font-black text-white uppercase tracking-widest">
|
||||||
{mode === "login" ? "LOGIN" : "REGISTER"}
|
{mode === "login" ? "LOGIN" : "REGISTER"}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Form */}
|
{/* Form */}
|
||||||
<div className="px-8 pb-6 space-y-4">
|
<div className="px-4 pb-6 space-y-4">
|
||||||
{/* Phone Number */}
|
{/* Phone Number */}
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-[11px] font-semibold text-white/80 mb-1">
|
<label className="block text-[11px] font-semibold text-white/80 mb-1">
|
||||||
Phone Number
|
Phone Number
|
||||||
</label>
|
</label>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<span className="flex items-center justify-center bg-white text-[#333] text-[12px] font-bold px-3 border border-gray-300 whitespace-nowrap select-none">
|
<span className="flex items-center justify-center bg-white text-[#333] text-[11px] font-bold px-1.5 border border-gray-300 whitespace-nowrap select-none">
|
||||||
ET +251
|
ET +251
|
||||||
</span>
|
</span>
|
||||||
<input
|
<input
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,18 @@ 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"
|
import { MobileBottomNav } from "@/components/layout/mobile-bottom-nav"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
type AuthMode = "login" | "register"
|
type AuthMode = "login" | "register"
|
||||||
|
|
||||||
export default function LayoutClientWrapper({ children }: { children: React.ReactNode }) {
|
export default function LayoutClientWrapper({ children }: { children: React.ReactNode }) {
|
||||||
const pathname = usePathname()
|
const pathname = usePathname()
|
||||||
const isLivePage = pathname === "/live"
|
const isLivePage = pathname === "/live"
|
||||||
|
const isVirtualPage = pathname === "/virtual"
|
||||||
|
const isSpecialGamesPage = pathname === "/special-games"
|
||||||
|
|
||||||
|
const hideLeftSidebar = isLivePage || isVirtualPage || isSpecialGamesPage
|
||||||
|
const hideRightSidebar = isVirtualPage || isSpecialGamesPage // Show RightPanel on Live page
|
||||||
|
|
||||||
const [authOpen, setAuthOpen] = useState(false)
|
const [authOpen, setAuthOpen] = useState(false)
|
||||||
const [authMode, setAuthMode] = useState<AuthMode>("login")
|
const [authMode, setAuthMode] = useState<AuthMode>("login")
|
||||||
|
|
@ -24,23 +30,25 @@ export default function LayoutClientWrapper({ children }: { children: React.Reac
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen flex-col pb-14 md:pb-0">
|
<div className="flex min-h-screen flex-col pb-14 md:pb-0 overflow-x-hidden">
|
||||||
<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 min-w-0">
|
||||||
{/* Sidebar: hidden on mobile */}
|
{/* Sidebar: hidden on mobile and hidden on specific pages */}
|
||||||
{!isLivePage && (
|
{!hideLeftSidebar && (
|
||||||
<div className="hidden md:block">
|
<div className="hidden md:block shrink-0">
|
||||||
<SportsSidebar />
|
<SportsSidebar />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<main className="flex-1 min-w-0 px-2 py-3">{children}</main>
|
<main className={cn("flex-1 min-w-0 overflow-x-hidden", !hideLeftSidebar && "px-2 py-3")}>{children}</main>
|
||||||
{/* Right panel: hidden on mobile */}
|
{/* Right panel: completely off-flow on mobile/tablet; only from lg to match RightPanel */}
|
||||||
<div className="hidden md:block">
|
{!hideRightSidebar && (
|
||||||
|
<div className="hidden lg:block shrink-0 overflow-hidden">
|
||||||
<RightPanel />
|
<RightPanel />
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<SiteFooter />
|
<SiteFooter />
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
import { Betslip } from "@/components/betting/betslip"
|
import { Betslip } from "@/components/betting/betslip"
|
||||||
import { ReloadTicket } from "@/components/betting/reload-ticket"
|
import { ReloadTicket } from "@/components/betting/reload-ticket"
|
||||||
import { CheckYourBet } from "@/components/betting/check-your-bet"
|
import { CheckYourBet } from "@/components/betting/check-your-bet"
|
||||||
|
import { useBetslipStore } from "@/lib/store/betslip-store"
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
|
|
@ -10,14 +11,15 @@ import { Input } from "@/components/ui/input"
|
||||||
|
|
||||||
export function RightPanel() {
|
export function RightPanel() {
|
||||||
const [activeTab, setActiveTab] = useState<"betslip" | "myBets">("betslip")
|
const [activeTab, setActiveTab] = useState<"betslip" | "myBets">("betslip")
|
||||||
|
const bets = useBetslipStore((s) => s.bets)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className="hidden lg:flex w-[280px] shrink-0 flex-col gap-0 border-l border-border/30 bg-[#222]">
|
<aside className="hidden lg:flex w-[280px] shrink-0 flex-col gap-0 border-l border-border/30 bg-brand-surface">
|
||||||
{/* Search Header */}
|
{/* Search Header */}
|
||||||
<div className="p-3 bg-[#1a1a1a] flex items-center justify-between border-b border-border/20">
|
<div className="p-3 bg-brand-bg flex items-center justify-between border-b border-border/20">
|
||||||
<div className="flex items-center gap-2 text-[12px] font-bold text-white uppercase">
|
<div className="flex items-center gap-2 text-[12px] font-bold text-white uppercase">
|
||||||
Fast Bet <span className="text-[#ff9800]">QBET</span>
|
Fast Bet <span className="text-brand-primary">QBET</span>
|
||||||
<svg viewBox="0 0 24 24" className="size-4 fill-[#ff9800] ml-1"><path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>
|
<svg viewBox="0 0 24 24" className="size-4 fill-brand-primary ml-1"><path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -26,32 +28,28 @@ export function RightPanel() {
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Event Code"
|
placeholder="Event Code"
|
||||||
className="bg-[#333] border border-border/40 px-2 py-1.5 h-auto text-[11px] outline-none text-white focus:border-[#ff9800] rounded-none shadow-none"
|
className="bg-brand-surface-light border border-border/40 px-2 py-1.5 h-auto text-[11px] outline-none text-white focus:border-brand-primary rounded-none shadow-none"
|
||||||
/>
|
/>
|
||||||
<div className="bg-[#333] border border-border/40 px-2 py-1.5 text-[11px] text-muted-foreground flex items-center justify-center">...</div>
|
<div className="bg-brand-surface-light border border-border/40 px-2 py-1.5 text-[11px] text-muted-foreground flex items-center justify-center">...</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Tab switcher */}
|
{/* Tab switcher */}
|
||||||
<div className="flex items-center justify-between text-[11px] font-bold py-2.5 px-1 border-b border-border/10">
|
<div className="flex items-center justify-between text-[11px] font-bold py-2.5 px-1 border-b border-border/10">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-[#ff9800] uppercase cursor-pointer">Betslip</span>
|
<span className="text-brand-primary uppercase cursor-pointer">Betslip</span>
|
||||||
<span className="bg-[#ff9800] text-black px-1.5 rounded-full text-[10px] font-bold">0</span>
|
<span className="bg-brand-primary text-black px-1.5 rounded-full text-[10px] font-bold min-w-[18px] text-center">{bets.length}</span>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
className="text-white uppercase flex items-center gap-1 ml-2 opacity-80 hover:opacity-100 p-0 h-auto font-bold text-[11px]"
|
className="text-white uppercase flex items-center gap-1 ml-2 opacity-80 hover:opacity-100 p-0 h-auto font-bold text-[11px]"
|
||||||
>
|
>
|
||||||
<svg viewBox="0 0 24 24" className="size-3 fill-[#ff9800]"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>
|
<svg viewBox="0 0 24 24" className="size-3 fill-brand-primary"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>
|
||||||
Settings
|
Settings
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-white uppercase cursor-pointer opacity-80 hover:opacity-100">Decimal</span>
|
<span className="text-white uppercase cursor-pointer opacity-80 hover:opacity-100">Decimal</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="py-10 px-4 text-center">
|
<Betslip />
|
||||||
<p className="text-[11px] text-muted-foreground font-medium leading-relaxed">
|
|
||||||
No bet has been selected. To select a bet, please click on the respective odds
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ReloadTicket />
|
<ReloadTicket />
|
||||||
<CheckYourBet />
|
<CheckYourBet />
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import Link from "next/link"
|
||||||
|
|
||||||
export function SiteFooter() {
|
export function SiteFooter() {
|
||||||
return (
|
return (
|
||||||
<footer className="bg-[#2a2a2a] text-white pt-12">
|
<footer className="bg-brand-surface text-white pt-12">
|
||||||
<div className="container mx-auto px-6 grid grid-cols-1 md:grid-cols-4 gap-12 text-center md:text-left">
|
<div className="container mx-auto px-6 grid grid-cols-1 md:grid-cols-4 gap-12 text-center md:text-left">
|
||||||
{/* ABOUT */}
|
{/* ABOUT */}
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -51,12 +51,12 @@ export function SiteFooter() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Logo Section */}
|
{/* Logo Section */}
|
||||||
<div className="flex flex-col items-center justify-center py-16 border-t border-white/5 mt-12 bg-[#222]">
|
<div className="flex flex-col items-center justify-center py-16 border-t border-white/5 mt-12 bg-brand-surface-light">
|
||||||
<div className="flex items-center bg-[#1a1a1a] px-5 py-2">
|
<div className="flex items-center bg-brand-surface px-5 py-2">
|
||||||
<div className="bg-[#852222] px-3 py-1 -skew-x-12">
|
<div className="bg-brand-accent px-3 py-1 -skew-x-12">
|
||||||
<span className="text-3xl font-black text-white italic tracking-tighter skew-x-12 inline-block">HARIF</span>
|
<span className="text-3xl font-black text-white italic tracking-tighter skew-x-12 inline-block">HARIF</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-3xl font-black text-[#ff9800] italic tracking-tighter ml-1">SPORT</span>
|
<span className="text-3xl font-black text-brand-primary italic tracking-tighter ml-1">SPORT</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Footer Links */}
|
{/* Footer Links */}
|
||||||
|
|
@ -70,7 +70,7 @@ export function SiteFooter() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Cookie Text */}
|
{/* Cookie Text */}
|
||||||
<div className="bg-[#1a1a1a] py-10 px-6 text-center">
|
<div className="bg-brand-bg py-10 px-6 text-center">
|
||||||
<div className="container mx-auto max-w-5xl">
|
<div className="container mx-auto max-w-5xl">
|
||||||
<p className="text-[10px] text-white/40 leading-relaxed font-medium uppercase tracking-tight">
|
<p className="text-[10px] text-white/40 leading-relaxed font-medium uppercase tracking-tight">
|
||||||
By accessing, or continuing to use or browse this site, you consent to our use of certain cookies to improve your experience with us. We only use cookies that will enhance your experience and will not interfere with your privacy. Please look at our Cookie Policy for further informations on our use of the cookie and how you can disable it or manage it if you so choose.
|
By accessing, or continuing to use or browse this site, you consent to our use of certain cookies to improve your experience with us. We only use cookies that will enhance your experience and will not interfere with your privacy. Please look at our Cookie Policy for further informations on our use of the cookie and how you can disable it or manage it if you so choose.
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,13 @@ import { useState, useEffect } from "react"
|
||||||
import { cn } from "@/lib/utils"
|
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"
|
||||||
|
import Image from "next/image"
|
||||||
|
|
||||||
const allNavItems = [
|
const allNavItems = [
|
||||||
{ href: "/", label: "SPORTS" },
|
{ href: "/", label: "ALL 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 G." },
|
{ href: "/special-games", label: "SPECIAL Games" },
|
||||||
{ 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 },
|
||||||
|
|
@ -68,7 +68,14 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
|
||||||
<div className="hidden md:flex bg-brand-surface px-3 py-1 items-center justify-between text-[11px] text-white">
|
<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" />
|
<Image
|
||||||
|
src="https://flagcdn.com/w20/gb.png"
|
||||||
|
alt="English"
|
||||||
|
width={20}
|
||||||
|
height={15}
|
||||||
|
className="rounded-sm"
|
||||||
|
unoptimized // Since it's an external image from a CDN
|
||||||
|
/>
|
||||||
<span className="font-bold flex items-center gap-1">en <span className="text-[8px]">▼</span></span>
|
<span className="font-bold flex items-center gap-1">en <span className="text-[8px]">▼</span></span>
|
||||||
</button>
|
</button>
|
||||||
<div className="flex items-center gap-2 font-bold">
|
<div className="flex items-center gap-2 font-bold">
|
||||||
|
|
@ -78,14 +85,16 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
|
||||||
</div>
|
</div>
|
||||||
<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)
|
||||||
|
<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" />
|
||||||
|
</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" />
|
<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 onClick={onLoginClick} className="bg-[#e67e22] text-white hover:bg-[#d35400] px-5 h-7 text-[11px] font-bold rounded-none uppercase">
|
<Button onClick={onLoginClick} className="bg-brand-primary text-white hover:bg-brand-primary-hover px-5 h-7 text-[11px] font-bold rounded-none uppercase">
|
||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={onRegisterClick} className="bg-[#d35400] text-white hover:bg-[#c0392b] px-5 h-7 text-[11px] font-bold rounded-none uppercase">
|
<Button onClick={onRegisterClick} className="bg-brand-primary text-white hover:bg-brand-primary-hover px-5 h-7 text-[11px] font-bold rounded-none uppercase">
|
||||||
Sign Up
|
Sign Up
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -119,13 +128,13 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
|
||||||
<div className="flex items-center gap-1 shrink-0">
|
<div className="flex items-center gap-1 shrink-0">
|
||||||
<button
|
<button
|
||||||
onClick={onLoginClick}
|
onClick={onLoginClick}
|
||||||
className="bg-[#e67e22] text-white px-3 h-8 text-[11px] font-bold uppercase"
|
className="bg-brand-primary text-white px-3 h-8 text-[11px] font-bold uppercase"
|
||||||
>
|
>
|
||||||
LOGIN
|
LOGIN
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={onRegisterClick}
|
onClick={onRegisterClick}
|
||||||
className="bg-[#d35400] text-white px-3 h-8 text-[11px] font-bold uppercase"
|
className="bg-brand-primary text-white px-3 h-8 text-[11px] font-bold uppercase"
|
||||||
>
|
>
|
||||||
SIGN UP
|
SIGN UP
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -133,30 +142,38 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ===== DESKTOP: Main header bar ===== */}
|
{/* ===== DESKTOP: Main header bar ===== */}
|
||||||
<div className="hidden md:flex items-center px-0 bg-[#333] h-[60px]">
|
<div className="hidden md:flex items-center px-0 bg-brand-bg h-[60px]">
|
||||||
<Link href="/" className="flex items-center shrink-0">
|
<Link href="/" className="flex items-center shrink-0">
|
||||||
<div className="flex items-center bg-brand-surface h-[60px] px-4">
|
<div className="flex items-center bg-brand-surface h-[60px] px-4 w-[280px] shrink-0 border-r border-white/5">
|
||||||
<div className="bg-brand-accent 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-brand-primary 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>
|
||||||
<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 bg-brand-surface">
|
||||||
<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
|
||||||
<svg viewBox="0 0 24 24" className="size-6 fill-black"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
|
href="/"
|
||||||
|
className={cn(
|
||||||
|
"flex items-center justify-center h-[60px] w-[50px] shrink-0 transition-colors",
|
||||||
|
pathname === "/"
|
||||||
|
? "bg-brand-primary hover:bg-brand-primary-hover"
|
||||||
|
: "text-white hover:bg-white/10"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<svg viewBox="0 0 24 24" className={cn("size-6", pathname === "/" ? "fill-black" : "fill-white")}><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
|
||||||
</Link>
|
</Link>
|
||||||
<nav className="flex items-center text-[10.5px] font-bold h-full">
|
<nav className="flex items-center text-[10.5px] font-bold h-full">
|
||||||
{allNavItems.slice(0, 5).map((item) => {
|
{allNavItems.slice(0, 5).map((item) => {
|
||||||
const isActive = pathname === item.href
|
const isActive = pathname === item.href && item.href !== "/"
|
||||||
return (
|
return (
|
||||||
<Link key={item.href} href={item.href}
|
<Link key={item.href} href={item.href}
|
||||||
className={cn(
|
className={cn(
|
||||||
"px-4 flex items-center h-full transition-colors uppercase",
|
"px-4 flex items-center h-full transition-colors uppercase relative",
|
||||||
isActive ? (item.label === "LIVE" ? "bg-brand-primary text-black" : "text-primary bg-black/10") : "text-white hover:text-primary"
|
isActive ? "text-white bg-brand-primary" : "text-white hover:bg-white/5"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{item.label}
|
<span>{item.label}</span>
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
@ -168,11 +185,11 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
|
||||||
<Link key={item.href} href={item.href}
|
<Link 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-white bg-brand-primary" : "text-white hover:bg-white/5"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{item.isNew && (
|
{item.isNew && (
|
||||||
<span className="absolute top-3 text-[7px] text-primary font-black tracking-tighter leading-none">NEW</span>
|
<span className="absolute top-3 text-[7px] text-white/70 font-black tracking-tighter leading-none">NEW</span>
|
||||||
)}
|
)}
|
||||||
<span className={cn(item.isNew && "mt-1.5")}>{item.label}</span>
|
<span className={cn(item.isNew && "mt-1.5")}>{item.label}</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
@ -184,8 +201,14 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
|
||||||
|
|
||||||
{/* ===== MOBILE: Horizontally scrollable nav tabs ===== */}
|
{/* ===== MOBILE: Horizontally scrollable nav tabs ===== */}
|
||||||
<div className="flex md:hidden overflow-x-auto scrollbar-none bg-brand-surface-light border-t border-white/5">
|
<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">
|
<Link
|
||||||
<svg viewBox="0 0 24 24" className="size-5 fill-black"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
|
href="/"
|
||||||
|
className={cn(
|
||||||
|
"flex-none px-4 h-9 flex items-center transition-colors",
|
||||||
|
pathname === "/" ? "bg-brand-primary" : "text-white"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<svg viewBox="0 0 24 24" className={cn("size-5", pathname === "/" ? "fill-black" : "fill-white")}><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
|
||||||
</Link>
|
</Link>
|
||||||
{allNavItems.map((item) => {
|
{allNavItems.map((item) => {
|
||||||
const isActive = pathname === item.href
|
const isActive = pathname === item.href
|
||||||
|
|
@ -210,7 +233,7 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ===== MOBILE: Sport Category Icons Row ===== */}
|
{/* ===== 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">
|
<div className="flex md:hidden overflow-x-auto scrollbar-none bg-brand-surface-light 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: "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: "Live", icon: (active: boolean) => <div className="size-2 bg-brand-live rounded-full animate-pulse" />, count: 1247 },
|
||||||
|
|
@ -229,11 +252,11 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ===== DESKTOP: Secondary sub-header ===== */}
|
{/* ===== DESKTOP: Secondary sub-header ===== */}
|
||||||
|
{pathname !== "/virtual" && pathname !== "/special-games" && (
|
||||||
<div className="hidden md:flex bg-brand-surface-light border-t border-white/5 h-8 px-3 items-center gap-6 text-[11px]">
|
<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: "Live View", href: "/live", forceActive: isLivePage },
|
||||||
{ label: "Event View", href: "/live/event" },
|
|
||||||
].map((tab) => {
|
].map((tab) => {
|
||||||
const isActive = tab.forceActive || pathname === tab.href
|
const isActive = tab.forceActive || pathname === tab.href
|
||||||
return (
|
return (
|
||||||
|
|
@ -251,6 +274,7 @@ export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{/* ===== MOBILE Drawer ===== */}
|
{/* ===== MOBILE Drawer ===== */}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,18 @@ import Link from "next/link"
|
||||||
import { popularLeagues } from "@/lib/mock-data"
|
import { popularLeagues } from "@/lib/mock-data"
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
|
import { ChevronsLeft } from "lucide-react"
|
||||||
|
|
||||||
|
/** Soccer ball icon - outline style for white/green theme */
|
||||||
|
function SoccerBallIcon({ className }: { className?: string }) {
|
||||||
|
return (
|
||||||
|
<svg viewBox="0 0 24 24" className={className} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<circle cx="12" cy="12" r="10" />
|
||||||
|
<path d="M12 2v20M2 12h20" />
|
||||||
|
<path d="M4.93 4.93l14.14 14.14M4.93 19.07l14.14-14.14" strokeWidth="1" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const sportCategories = [
|
const sportCategories = [
|
||||||
{ id: "football", name: "Football", icon: "⚽", count: 1412 },
|
{ id: "football", name: "Football", icon: "⚽", count: 1412 },
|
||||||
|
|
@ -25,11 +37,13 @@ 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-brand-surface-light lg:block overflow-y-auto border-r border-border/40 scrollbar-hide">
|
<aside className="hidden h-full w-[280px] 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-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">
|
<div className="bg-brand-surface px-3 py-2 text-[11px] font-black text-white uppercase tracking-tighter flex items-center justify-between border-b border-border/30 h-10">
|
||||||
Sports Menu
|
<span>Sports Menu</span>
|
||||||
<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>
|
<button type="button" className="p-1 rounded hover:bg-white/10 text-white/70 hover:text-white transition-colors" aria-label="Collapse sidebar">
|
||||||
|
<ChevronsLeft className="size-4" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Top Leagues Header */}
|
{/* Top Leagues Header */}
|
||||||
|
|
@ -45,27 +59,28 @@ export function SportsSidebar() {
|
||||||
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-brand-surface 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 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-5 shrink-0 overflow-hidden rounded-sm flex items-center justify-center bg-white/5 border border-white/10 group-hover:border-white/20 transition-colors">
|
||||||
{league.logo ? (
|
{league.logo ? (
|
||||||
<img src={league.logo} alt="" className="size-full object-contain" />
|
<img src={league.logo} alt="" className="size-full object-contain" />
|
||||||
) : (
|
) : (
|
||||||
<span className="text-[10px] leading-none invert">⚽</span>
|
<span className="text-[11px]">⚽</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<span className="text-[10.5px] font-bold leading-tight truncate max-w-[150px]">{league.name}</span>
|
<span className="text-white/50 text-[8px] font-bold select-none">•</span>
|
||||||
</div>
|
<span className="text-[10.5px] font-bold leading-tight truncate max-w-[140px]">{league.name}</span>
|
||||||
<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-brand-primary" />
|
|
||||||
</div>
|
</div>
|
||||||
|
<SoccerBallIcon className="size-4 shrink-0 text-white/40 group-hover:text-brand-primary transition-colors" />
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* In-Play Strip */}
|
{/* In-Play Strip */}
|
||||||
<Button className="w-full bg-[#004d40] text-[#00bfa5] hover:bg-[#003d33] border-none py-2.5 h-auto text-[11px] font-black uppercase rounded-none tracking-[2px]">
|
<Button asChild className="w-full bg-[#004d40] text-[#00bfa5] hover:bg-[#003d33] border-none py-2.5 h-auto text-[11px] font-black uppercase rounded-none tracking-[2px]">
|
||||||
<span className="size-2 rounded-full bg-[#ff9800] mr-2 live-dot shadow-[0_0_8px_#ff9800]"></span>
|
<Link href="/live">
|
||||||
|
<span className="size-2 rounded-full bg-brand-primary mr-2 live-dot shadow-[0_0_8px_var(--brand-primary)]"></span>
|
||||||
IN-PLAY
|
IN-PLAY
|
||||||
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{/* Quick Filter Section */}
|
{/* Quick Filter Section */}
|
||||||
|
|
@ -75,7 +90,7 @@ export function SportsSidebar() {
|
||||||
{["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(
|
||||||
"text-[10px] py-1.5 font-bold transition-colors",
|
"text-[10px] py-1.5 font-bold transition-colors",
|
||||||
t === "All" ? "bg-[#333] text-white" : "bg-[#2a2a2a] text-white/50 hover:text-white"
|
t === "All" ? "bg-brand-surface-light text-white" : "bg-brand-surface text-white/50 hover:text-white"
|
||||||
)}>{t}</button>
|
)}>{t}</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -112,7 +127,7 @@ export function SportsSidebar() {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-[10px] font-bold text-white/40">{sport.count}</span>
|
<span className="text-[10px] font-bold text-white/40">{sport.count}</span>
|
||||||
<span className="text-[11px] text-white/20">⚽</span>
|
<SoccerBallIcon className="size-3.5 text-white/30 shrink-0" />
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
|
|
@ -123,17 +138,49 @@ export function SportsSidebar() {
|
||||||
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-brand-surface group">
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
type="button"
|
||||||
|
className="flex flex-col items-center justify-center py-4 h-auto rounded-none border-r border-border/10 hover:bg-brand-surface group"
|
||||||
|
onClick={() => {
|
||||||
|
const w = 1200
|
||||||
|
const h = 800
|
||||||
|
const left = typeof window !== "undefined" ? Math.max(0, (window.screen.width - w) / 2) : 0
|
||||||
|
const top = typeof window !== "undefined" ? Math.max(0, (window.screen.height - h) / 2) : 0
|
||||||
|
window.open(
|
||||||
|
"https://s5.sir.sportradar.com/betinaction/en",
|
||||||
|
"LiveScore",
|
||||||
|
`noopener,noreferrer,width=${w},height=${h},left=${left},top=${top},scrollbars=yes,resizable=yes`
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
>
|
||||||
<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>
|
<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-brand-surface group">
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
type="button"
|
||||||
|
className="flex flex-col items-center justify-center py-4 h-auto rounded-none border-r border-border/10 hover:bg-brand-surface group"
|
||||||
|
onClick={() => {
|
||||||
|
const w = 1200
|
||||||
|
const h = 800
|
||||||
|
const left = typeof window !== "undefined" ? Math.max(0, (window.screen.width - w) / 2) : 0
|
||||||
|
const top = typeof window !== "undefined" ? Math.max(0, (window.screen.height - h) / 2) : 0
|
||||||
|
window.open(
|
||||||
|
"https://statistics.betconstruct.com/#/en",
|
||||||
|
"Results",
|
||||||
|
`noopener,noreferrer,width=${w},height=${h},left=${left},top=${top},scrollbars=yes,resizable=yes`
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
>
|
||||||
<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>
|
<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-brand-surface group">
|
<Button variant="ghost" asChild className="flex flex-col items-center justify-center py-4 h-auto rounded-none hover:bg-brand-surface group">
|
||||||
|
<Link href="/print-odds" className="flex flex-col items-center justify-center">
|
||||||
<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>
|
<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>
|
||||||
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ const buttonVariants = cva(
|
||||||
ghost:
|
ghost:
|
||||||
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||||
link: "text-primary underline-offset-4 hover:underline",
|
link: "text-primary underline-offset-4 hover:underline",
|
||||||
"hs-primary": "bg-[#ff9800] text-black font-bold hover:bg-[#ffa726] rounded-none",
|
"hs-primary": "bg-brand-primary text-black font-bold hover:bg-brand-primary-hover rounded-none",
|
||||||
"hs-secondary": "bg-[#333] text-white hover:bg-[#444] border border-border/20 rounded-none",
|
"hs-secondary": "bg-brand-surface-light text-white hover:bg-[#404040] border border-border/20 rounded-none",
|
||||||
"hs-maroon": "bg-[#852222] text-white font-bold hover:bg-[#962d2d] rounded-none",
|
"hs-maroon": "bg-brand-accent text-white font-bold hover:opacity-90 rounded-none",
|
||||||
"hs-inplay": "bg-[#004242] text-[#ff9800] font-bold hover:bg-[#005252] border-y border-border/10 rounded-none",
|
"hs-inplay": "bg-[#004242] text-brand-primary font-bold hover:bg-[#005252] border-y border-border/10 rounded-none",
|
||||||
"hs-nav": "bg-[#1a1a1a] text-[#ff9800] font-bold hover:bg-[#222] border-r border-border/10 rounded-none",
|
"hs-nav": "bg-brand-bg text-brand-primary font-bold hover:bg-brand-surface border-r border-border/10 rounded-none",
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
"use client"
|
"use client";
|
||||||
|
|
||||||
import * as React from "react"
|
import * as React from "react";
|
||||||
import { cva, type VariantProps } from "class-variance-authority"
|
import { cva, type VariantProps } from "class-variance-authority";
|
||||||
import { Tabs as TabsPrimitive } from "radix-ui"
|
import { Tabs as TabsPrimitive } from "radix-ui";
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
function Tabs({
|
function Tabs({
|
||||||
className,
|
className,
|
||||||
|
|
@ -18,29 +18,30 @@ function Tabs({
|
||||||
orientation={orientation}
|
orientation={orientation}
|
||||||
className={cn(
|
className={cn(
|
||||||
"group/tabs flex gap-2 data-[orientation=horizontal]:flex-col",
|
"group/tabs flex gap-2 data-[orientation=horizontal]:flex-col",
|
||||||
className
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const tabsListVariants = cva(
|
const tabsListVariants = cva(
|
||||||
"rounded-lg p-[3px] group-data-[orientation=horizontal]/tabs:h-9 data-[variant=line]:rounded-none data-[variant=hs-home]:rounded-none data-[variant=hs-home]:bg-[#1a1a1a] data-[variant=hs-nav]:rounded-none data-[variant=hs-nav]:bg-[#1a1a1a] group/tabs-list text-muted-foreground inline-flex w-fit items-center justify-center group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col",
|
"rounded-lg p-[3px] group-data-[orientation=horizontal]/tabs:h-9 data-[variant=line]:rounded-none data-[variant=hs-home]:rounded-none data-[variant=hs-home]:bg-brand-bg data-[variant=hs-nav]:rounded-none data-[variant=hs-nav]:bg-brand-bg group/tabs-list text-muted-foreground inline-flex w-fit items-center justify-center group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col",
|
||||||
{
|
{
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default: "bg-muted",
|
default: "bg-muted",
|
||||||
line: "gap-1 bg-transparent",
|
line: "gap-1 bg-transparent",
|
||||||
"hs-home": "w-full gap-0 border border-border/20",
|
"hs-home": "w-full gap-0 border border-border/20",
|
||||||
"hs-nav": "w-full gap-0 border border-border/20 overflow-x-auto justify-start",
|
"hs-nav":
|
||||||
|
"w-full gap-0 border border-border/20 flex-wrap justify-start overflow-hidden min-h-14 h-auto py-1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
variant: "default",
|
variant: "default",
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
)
|
);
|
||||||
|
|
||||||
function TabsList({
|
function TabsList({
|
||||||
className,
|
className,
|
||||||
|
|
@ -55,7 +56,7 @@ function TabsList({
|
||||||
className={cn(tabsListVariants({ variant }), className)}
|
className={cn(tabsListVariants({ variant }), className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function TabsTrigger({
|
function TabsTrigger({
|
||||||
|
|
@ -69,14 +70,14 @@ function TabsTrigger({
|
||||||
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||||
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent",
|
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent",
|
||||||
"group-data-[variant=hs-home]/tabs-list:rounded-none group-data-[variant=hs-home]/tabs-list:h-12 group-data-[variant=hs-home]/tabs-list:text-[13px] group-data-[variant=hs-home]/tabs-list:font-extrabold group-data-[variant=hs-home]/tabs-list:uppercase group-data-[variant=hs-home]/tabs-list:data-[state=active]:bg-transparent group-data-[variant=hs-home]/tabs-list:data-[state=active]:text-white",
|
"group-data-[variant=hs-home]/tabs-list:rounded-none group-data-[variant=hs-home]/tabs-list:h-12 group-data-[variant=hs-home]/tabs-list:text-[13px] group-data-[variant=hs-home]/tabs-list:font-extrabold group-data-[variant=hs-home]/tabs-list:uppercase group-data-[variant=hs-home]/tabs-list:data-[state=active]:bg-transparent group-data-[variant=hs-home]/tabs-list:data-[state=active]:text-white",
|
||||||
"group-data-[variant=hs-nav]/tabs-list:rounded-none group-data-[variant=hs-nav]/tabs-list:flex-col group-data-[variant=hs-nav]/tabs-list:min-w-[70px] group-data-[variant=hs-nav]/tabs-list:py-2 group-data-[variant=hs-nav]/tabs-list:gap-1 group-data-[variant=hs-nav]/tabs-list:border-r group-data-[variant=hs-nav]/tabs-list:border-border/10 group-data-[variant=hs-nav]/tabs-list:data-[state=active]:bg-[#222]",
|
"group-data-[variant=hs-nav]/tabs-list:rounded-none group-data-[variant=hs-nav]/tabs-list:flex-col group-data-[variant=hs-nav]/tabs-list:min-w-[70px] group-data-[variant=hs-nav]/tabs-list:py-2 group-data-[variant=hs-nav]/tabs-list:gap-1 group-data-[variant=hs-nav]/tabs-list:border-r group-data-[variant=hs-nav]/tabs-list:border-border/10 group-data-[variant=hs-nav]/tabs-list:data-[state=active]:bg-brand-surface",
|
||||||
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 data-[state=active]:text-foreground",
|
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 data-[state=active]:text-foreground",
|
||||||
"after:bg-[#ff9800] after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-0 group-data-[orientation=horizontal]/tabs:after:h-[3px] group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100 group-data-[variant=hs-home]/tabs-list:data-[state=active]:after:opacity-100",
|
"after:bg-brand-primary after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-0 group-data-[orientation=horizontal]/tabs:after:h-[3px] group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100 group-data-[variant=hs-home]/tabs-list:data-[state=active]:after:opacity-100",
|
||||||
className
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function TabsContent({
|
function TabsContent({
|
||||||
|
|
@ -89,7 +90,7 @@ function TabsContent({
|
||||||
className={cn("flex-1 outline-none", className)}
|
className={cn("flex-1 outline-none", className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }
|
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user