diff --git a/client/pages/Login.tsx b/client/pages/Login.tsx index e9d2e6bc..33aa63fb 100644 --- a/client/pages/Login.tsx +++ b/client/pages/Login.tsx @@ -52,85 +52,6 @@ import { DialogClose, } from "@/components/ui/dialog"; -function OrgLogin() { - const [email, setEmail] = useState(""); - const [sending, setSending] = useState(false); - const [sent, setSent] = useState(null); - const [error, setError] = useState(null); - const isValid = /@aethex\.dev$/i.test(email); - return ( -
-
-
Aethex Login (org)
- - @aethex.dev - -
- {sent ? ( - - Check your inbox - - We sent a magic link to {email}. If email isn’t configured, a manual - link is shown below. - - {sent.startsWith("http") && ( -

- {sent} -

- )} -
- ) : null} - {error ? ( - - Request failed - {error} - - ) : null} -
-
- setEmail(e.target.value)} - /> -
- -
-
- ); -} - export default function Login() { const [isLoading, setIsLoading] = useState(false); const [isSignUp, setIsSignUp] = useState(false); @@ -198,106 +119,134 @@ export default function Login() { try { if (isSignUp) { const result = await signUp(email, password, { - id: "", - full_name: fullName, - user_type: "game_developer", - username: email.split("@")[0], + data: { + full_name: fullName, + }, }); - - if (result?.emailSent) { - setManualVerificationLink(null); - } else if (result?.verificationUrl) { - setManualVerificationLink(result.verificationUrl); - try { - if ( - typeof navigator !== "undefined" && - navigator.clipboard?.writeText - ) { - await navigator.clipboard.writeText(result.verificationUrl); - toastInfo({ - title: "Verification link copied", - description: - "We copied the manual verification link to your clipboard. Paste it into your browser to finish signup.", - }); - } else { - throw new Error("clipboard unsupported"); - } - } catch { - toastInfo({ - title: "Manual verification required", - description: - "Copy the link shown in the banner to verify your account.", - }); - } + 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 }); } - - setIsSignUp(false); } else { - await signIn(email, password); - // Do not navigate immediately; wait for auth state to update + const result = await signIn(email, password); + if (result?.user) { + const params = new URLSearchParams(location.search); + const next = params.get("next"); + const safeNext = next && next.startsWith("/") ? next : null; + navigate( + safeNext || + (result?.user_metadata?.profile_complete + ? "/dashboard" + : "/onboarding"), + { replace: true }, + ); + } } } catch (error: any) { - console.error("Authentication error:", error); + console.error("Auth error:", error); + const message = + error?.message || + (isSignUp ? "Failed to create account" : "Failed to sign in"); toastError({ - title: "Authentication failed", - description: - error?.message || "Something went wrong. Please try again.", + title: isSignUp ? "Signup failed" : "Login failed", + description: message, }); } finally { setIsLoading(false); } }; - const handleSocialLogin = async (provider: "github" | "google") => { - setIsLoading(true); + const handleSocialLogin = async (provider: string) => { try { await signInWithOAuth(provider); - } catch (error: any) { - console.error(`${provider} authentication error:`, error); - } finally { - setIsLoading(false); + } catch (error) { + console.error("OAuth error:", error); } }; const handleWeb3Login = async () => { - setIsLoading(true); try { - navigate("/web3-callback"); + 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 navigation error:", error); - setIsLoading(false); + console.error("Web3 error:", error); + toastError({ + title: "Web3 verification failed", + description: + error?.message || "Could not verify your wallet signature", + }); } }; - // Show loading screen only during form submission, not during auth context loading - if (isLoading && !loading) { - return ( - - ); - } - - // If auth context is still loading, show a different loading state if (loading) { - return ( - - ); + return ; } return ( <> -
-
-
-
-
- - Or continue with email - -
-
- - {/* Aethex Org Login (Magic Link) */} - - {/* Email/Password Form */}
{isSignUp && ( @@ -598,49 +533,6 @@ export default function Login() {
- - - - - Reset your password - - Enter the email associated with your account. We'll send a reset - link. - - -
- - setResetEmail(e.target.value)} - placeholder="you@example.com" - /> -
- - - - - - -
-
);