Login.tsx (1980B)
1 import { useState, type FormEvent } from "react"; 2 import { useAuthStore } from "../../store/auth"; 3 4 export function Login() { 5 const { login, error, loading } = useAuthStore(); 6 const [password, setPassword] = useState(""); 7 8 const handleSubmit = async (e: FormEvent) => { 9 e.preventDefault(); 10 if (!password.trim()) return; 11 await login(password); 12 }; 13 14 return ( 15 <div className="flex min-h-screen items-center justify-center bg-gray-950"> 16 <div className="w-full max-w-sm rounded-xl border border-gray-800 bg-gray-900 p-8 shadow-2xl"> 17 <h1 className="mb-6 text-center text-2xl font-bold text-gray-100"> 18 Theo Agent Dashboard 19 </h1> 20 21 <form onSubmit={handleSubmit} className="space-y-4"> 22 <div> 23 <label 24 htmlFor="password" 25 className="mb-1 block text-sm font-medium text-gray-300" 26 > 27 Password 28 </label> 29 <input 30 id="password" 31 type="password" 32 value={password} 33 onChange={(e) => setPassword(e.target.value)} 34 className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-100 placeholder-gray-500 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" 35 placeholder="Enter password" 36 autoFocus 37 /> 38 </div> 39 40 {error && ( 41 <div className="rounded-lg bg-red-900/50 px-3 py-2 text-sm text-red-300"> 42 {error} 43 </div> 44 )} 45 46 <button 47 type="submit" 48 disabled={loading || !password.trim()} 49 className="w-full rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors" 50 > 51 {loading ? "Signing in..." : "Sign In"} 52 </button> 53 </form> 54 </div> 55 </div> 56 ); 57 }