Spaces:
Sleeping
Sleeping
| import React, { useState, useEffect } from "react" | |
| import { useAuth } from "../services/authService" | |
| export default function SignInPage() { | |
| const [username, setUsername] = useState("") | |
| const [password, setPassword] = useState("") | |
| const [error, setError] = useState("") | |
| const { login, isAuthenticated, isLoading } = useAuth() | |
| useEffect(() => { | |
| // Redirect if already authenticated | |
| if (isAuthenticated) { | |
| window.location.href = "/" | |
| } | |
| }, [isAuthenticated]) | |
| const handleSubmit = async (e: React.FormEvent) => { | |
| e.preventDefault() | |
| setError("") | |
| const result = await login({ username, password }) | |
| if (!result.success) { | |
| setError(result.error || "Invalid credentials") | |
| } else { | |
| // Redirect to main app | |
| window.location.href = "/" | |
| } | |
| } | |
| // Show loading spinner if checking auth state | |
| if (isLoading) { | |
| return ( | |
| <div className="min-h-screen flex items-center justify-center bg-gray-900"> | |
| <div className="text-white">Loading...</div> | |
| </div> | |
| ) | |
| } | |
| return ( | |
| <div className="min-h-screen flex items-center justify-center bg-gray-900"> | |
| <div className="max-w-md w-full space-y-8 p-8"> | |
| <div> | |
| <h2 className="mt-6 text-center text-3xl font-extrabold text-white"> | |
| ACE UI Login | |
| </h2> | |
| <p className="mt-2 text-center text-sm text-gray-400"> | |
| Enter your credentials to access the dashboard | |
| </p> | |
| </div> | |
| <form className="mt-8 space-y-6" onSubmit={handleSubmit}> | |
| <div className="space-y-4"> | |
| <div> | |
| <label htmlFor="username" className="sr-only"> | |
| Username | |
| </label> | |
| <input | |
| id="username" | |
| name="username" | |
| type="text" | |
| required | |
| className="relative block w-full px-3 py-2 border border-gray-600 rounded-md placeholder-gray-400 text-white bg-gray-800 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm" | |
| placeholder="Username" | |
| value={username} | |
| onChange={(e) => setUsername(e.target.value)} | |
| /> | |
| </div> | |
| <div> | |
| <label htmlFor="password" className="sr-only"> | |
| Password | |
| </label> | |
| <input | |
| id="password" | |
| name="password" | |
| type="password" | |
| required | |
| className="relative block w-full px-3 py-2 border border-gray-600 rounded-md placeholder-gray-400 text-white bg-gray-800 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm" | |
| placeholder="Password" | |
| value={password} | |
| onChange={(e) => setPassword(e.target.value)} | |
| /> | |
| </div> | |
| </div> | |
| {error && ( | |
| <div className="text-red-400 text-sm text-center">{error}</div> | |
| )} | |
| <div> | |
| <button | |
| type="submit" | |
| disabled={isLoading} | |
| className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed" | |
| > | |
| {isLoading ? "Signing in..." : "Sign in"} | |
| </button> | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| ) | |
| } |