"use client"; import { useState, useRef, useEffect } from "react"; import { useAuth } from "@/lib/auth"; export function AuthButton({ onViewProfile }: { onViewProfile?: (handle: string) => void }) { const { isAuthenticated, isLoading, session, login, logout } = useAuth(); const [showModal, setShowModal] = useState(false); const [showDropdown, setShowDropdown] = useState(false); const [handle, setHandle] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const [error, setError] = useState(""); const dropdownRef = useRef(null); // Close dropdown on outside click useEffect(() => { if (!showDropdown) return; const handleClickOutside = (e: MouseEvent) => { if ( dropdownRef.current && !dropdownRef.current.contains(e.target as Node) ) { setShowDropdown(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, [showDropdown]); const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); if (!handle.trim()) return; setIsSubmitting(true); setError(""); try { await login(handle.trim()); } catch (err) { setError(err instanceof Error ? err.message : "Login failed"); setIsSubmitting(false); } }; const handleLogout = async () => { setShowDropdown(false); await logout(); }; if (isLoading) { return (
); } if (isAuthenticated && session) { return (
{showDropdown && (
)}
); } return ( <> {showModal && (
setShowModal(false)} > {/* Backdrop */}
{/* Modal */}
e.stopPropagation()} >

Sign in with ATProto

Enter your Bluesky handle to connect.

setHandle(e.target.value)} placeholder="alice.bsky.social" disabled={isSubmitting} autoFocus className="w-full px-3 py-2 text-sm bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-lg placeholder:text-zinc-300 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-emerald-500/30 focus:border-emerald-400 disabled:opacity-50 disabled:cursor-not-allowed text-zinc-900 dark:text-zinc-100" />

Just a username? We'll add .bsky.social for you.

{error &&

{error}

}
)} ); }