"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()); export default function NextAuthComponent() { return ( ); } 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); } }; 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 (
{/* Logo */}
vibn
{/* Card */}
{/* Glows */}
Welcome back

Sign in and keep building.

{subtitle}

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

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

{ e.preventDefault(); void handleDevLocalSignIn(); }} style={{ display: "flex", gap: 8 }} > setDevSecret(e.target.value)} style={{ flex: 1, padding: "0 14px", height: "40px", borderRadius: "8px", background: "oklch(0.16 0.008 60)", border: "1px solid var(--hairline)", color: "var(--fg)", fontSize: "14px", outline: "none", }} />
)}
By continuing, you agree to Vibn's{" "} Terms of Service {" "} and{" "} Privacy Policy .
); }