218 lines
7.1 KiB
TypeScript
218 lines
7.1 KiB
TypeScript
"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-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">
|
||
HARIF
|
||
</span>
|
||
</div>
|
||
{/* SPORT text */}
|
||
<span className="text-2xl font-black text-brand-primary 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-[280px] bg-brand-surface-light shadow-2xl animate-fade-in"
|
||
onClick={(e) => e.stopPropagation()}
|
||
>
|
||
{/* Close button */}
|
||
<button
|
||
onClick={onClose}
|
||
className="absolute top-1 right-2 text-white/60 hover:text-white text-lg leading-none transition-colors z-10"
|
||
aria-label="Close"
|
||
>
|
||
×
|
||
</button>
|
||
|
||
{/* Logo */}
|
||
<div className="flex items-center justify-center py-4 border-b border-white/10 bg-brand-surface">
|
||
<div className="scale-75 origin-center">
|
||
<Logo />
|
||
</div>
|
||
</div>
|
||
|
||
{/* Title */}
|
||
<div className="text-center py-3">
|
||
<h2 className="text-[12px] font-black text-white uppercase tracking-widest">
|
||
{mode === "login" ? "LOGIN" : "REGISTER"}
|
||
</h2>
|
||
</div>
|
||
|
||
{/* Form */}
|
||
<div className="px-4 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-[11px] font-bold px-1.5 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-brand-primary"
|
||
/>
|
||
</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-brand-primary"
|
||
/>
|
||
</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-brand-primary"
|
||
/>
|
||
</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-brand-primary"
|
||
/>
|
||
<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-brand-primary transition-colors"
|
||
onClick={onClose}
|
||
>
|
||
Forgot password?
|
||
</Link>
|
||
</div>
|
||
)}
|
||
|
||
{/* Submit button */}
|
||
<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"}
|
||
</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-brand-primary hover:underline font-semibold"
|
||
onClick={() => setMode("register")}
|
||
>
|
||
Register
|
||
</button>
|
||
</>
|
||
) : (
|
||
<>
|
||
Already have an account?{" "}
|
||
<button
|
||
className="text-brand-primary hover:underline font-semibold"
|
||
onClick={() => setMode("login")}
|
||
>
|
||
Login
|
||
</button>
|
||
</>
|
||
)}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|