"use client"; import { signIn } from "next-auth/react"; import Link from "next/link"; import { useSearchParams } from "next/navigation"; import { Suspense, useState } from "react"; function authErrorMessage(code: string | null): string | null { if (!code) return null; if (code === "Callback") { return ( "Google could not complete sign-in. Most often: DATABASE_URL in vibn-frontend/.env.local must reach Postgres from " + "this machine (Coolify internal hostnames only work inside Docker). Use a public host/port, tunnel, or proxy; " + "then run npx prisma db push. Also confirm NEXTAUTH_URL matches the browser (http://localhost:3000) and " + "Google redirect URI http://localhost:3000/api/auth/callback/google. Dev check: GET /api/debug/prisma — see terminal for [next-auth] logs." ); } if (code === "Configuration") { return "Auth is misconfigured (check GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, NEXTAUTH_SECRET)."; } if (code === "AccessDenied") { return "Access was denied. You may need to be added as a test user if the OAuth app is in testing mode."; } return `Sign-in error: ${code}`; } const showDevLocalSignIn = process.env.NODE_ENV === "development" && Boolean(process.env.NEXT_PUBLIC_DEV_LOCAL_AUTH_EMAIL?.trim()); function NextAuthForm() { const [isLoading, setIsLoading] = useState(false); const [devSecret, setDevSecret] = useState(""); const searchParams = useSearchParams(); const callbackUrl = searchParams.get("callbackUrl") ?? "/auth"; const errorCode = searchParams.get("error"); const errorHint = authErrorMessage(errorCode); const handleGoogleSignIn = async () => { setIsLoading(true); try { await signIn("google", { callbackUrl }); } catch (error) { console.error("Google sign-in error:", error); setIsLoading(false); } }; const handleDevLocalSignIn = async () => { setIsLoading(true); try { await signIn("dev-local", { callbackUrl, password: devSecret, redirect: true, }); } catch (error) { console.error("Dev local sign-in error:", error); setIsLoading(false); } }; // Detect new-vs-returning purely from local search params; we // don't have a session at this render path, but the homepage // sends "Get started" links with `?new=1` and "Sign in" links // without it. Fall back to neutral copy that works for both. const isNewUser = searchParams.get("new") === "1"; const title = isNewUser ? "Create your account" : "Sign in or sign up"; const subtitle = isNewUser ? "Continue with Google to set up your Vibn workspace." : "Continue with Google. New here? An account is created automatically on first sign-in."; return (

{title}

{subtitle}

{errorHint && (
{errorHint}
)} {showDevLocalSignIn && (

Local only: sign in without Google as{" "} {process.env.NEXT_PUBLIC_DEV_LOCAL_AUTH_EMAIL}

{ e.preventDefault(); void handleDevLocalSignIn(); }} > setDevSecret(e.target.value)} className="justine-auth-dev-input" style={{ width: "100%", marginBottom: 10, padding: "10px 12px", borderRadius: 8, border: "1px solid rgba(0,0,0,0.12)", fontSize: 14, }} />
)}

By continuing, you agree to our{" "} Terms and Privacy Policy.

); } function NextAuthFallback() { return (

Loading…

); } export default function NextAuthComponent() { return ( }> ); }