login and signup
This commit is contained in:
parent
612bb9386b
commit
77944930d0
|
|
@ -65,7 +65,7 @@
|
|||
--border: #2a2a2a;
|
||||
--input: #222222;
|
||||
--ring: #ff9800;
|
||||
|
||||
|
||||
/* HarifSport specific */
|
||||
--hs-orange: #ff9800;
|
||||
--hs-maroon: #852222;
|
||||
|
|
@ -109,6 +109,7 @@
|
|||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
font-size: 13px;
|
||||
|
|
@ -117,9 +118,17 @@
|
|||
|
||||
/* HarifSport odds button animation */
|
||||
@keyframes odds-flash {
|
||||
0% { background-color: oklch(0.55 0.18 145); }
|
||||
50% { background-color: oklch(0.7 0.22 80); }
|
||||
100% { background-color: oklch(0.55 0.18 145); }
|
||||
0% {
|
||||
background-color: oklch(0.55 0.18 145);
|
||||
}
|
||||
|
||||
50% {
|
||||
background-color: oklch(0.7 0.22 80);
|
||||
}
|
||||
|
||||
100% {
|
||||
background-color: oklch(0.55 0.18 145);
|
||||
}
|
||||
}
|
||||
|
||||
.odds-selected {
|
||||
|
|
@ -128,22 +137,48 @@
|
|||
|
||||
/* Live pulse */
|
||||
@keyframes live-pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.4; }
|
||||
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
.live-dot {
|
||||
animation: live-pulse 1.2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Auth modal fade-in */
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px) scale(0.98);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fade-in 0.18s ease-out both;
|
||||
}
|
||||
|
||||
/* Scrollbar */
|
||||
::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
border-radius: 2px;
|
||||
|
|
|
|||
|
|
@ -2,55 +2,126 @@
|
|||
|
||||
import { useState } from "react"
|
||||
import Link from "next/link"
|
||||
import { useRouter } from "next/navigation"
|
||||
|
||||
export default function LoginPage() {
|
||||
const [username, setUsername] = useState("")
|
||||
const router = useRouter()
|
||||
const [phone, setPhone] = useState("")
|
||||
const [password, setPassword] = useState("")
|
||||
|
||||
return (
|
||||
<div className="max-w-sm mx-auto mt-8">
|
||||
<div className="bg-card border border-border rounded-lg overflow-hidden">
|
||||
<div className="bg-primary px-6 py-4">
|
||||
<h1 className="text-base font-black text-primary-foreground uppercase tracking-wide">Login</h1>
|
||||
<p className="text-[11px] text-primary-foreground/70 mt-0.5">Sign in to your Harifsport account</p>
|
||||
</div>
|
||||
<div className="p-6 space-y-4">
|
||||
<div>
|
||||
<label className="text-[11px] font-semibold text-muted-foreground uppercase block mb-1">Username</label>
|
||||
<input
|
||||
type="text"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
placeholder="Enter username"
|
||||
className="w-full bg-input border border-border rounded px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:border-primary transition-colors"
|
||||
/>
|
||||
/* Full-screen dark backdrop */
|
||||
<div
|
||||
className="fixed inset-0 z-50 flex items-center justify-center bg-black/70"
|
||||
onClick={() => router.back()}
|
||||
>
|
||||
{/* Modal card */}
|
||||
<div
|
||||
className="relative w-[420px] bg-[#3a3a3a] shadow-2xl"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Close button */}
|
||||
<button
|
||||
onClick={() => router.back()}
|
||||
className="absolute top-2 right-3 text-white/60 hover:text-white text-xl leading-none transition-colors z-10"
|
||||
aria-label="Close"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
|
||||
{/* Logo */}
|
||||
<div className="flex items-center justify-center py-5 border-b border-white/10 bg-[#2e2e2e]">
|
||||
<div className="flex items-center">
|
||||
{/* Red slashes */}
|
||||
<div className="flex gap-[3px] mr-2">
|
||||
{[0, 1, 2].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="w-[5px] h-[38px] bg-[#cc2222] -skew-x-12"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{/* HARIF box */}
|
||||
<div className="bg-[#852222] 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">
|
||||
HARIF
|
||||
</span>
|
||||
</div>
|
||||
{/* SPORT text */}
|
||||
<span className="text-2xl font-black text-[#ff9800] italic tracking-tighter ml-1 leading-none">
|
||||
SPORT
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<div className="text-center py-4">
|
||||
<h1 className="text-sm font-black text-white uppercase tracking-widest">
|
||||
LOGIN
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* Form */}
|
||||
<div className="px-8 pb-6 space-y-4">
|
||||
{/* Phone Number */}
|
||||
<div>
|
||||
<label className="text-[11px] font-semibold text-muted-foreground uppercase block mb-1">Password</label>
|
||||
<label className="block text-[11px] font-semibold text-white/80 mb-1">
|
||||
Phone Number
|
||||
</label>
|
||||
<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">
|
||||
ET +251
|
||||
</span>
|
||||
<input
|
||||
type="tel"
|
||||
value={phone}
|
||||
onChange={(e) => setPhone(e.target.value)}
|
||||
className="flex-1 bg-white border border-gray-300 px-3 py-2 text-sm text-[#333] placeholder:text-gray-400 focus:outline-none focus:border-[#ff9800]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Password */}
|
||||
<div>
|
||||
<label className="block text-[11px] font-semibold text-white/80 mb-1">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
placeholder="Enter password"
|
||||
className="w-full bg-input border border-border rounded px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:border-primary transition-colors"
|
||||
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]"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-[11px]">
|
||||
<label className="flex items-center gap-2 text-muted-foreground cursor-pointer">
|
||||
<input type="checkbox" className="rounded" />
|
||||
Remember me
|
||||
</label>
|
||||
<Link href="/reset-password" className="text-primary hover:underline">
|
||||
|
||||
{/* Forgot password */}
|
||||
<div className="text-right">
|
||||
<Link
|
||||
href="/reset-password"
|
||||
className="text-[11px] text-white/50 hover:text-[#ff9800] transition-colors"
|
||||
>
|
||||
Forgot password?
|
||||
</Link>
|
||||
</div>
|
||||
<button className="w-full bg-primary text-primary-foreground font-bold py-2.5 rounded uppercase text-sm hover:opacity-90 transition-opacity">
|
||||
Login
|
||||
|
||||
{/* Login button */}
|
||||
<button className="w-full bg-[#e6b800] hover:bg-[#ffcc00] text-black font-black py-3 uppercase text-sm tracking-widest transition-colors">
|
||||
LOGIN
|
||||
</button>
|
||||
<p className="text-center text-[11px] text-muted-foreground">
|
||||
|
||||
{/* Support link */}
|
||||
<p className="text-center text-[12px] text-white/60">
|
||||
<Link href="/support" className="hover:text-white transition-colors">
|
||||
Support
|
||||
</Link>
|
||||
</p>
|
||||
|
||||
{/* Register link */}
|
||||
<p className="text-center text-[11px] text-white/50">
|
||||
Don't have an account?{" "}
|
||||
<Link href="/register" className="text-primary hover:underline font-semibold">
|
||||
Register now
|
||||
<Link href="/register" className="text-[#ff9800] hover:underline font-semibold">
|
||||
Register
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,107 +2,147 @@
|
|||
|
||||
import { useState } from "react"
|
||||
import Link from "next/link"
|
||||
import { useRouter } from "next/navigation"
|
||||
|
||||
export default function RegisterPage() {
|
||||
const [step, setStep] = useState(1)
|
||||
const router = useRouter()
|
||||
const [phone, setPhone] = useState("")
|
||||
const [password, setPassword] = useState("")
|
||||
const [repeatPassword, setRepeatPassword] = useState("")
|
||||
const [ageConfirmed, setAgeConfirmed] = useState(false)
|
||||
|
||||
return (
|
||||
<div className="max-w-md mx-auto mt-8">
|
||||
<div className="bg-card border border-border rounded-lg overflow-hidden">
|
||||
<div className="bg-primary px-6 py-4">
|
||||
<h1 className="text-base font-black text-primary-foreground uppercase tracking-wide">Create Account</h1>
|
||||
<p className="text-[11px] text-primary-foreground/70 mt-0.5">Join Harifsport today</p>
|
||||
/* Full-screen dark backdrop */
|
||||
<div
|
||||
className="fixed inset-0 z-50 flex items-center justify-center bg-black/70"
|
||||
onClick={() => router.back()}
|
||||
>
|
||||
{/* Modal card — stop clicks propagating to backdrop */}
|
||||
<div
|
||||
className="relative w-[420px] bg-[#3a3a3a] shadow-2xl"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Close button */}
|
||||
<button
|
||||
onClick={() => router.back()}
|
||||
className="absolute top-2 right-3 text-white/60 hover:text-white text-xl leading-none transition-colors z-10"
|
||||
aria-label="Close"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
|
||||
{/* Logo */}
|
||||
<div className="flex items-center justify-center py-5 border-b border-white/10 bg-[#2e2e2e]">
|
||||
<div className="flex items-center">
|
||||
{/* Red slashes */}
|
||||
<div className="flex gap-[3px] mr-2">
|
||||
{[0, 1, 2].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="w-[5px] h-[38px] bg-[#cc2222] -skew-x-12"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{/* HARIF box */}
|
||||
<div className="bg-[#852222] 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">
|
||||
HARIF
|
||||
</span>
|
||||
</div>
|
||||
{/* SPORT text */}
|
||||
<span className="text-2xl font-black text-[#ff9800] italic tracking-tighter ml-1 leading-none">
|
||||
SPORT
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Steps */}
|
||||
<div className="flex border-b border-border">
|
||||
{["Personal Info", "Account Details", "Verification"].map((s, i) => (
|
||||
<div
|
||||
key={s}
|
||||
className={`flex-1 py-2 text-center text-[10px] font-semibold uppercase transition-colors ${
|
||||
i + 1 === step ? "bg-muted text-primary border-b-2 border-primary" :
|
||||
i + 1 < step ? "text-muted-foreground bg-primary/5" : "text-muted-foreground"
|
||||
}`}
|
||||
>
|
||||
{i + 1}. {s}
|
||||
</div>
|
||||
))}
|
||||
{/* Title */}
|
||||
<div className="text-center py-4">
|
||||
<h1 className="text-sm font-black text-white uppercase tracking-widest">
|
||||
REGISTER
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className="p-6 space-y-4">
|
||||
{step === 1 && (
|
||||
<>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label className="text-[11px] font-semibold text-muted-foreground uppercase block mb-1">First Name</label>
|
||||
<input type="text" placeholder="First name" className="w-full bg-input border border-border rounded px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:border-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-[11px] font-semibold text-muted-foreground uppercase block mb-1">Last Name</label>
|
||||
<input type="text" placeholder="Last name" className="w-full bg-input border border-border rounded px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:border-primary" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-[11px] font-semibold text-muted-foreground uppercase block mb-1">Phone Number</label>
|
||||
<input type="tel" placeholder="+251 xxx xxx xxxx" className="w-full bg-input border border-border rounded px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:border-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-[11px] font-semibold text-muted-foreground uppercase block mb-1">Date of Birth</label>
|
||||
<input type="date" className="w-full bg-input border border-border rounded px-3 py-2 text-sm text-foreground focus:outline-none focus:border-primary" />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{step === 2 && (
|
||||
<>
|
||||
<div>
|
||||
<label className="text-[11px] font-semibold text-muted-foreground uppercase block mb-1">Username</label>
|
||||
<input type="text" placeholder="Choose a username" className="w-full bg-input border border-border rounded px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:border-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-[11px] font-semibold text-muted-foreground uppercase block mb-1">Email</label>
|
||||
<input type="email" placeholder="your@email.com" className="w-full bg-input border border-border rounded px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:border-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-[11px] font-semibold text-muted-foreground uppercase block mb-1">Password</label>
|
||||
<input type="password" placeholder="Min 8 characters" className="w-full bg-input border border-border rounded px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:border-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-[11px] font-semibold text-muted-foreground uppercase block mb-1">Confirm Password</label>
|
||||
<input type="password" placeholder="Repeat password" className="w-full bg-input border border-border rounded px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:border-primary" />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{step === 3 && (
|
||||
<div className="text-center py-4">
|
||||
<div className="text-4xl mb-3">✅</div>
|
||||
<h3 className="font-bold text-foreground mb-2">Account Created!</h3>
|
||||
<p className="text-[11px] text-muted-foreground">Please verify your phone number to start betting.</p>
|
||||
<input type="text" placeholder="Enter OTP code" className="mt-4 w-full bg-input border border-border rounded px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:border-primary text-center tracking-widest" maxLength={6} />
|
||||
{/* Form */}
|
||||
<div className="px-8 pb-6 space-y-4">
|
||||
{/* Phone Number */}
|
||||
<div>
|
||||
<label className="block text-[11px] font-semibold text-white/80 mb-1">
|
||||
Phone Number
|
||||
</label>
|
||||
<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">
|
||||
ET +251
|
||||
</span>
|
||||
<input
|
||||
type="tel"
|
||||
value={phone}
|
||||
onChange={(e) => setPhone(e.target.value)}
|
||||
className="flex-1 bg-white border border-gray-300 px-3 py-2 text-sm text-[#333] placeholder:text-gray-400 focus:outline-none focus:border-[#ff9800]"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex gap-3">
|
||||
{step > 1 && (
|
||||
<button onClick={() => setStep(step - 1)} className="flex-1 bg-secondary text-secondary-foreground font-semibold py-2.5 rounded uppercase text-sm hover:bg-muted transition-colors">
|
||||
Back
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={() => step < 3 ? setStep(step + 1) : null}
|
||||
className="flex-1 bg-primary text-primary-foreground font-bold py-2.5 rounded uppercase text-sm hover:opacity-90 transition-opacity"
|
||||
>
|
||||
{step === 3 ? "Verify & Start" : "Next"}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{step === 1 && (
|
||||
<p className="text-center text-[11px] text-muted-foreground">
|
||||
Already have an account?{" "}
|
||||
<Link href="/login" className="text-primary hover:underline font-semibold">Login</Link>
|
||||
</p>
|
||||
)}
|
||||
{/* Password */}
|
||||
<div>
|
||||
<label className="block text-[11px] font-semibold text-white/80 mb-1">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
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]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Repeat Password */}
|
||||
<div>
|
||||
<label className="block text-[11px] font-semibold text-white/80 mb-1">
|
||||
Repeat Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
value={repeatPassword}
|
||||
onChange={(e) => setRepeatPassword(e.target.value)}
|
||||
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]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Age confirmation */}
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={ageConfirmed}
|
||||
onChange={(e) => setAgeConfirmed(e.target.checked)}
|
||||
className="w-4 h-4 accent-[#ff9800]"
|
||||
/>
|
||||
<span className="text-[12px] text-white/80">
|
||||
I confirm I'm over 21 years old
|
||||
</span>
|
||||
</label>
|
||||
|
||||
{/* Register button */}
|
||||
<button className="w-full bg-[#e6b800] hover:bg-[#ffcc00] text-black font-black py-3 uppercase text-sm tracking-widest transition-colors">
|
||||
REGISTER
|
||||
</button>
|
||||
|
||||
{/* Support link */}
|
||||
<p className="text-center text-[12px] text-white/60">
|
||||
<Link href="/support" className="hover:text-white transition-colors">
|
||||
Support
|
||||
</Link>
|
||||
</p>
|
||||
|
||||
{/* Login link */}
|
||||
<p className="text-center text-[11px] text-white/50">
|
||||
Already have an account?{" "}
|
||||
<Link href="/login" className="text-[#ff9800] hover:underline font-semibold">
|
||||
Login
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
215
components/layout/auth-modal.tsx
Normal file
215
components/layout/auth-modal.tsx
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
"use client"
|
||||
|
||||
import { useState, useEffect, useCallback } from "react"
|
||||
import Link from "next/link"
|
||||
|
||||
type Mode = "login" | "register"
|
||||
|
||||
function Logo() {
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
{/* Red slashes */}
|
||||
<div className="flex gap-[3px] mr-2">
|
||||
{[0, 1, 2].map((i) => (
|
||||
<div key={i} className="w-[5px] h-[38px] bg-[#cc2222] -skew-x-12" />
|
||||
))}
|
||||
</div>
|
||||
{/* HARIF box */}
|
||||
<div className="bg-[#852222] 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">
|
||||
HARIF
|
||||
</span>
|
||||
</div>
|
||||
{/* SPORT text */}
|
||||
<span className="text-2xl font-black text-[#ff9800] italic tracking-tighter ml-1 leading-none">
|
||||
SPORT
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
interface AuthModalProps {
|
||||
open: boolean
|
||||
defaultMode: Mode
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
export function AuthModal({ open, defaultMode, onClose }: AuthModalProps) {
|
||||
const [mode, setMode] = useState<Mode>(defaultMode)
|
||||
const [phone, setPhone] = useState("")
|
||||
const [password, setPassword] = useState("")
|
||||
const [repeatPassword, setRepeatPassword] = useState("")
|
||||
const [ageConfirmed, setAgeConfirmed] = useState(false)
|
||||
|
||||
// Sync mode if parent changes defaultMode while open
|
||||
useEffect(() => {
|
||||
if (open) setMode(defaultMode)
|
||||
}, [defaultMode, open])
|
||||
|
||||
// Close on Escape
|
||||
const handleKey = useCallback(
|
||||
(e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") onClose()
|
||||
},
|
||||
[onClose]
|
||||
)
|
||||
useEffect(() => {
|
||||
if (open) window.addEventListener("keydown", handleKey)
|
||||
return () => window.removeEventListener("keydown", handleKey)
|
||||
}, [open, handleKey])
|
||||
|
||||
if (!open) return null
|
||||
|
||||
return (
|
||||
<div
|
||||
className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/70"
|
||||
onClick={onClose}
|
||||
>
|
||||
<div
|
||||
className="relative w-[420px] bg-[#3a3a3a] shadow-2xl animate-fade-in"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Close button */}
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="absolute top-2 right-3 text-white/60 hover:text-white text-xl leading-none transition-colors z-10"
|
||||
aria-label="Close"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
|
||||
{/* Logo */}
|
||||
<div className="flex items-center justify-center py-5 border-b border-white/10 bg-[#2e2e2e]">
|
||||
<Logo />
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<div className="text-center py-4">
|
||||
<h2 className="text-sm font-black text-white uppercase tracking-widest">
|
||||
{mode === "login" ? "LOGIN" : "REGISTER"}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
{/* Form */}
|
||||
<div className="px-8 pb-6 space-y-4">
|
||||
{/* Phone Number */}
|
||||
<div>
|
||||
<label className="block text-[11px] font-semibold text-white/80 mb-1">
|
||||
Phone Number
|
||||
</label>
|
||||
<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">
|
||||
ET +251
|
||||
</span>
|
||||
<input
|
||||
type="tel"
|
||||
value={phone}
|
||||
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]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Password */}
|
||||
<div>
|
||||
<label className="block text-[11px] font-semibold text-white/80 mb-1">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
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]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Repeat Password (register only) */}
|
||||
{mode === "register" && (
|
||||
<div>
|
||||
<label className="block text-[11px] font-semibold text-white/80 mb-1">
|
||||
Repeat Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
value={repeatPassword}
|
||||
onChange={(e) => setRepeatPassword(e.target.value)}
|
||||
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]"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Age confirmation (register only) */}
|
||||
{mode === "register" && (
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={ageConfirmed}
|
||||
onChange={(e) => setAgeConfirmed(e.target.checked)}
|
||||
className="w-4 h-4 accent-[#ff9800]"
|
||||
/>
|
||||
<span className="text-[12px] text-white/80">
|
||||
I confirm I'm over 21 years old
|
||||
</span>
|
||||
</label>
|
||||
)}
|
||||
|
||||
{/* Forgot password (login only) */}
|
||||
{mode === "login" && (
|
||||
<div className="text-right -mt-2">
|
||||
<Link
|
||||
href="/reset-password"
|
||||
className="text-[11px] text-white/50 hover:text-[#ff9800] transition-colors"
|
||||
onClick={onClose}
|
||||
>
|
||||
Forgot password?
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Submit button */}
|
||||
<button className="w-full bg-[#e6b800] hover:bg-[#ffcc00] text-black font-black py-3 uppercase text-sm tracking-widest transition-colors">
|
||||
{mode === "login" ? "LOGIN" : "REGISTER"}
|
||||
</button>
|
||||
|
||||
{/* Support link */}
|
||||
<p className="text-center text-[12px] text-white/60">
|
||||
<Link
|
||||
href="/support"
|
||||
className="hover:text-white transition-colors"
|
||||
onClick={onClose}
|
||||
>
|
||||
Support
|
||||
</Link>
|
||||
</p>
|
||||
|
||||
{/* Toggle mode */}
|
||||
<p className="text-center text-[11px] text-white/50">
|
||||
{mode === "login" ? (
|
||||
<>
|
||||
Don't have an account?{" "}
|
||||
<button
|
||||
className="text-[#ff9800] hover:underline font-semibold"
|
||||
onClick={() => setMode("register")}
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Already have an account?{" "}
|
||||
<button
|
||||
className="text-[#ff9800] hover:underline font-semibold"
|
||||
onClick={() => setMode("login")}
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,24 +1,45 @@
|
|||
"use client"
|
||||
|
||||
import { usePathname } from "next/navigation"
|
||||
import { useState } from "react"
|
||||
import { SiteHeader } from "@/components/layout/site-header"
|
||||
import { SportsSidebar } from "@/components/layout/sports-sidebar"
|
||||
import { RightPanel } from "@/components/layout/right-panel"
|
||||
import { SiteFooter } from "@/components/layout/site-footer"
|
||||
import { AuthModal } from "@/components/layout/auth-modal"
|
||||
|
||||
type AuthMode = "login" | "register"
|
||||
|
||||
export default function LayoutClientWrapper({ children }: { children: React.ReactNode }) {
|
||||
const pathname = usePathname()
|
||||
const isLivePage = pathname === "/live"
|
||||
|
||||
const [authOpen, setAuthOpen] = useState(false)
|
||||
const [authMode, setAuthMode] = useState<AuthMode>("login")
|
||||
|
||||
function openAuth(mode: AuthMode) {
|
||||
setAuthMode(mode)
|
||||
setAuthOpen(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col">
|
||||
<SiteHeader />
|
||||
<SiteHeader
|
||||
onLoginClick={() => openAuth("login")}
|
||||
onRegisterClick={() => openAuth("register")}
|
||||
/>
|
||||
<div className="flex w-full flex-1 gap-0">
|
||||
{!isLivePage && <SportsSidebar />}
|
||||
<main className="flex-1 px-2 py-3 min-w-0">{children}</main>
|
||||
<RightPanel />
|
||||
</div>
|
||||
<SiteFooter />
|
||||
|
||||
<AuthModal
|
||||
open={authOpen}
|
||||
defaultMode={authMode}
|
||||
onClose={() => setAuthOpen(false)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,12 @@ const extraNavItems = [
|
|||
{ href: "/promo", label: "PROMO" },
|
||||
]
|
||||
|
||||
export function SiteHeader() {
|
||||
interface SiteHeaderProps {
|
||||
onLoginClick?: () => void
|
||||
onRegisterClick?: () => void
|
||||
}
|
||||
|
||||
export function SiteHeader({ onLoginClick, onRegisterClick }: SiteHeaderProps) {
|
||||
const pathname = usePathname()
|
||||
const isLivePage = pathname === "/live"
|
||||
const [time, setTime] = useState("")
|
||||
|
|
@ -43,7 +48,7 @@ export function SiteHeader() {
|
|||
<div className="bg-[#1a1a1a] px-3 py-1 flex items-center justify-between text-[11px] text-white">
|
||||
<div className="flex items-center gap-4">
|
||||
<button className="flex items-center gap-1.5 hover:text-primary transition-colors">
|
||||
<img src="https://flagcdn.com/w20/gb.png" srcSet="https://flagcdn.com/w40/gb.png 2x" width="16" alt="English" className="rounded-sm" />
|
||||
<img src="https://flagcdn.com/w20/gb.png" width="16" alt="English" className="rounded-sm" />
|
||||
<span className="font-bold flex items-center gap-1">en <span className="text-[8px]">▼</span></span>
|
||||
</button>
|
||||
<div className="flex items-center gap-2 font-bold">
|
||||
|
|
@ -57,11 +62,17 @@ export function SiteHeader() {
|
|||
<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" />
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<Button asChild className="bg-[#e67e22] text-white hover:bg-[#d35400] px-5 h-7 text-[11px] font-bold rounded-none uppercase">
|
||||
<Link href="/login">Login</Link>
|
||||
<Button
|
||||
onClick={onLoginClick}
|
||||
className="bg-[#e67e22] text-white hover:bg-[#d35400] px-5 h-7 text-[11px] font-bold rounded-none uppercase"
|
||||
>
|
||||
Login
|
||||
</Button>
|
||||
<Button asChild className="bg-[#d35400] text-white hover:bg-[#c0392b] px-5 h-7 text-[11px] font-bold rounded-none uppercase">
|
||||
<Link href="/register">Sign Up</Link>
|
||||
<Button
|
||||
onClick={onRegisterClick}
|
||||
className="bg-[#d35400] text-white hover:bg-[#c0392b] px-5 h-7 text-[11px] font-bold rounded-none uppercase"
|
||||
>
|
||||
Sign Up
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user