import { useState, useEffect } from "react"; import { useNavigate, Link, useLocation } from "react-router-dom"; import { aethexUserService } from "@/lib/aethex-database-adapter"; import { useAuth } from "@/contexts/AuthContext"; import { useAethexToast } from "@/hooks/use-aethex-toast"; import Layout from "@/components/Layout"; import SEO from "@/components/SEO"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Badge } from "@/components/ui/badge"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import LoadingScreen from "@/components/LoadingScreen"; import { LogIn, ArrowRight, Shield, Sparkles, Github, Mail, Lock, User, Info, Wallet, } from "lucide-react"; const DiscordIcon = () => ( ); import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, } from "@/components/ui/dialog"; export default function Login() { const [isLoading, setIsLoading] = useState(false); const [isSignUp, setIsSignUp] = useState(false); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [fullName, setFullName] = useState(""); const [manualVerificationLink, setManualVerificationLink] = useState< string | null >(null); const [showReset, setShowReset] = useState(false); const [resetEmail, setResetEmail] = useState(""); const [errorFromUrl, setErrorFromUrl] = useState(null); const navigate = useNavigate(); const location = useLocation(); const { signIn, signUp, signInWithOAuth, user, loading, profileComplete, requestPasswordReset, } = useAuth(); const { info: toastInfo, error: toastError } = useAethexToast(); // Check for error messages from URL query parameters (e.g., from OAuth callbacks) useEffect(() => { const params = new URLSearchParams(location.search); const errorType = params.get("error"); const errorMessage = params.get("message"); if (errorType && errorMessage) { setErrorFromUrl(decodeURIComponent(errorMessage)); // Show in toast as well if (errorType === "account_exists") { toastError({ title: "Account Already Exists", description: errorMessage, }); } else if (errorType === "auth_create") { toastError({ title: "Authentication Error", description: errorMessage, }); } } }, [location.search, toastError]); // After auth resolves and a user exists, navigate to next path or dashboard useEffect(() => { if (!loading && user) { const params = new URLSearchParams(location.search); const next = params.get("next"); // Check if there's an OAuth redirect destination stored (e.g., from staff login) const oauthRedirect = sessionStorage.getItem("oauth_redirect_to"); const redirectDest = (next && next.startsWith("/") ? next : null) || oauthRedirect || (profileComplete ? "/dashboard" : "/onboarding"); // Clear the stored redirect after using it if (oauthRedirect) { sessionStorage.removeItem("oauth_redirect_to"); } navigate(redirectDest, { replace: true, }); } }, [user, loading, profileComplete, navigate, location.search]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setIsLoading(true); try { if (isSignUp) { const result = await signUp(email, password, { data: { full_name: fullName, }, }); if (result?.user) { toastInfo({ title: "Account created", description: result?.identities?.length === 0 ? "Please verify your email to log in" : "Redirecting to onboarding...", }); await aethexUserService.ensureUserProfile(result.user); navigate("/onboarding", { replace: true }); } } else { // Sign in with email/password const result = await signIn(email, password); if (result?.user) { // Don't navigate immediately - let Auth context update and the useEffect below handle redirect // This ensures profile data is fetched and profileComplete is properly calculated toastInfo({ title: "Signing you in", description: "Redirecting...", }); } } } catch (error: any) { console.error("Auth error:", error); const message = error?.message || (isSignUp ? "Failed to create account" : "Failed to sign in"); toastError({ title: isSignUp ? "Signup failed" : "Login failed", description: message, }); } finally { setIsLoading(false); } }; const handleSocialLogin = async (provider: string) => { try { await signInWithOAuth(provider); } catch (error) { console.error("OAuth error:", error); } }; const handleWeb3Login = async () => { try { const nonce = await fetch("/api/web3/nonce", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ address: "", }), }) .then((r) => (r.ok ? r.json() : null)) .catch(() => null); if (!nonce?.nonce) { toastError({ title: "Web3 login unavailable", description: "Please try again later", }); return; } const message = `Sign this message to verify your Ethereum wallet:\n\nNonce: ${nonce.nonce}`; const address = (window as any).ethereum?.selectedAddress; if (!address || !(window as any).ethereum) { toastError({ title: "Wallet not connected", description: "Please install MetaMask or another Ethereum wallet extension", }); return; } const signature = await (window as any).ethereum.request({ method: "personal_sign", params: [message, address], }); const result = await fetch("/api/web3/verify", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ address, nonce: nonce.nonce, signature, redirectTo: window.location.origin + (profileComplete ? "/dashboard" : "/onboarding"), }), }) .then((r) => (r.ok ? r.json() : null)) .catch(() => null); if (result?.url) { window.location.href = result.url; } } catch (error: any) { console.error("Web3 error:", error); toastError({ title: "Web3 verification failed", description: error?.message || "Could not verify your wallet signature", }); } }; if (loading) { return ; } return ( <>
{/* Floating particles effect */}
{[...Array(20)].map((_, i) => (
))}
{isSignUp ? "Create Account" : "Welcome Back"} {isSignUp ? "Create your AeThex account to get started" : "Sign in to your AeThex account to access the dashboard"}
Secure Login
{errorFromUrl ? ( Error {errorFromUrl} ) : null} {manualVerificationLink ? ( Manual verification required

We couldn't send the verification email automatically. Use the link below to confirm your account:

{manualVerificationLink}

) : null} {/* Social Login Buttons */}
{/* Email/Password Form */}
{isSignUp && (
setFullName(e.target.value)} placeholder="Enter your full name" className="pl-10 bg-background/50 border-border/50 focus:border-aethex-400" required={isSignUp} />
)}
setEmail(e.target.value)} placeholder="Enter your email" className="pl-10 bg-background/50 border-border/50 focus:border-aethex-400" required />
setPassword(e.target.value)} placeholder={ isSignUp ? "Create a password" : "Enter your password" } className="pl-10 bg-background/50 border-border/50 focus:border-aethex-400" required minLength={isSignUp ? 6 : undefined} />
{isSignUp && (

Password must be at least 6 characters long

)}
{!isSignUp && (
)}

{isSignUp ? "Already have an account?" : "Don't have an account?"}{" "}

{/* Security Notice */}

🔒 Your data is protected with enterprise-grade security

); }