import { useState, useRef } from "react" import { supabase } from "../lib/supabase" const G = "linear-gradient(135deg, #1d4ed8 0%, #0891b2 100%)" export default function AuthView({ onAuth }) { const [mode, setMode] = useState("login") const [email, setEmail] = useState("") const [password, setPassword] = useState("") const [loading, setLoading] = useState(false) const [error, setError] = useState("") const [message, setMessage] = useState("") const [showPassword, setShowPassword] = useState(false) const hideTimerRef = useRef(null) const togglePassword = () => { if (showPassword) { setShowPassword(false) clearTimeout(hideTimerRef.current) } else { setShowPassword(true) clearTimeout(hideTimerRef.current) hideTimerRef.current = setTimeout(() => setShowPassword(false), 7000) } } const handleSubmit = async (e) => { e.preventDefault() setLoading(true) setError("") setMessage("") try { if (mode === "reset") { const { error } = await supabase.auth.resetPasswordForEmail(email) if (error) throw error setMessage("Password reset link sent — check your email.") setMode("login") } else if (mode === "signup") { const { error } = await supabase.auth.signUp({ email, password }) if (error) throw error setMessage("Check your email for a confirmation link.") } else { const { data, error } = await supabase.auth.signInWithPassword({ email, password }) if (error) throw error onAuth(data.session) } } catch (e) { setError(e.message) } finally { setLoading(false) } } const isExtension = typeof chrome !== "undefined" && !!chrome.runtime?.id const handleGoogle = async () => { setLoading(true) setError("") if (isExtension) { try { const redirectUrl = chrome.identity.getRedirectURL() const { data, error } = await supabase.auth.signInWithOAuth({ provider: "google", options: { redirectTo: redirectUrl, skipBrowserRedirect: true }, }) if (error || !data?.url) throw error || new Error("No auth URL returned") chrome.identity.launchWebAuthFlow( { url: data.url, interactive: true }, async (callbackUrl) => { if (chrome.runtime.lastError || !callbackUrl) { setError("Google sign-in was cancelled or failed.") setLoading(false) return } const parsed = new URL(callbackUrl) const hashParams = new URLSearchParams(parsed.hash.substring(1)) // Tokens can be in hash (implicit) or query params (some Supabase versions) const accessToken = hashParams.get("access_token") || parsed.searchParams.get("access_token") const refreshToken = hashParams.get("refresh_token") || parsed.searchParams.get("refresh_token") || "" if (accessToken) { const { data: s, error: se } = await supabase.auth.setSession({ access_token: accessToken, refresh_token: refreshToken }) if (se) setError(se.message) else onAuth(s.session) setLoading(false) return } // PKCE: exchange authorization code const code = parsed.searchParams.get("code") || hashParams.get("code") if (code) { const { data: s, error: se } = await supabase.auth.exchangeCodeForSession(code) if (se) setError(se.message) else onAuth(s.session) setLoading(false) return } // Show the actual error from the URL if present const oauthError = hashParams.get("error_description") || parsed.searchParams.get("error_description") || hashParams.get("error") || parsed.searchParams.get("error") setError(oauthError || "Could not retrieve session from Google.") setLoading(false) } ) } catch (e) { setError(e.message) setLoading(false) } return } const { error } = await supabase.auth.signInWithOAuth({ provider: "google", options: { redirectTo: window.location.origin }, }) if (error) { setError(error.message) setLoading(false) } } return (
{mode === "login" ? "Sign in to access your sessions." : "Create an account to get started."}