Skip to main content
Glama
orneryd

M.I.M.I.R - Multi-agent Intelligent Memory & Insight Repository

by orneryd
Login.tsx6.19 kB
import { useState, useEffect, FormEvent } from 'react'; import { useNavigate } from 'react-router-dom'; import { Database, Lock, User } from 'lucide-react'; import { api, AuthConfig } from '../utils/api'; export function Login() { const navigate = useNavigate(); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const [loading, setLoading] = useState(false); const [authConfig, setAuthConfig] = useState<AuthConfig | null>(null); useEffect(() => { // Check auth config api.getAuthConfig().then(config => { if (!config.securityEnabled) { // Auth disabled - go straight to browser navigate('/', { replace: true }); return; } // Check if already authenticated api.checkAuth().then(result => { if (result.authenticated) { navigate('/', { replace: true }); } else { setAuthConfig(config); } }); }); }, [navigate]); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); setError(''); setLoading(true); const result = await api.login(username, password); if (result.success) { navigate('/', { replace: true }); } else { setError(result.error || 'Login failed'); } setLoading(false); }; if (!authConfig) { return ( <div className="min-h-screen flex items-center justify-center bg-norse-night"> <div className="w-12 h-12 border-4 border-nornic-primary border-t-transparent rounded-full animate-spin" /> </div> ); } return ( <div className="min-h-screen flex items-center justify-center bg-norse-night"> {/* Background pattern */} <div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,rgba(16,185,129,0.1),transparent_50%)]" /> <div className="relative max-w-md w-full mx-4"> <div className="bg-norse-shadow border border-norse-rune rounded-xl p-8 shadow-2xl"> {/* Logo */} <div className="text-center mb-8"> <div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-gradient-to-br from-nornic-primary to-nornic-secondary mb-4"> <Database className="w-8 h-8 text-white" /> </div> <h1 className="text-2xl font-bold text-white">NornicDB</h1> <p className="text-norse-silver text-sm mt-1">Graph Database Browser</p> </div> {authConfig.devLoginEnabled ? ( // Dev mode login form <form onSubmit={handleSubmit} className="space-y-4"> <div> <label htmlFor="username" className="block text-sm font-medium text-norse-silver mb-2"> Username </label> <div className="relative"> <User className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-norse-fog" /> <input id="username" type="text" value={username} onChange={(e) => setUsername(e.target.value)} className="w-full pl-10 pr-4 py-2 bg-norse-stone border border-norse-rune rounded-lg text-white placeholder-norse-fog focus:outline-none focus:ring-2 focus:ring-nornic-primary focus:border-transparent" placeholder="neo4j" required /> </div> </div> <div> <label htmlFor="password" className="block text-sm font-medium text-norse-silver mb-2"> Password </label> <div className="relative"> <Lock className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-norse-fog" /> <input id="password" type="password" value={password} onChange={(e) => setPassword(e.target.value)} className="w-full pl-10 pr-4 py-2 bg-norse-stone border border-norse-rune rounded-lg text-white placeholder-norse-fog focus:outline-none focus:ring-2 focus:ring-nornic-primary focus:border-transparent" placeholder="••••••••" required /> </div> </div> {error && ( <div className="p-3 bg-red-500/10 border border-red-500/30 rounded-lg"> <p className="text-sm text-red-400">{error}</p> </div> )} <button type="submit" disabled={loading} className="w-full py-2 px-4 bg-gradient-to-r from-nornic-primary to-nornic-secondary text-white font-medium rounded-lg hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-nornic-primary focus:ring-offset-2 focus:ring-offset-norse-shadow disabled:opacity-50 transition-opacity" > {loading ? 'Connecting...' : 'Connect'} </button> <p className="text-xs text-center text-norse-fog mt-4"> Development Mode - Use configured credentials </p> </form> ) : ( // OAuth providers <div className="space-y-3"> {authConfig.oauthProviders.map((provider) => ( <a key={provider.name} href={provider.url} className="flex items-center justify-center gap-2 w-full py-2 px-4 bg-norse-stone border border-norse-rune rounded-lg text-white hover:bg-norse-rune transition-colors" > <Lock className="w-4 h-4" /> Sign in with {provider.displayName} </a> ))} {authConfig.oauthProviders.length === 0 && ( <p className="text-center text-norse-silver"> No authentication providers configured </p> )} </div> )} </div> </div> </div> ); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/orneryd/Mimir'

If you have feedback or need assistance with the MCP directory API, please join our Discord server