"use client"; import Link from "next/link"; import { useSession, signOut, signIn } from "next-auth/react"; import { useState, useEffect } from "react"; import { usePathname } from "next/navigation"; import { IoClose, IoMenu } from "react-icons/io5"; import { FiMoon, FiSun, FiLogOut, FiDollarSign, FiPlus, FiUser, FiKey, FiCheck, FiX, FiTrash2 } from "react-icons/fi"; import config from "@/lib/config"; import toast from "react-hot-toast"; function HuggingFaceIcon({ className = "w-3 h-3" }) { return ( ); } const HF_DUPLICATE_URL = "https://huggingface.co/spaces?duplicate=sonic-coders/Hugging-c-ai"; export default function Navbar() { const { data: session, status, update: updateSession } = useSession(); const pathname = usePathname(); const [isOpen, setIsOpen] = useState(false); const [isProfileOpen, setIsProfileOpen] = useState(false); const [isApiKeyModalOpen, setIsApiKeyModalOpen] = useState(false); const [apiKeyInput, setApiKeyInput] = useState(""); const [savingKey, setSavingKey] = useState(false); const appName = config?.appName || "AI SaaS"; const logoLetter = appName.trim().charAt(0).toUpperCase(); const isApiKeyActive = Boolean(session?.user?.customApiKey); useEffect(() => { if (session?.user?.customApiKey) { setApiKeyInput(session.user.customApiKey); } }, [session?.user?.customApiKey]); const appMatch = pathname ? pathname.match(/^\/app\/([^\/]+)/) : null; const currentAppId = appMatch ? appMatch[1] : null; const navLinks = currentAppId ? [ { name: "Workspace", path: `/app/${currentAppId}` }, { name: "Gallery", path: `/app/${currentAppId}/gallery` }, { name: "Pricing", path: `/app/${currentAppId}/pricing` }, ] : [ { name: "Workspace", path: "/" }, { name: "Gallery", path: "/gallery" }, { name: "Pricing", path: "/pricing" }, ]; const handleSaveApiKey = async (e) => { e.preventDefault(); const key = apiKeyInput.trim(); if (!key) { toast.error("Please enter a valid API Key"); return; } setSavingKey(true); try { if (status === "authenticated") { const res = await fetch("/api/user/apikey", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ apiKey: key }), }); const data = await res.json(); if (!res.ok) throw new Error(data.error || "Failed to save API key"); await updateSession({ customApiKey: key }); toast.success("Custom API Key updated!"); setIsApiKeyModalOpen(false); window.location.reload(); } else { const res = await signIn("credentials", { apiKey: key, redirect: false, }); if (res?.error) { throw new Error(res.error || "Failed to sign in with API key"); } toast.success("Signed in with API Key!"); setIsApiKeyModalOpen(false); window.location.reload(); } } catch (err) { toast.error(err.message || "Failed to save API Key"); } finally { setSavingKey(false); } }; const handleRemoveApiKey = async () => { setSavingKey(true); try { const res = await fetch("/api/user/apikey", { method: "DELETE" }); const data = await res.json(); if (!res.ok) throw new Error(data.error || "Failed to remove API key"); await updateSession({ customApiKey: null }); setApiKeyInput(""); toast.success("Custom API Key removed"); setIsApiKeyModalOpen(false); window.location.reload(); } catch (err) { toast.error(err.message || "Failed to remove API Key"); } finally { setSavingKey(false); } }; return (
{/* Logo and Brand Title */}
{logoLetter}
{appName} {/* Desktop Navigation Links */} {/* Desktop Actions Section */}
{/* HF Space Duplicate Button */} Duplicate to HF Space {/* Add/Manage API Key - Directly visible in Navbar */} {status === "authenticated" ? (
{/* Credit Balance indicator */}
{isApiKeyActive ? "∞ (API Key)" : session.user.credits !== undefined ? session.user.credits : 0} {!isApiKeyActive && ( )}
{/* Profile Menu Toggle */}
{/* Profile Dropdown */} {isProfileOpen && (
{session.user.email}
)}
) : ( Sign In )}
{/* Mobile Navbar Controls */}
{status === "authenticated" && (
{isApiKeyActive ? "∞ Key" : session.user.credits !== undefined ? session.user.credits : 0}
)}
{/* Mobile Menu Dropdown */} {isOpen && (
)} {/* API Key Modal */} {isApiKeyModalOpen && (
Custom API Key Settings

Use your own HF token, OpenAI key, Anthropic key, Groq key, or MuAPI key. We auto-detect the provider from the key prefix. Keys are encrypted at rest.

setApiKeyInput(e.target.value)} placeholder="hf_... | sk-... | sk-ant... | gsk_... | mu_..." className="w-full bg-bg-page border border-divider rounded-lg px-3.5 py-2.5 text-xs text-white placeholder-secondary-text/50 focus:outline-none focus:border-amber-400 transition-colors" />
{isApiKeyActive && status === "authenticated" && ( )}
)}
); }