import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '../context/AuthContext'; import { LogIn, UserPlus, Eye, EyeOff } from 'lucide-react'; const API_BASE = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000/api'; /* ─── Typewriter ─── */ const useTypewriter = (words: string[], speed = 80, pause = 2200) => { const [index, setIndex] = useState(0); const [sub, setSub] = useState(0); const [deleting, setDeleting] = useState(false); const [text, setText] = useState(''); useEffect(() => { const word = words[index % words.length]; const timer = setTimeout(() => { if (!deleting) { setText(word.slice(0, sub + 1)); setSub(s => s + 1); if (sub + 1 === word.length) setTimeout(() => setDeleting(true), pause); } else { setText(word.slice(0, sub - 1)); setSub(s => s - 1); if (sub - 1 === 0) { setDeleting(false); setIndex(i => i + 1); } } }, deleting ? speed / 2 : speed); return () => clearTimeout(timer); }, [sub, deleting, index]); return text; }; const Login: React.FC = () => { const [isRegistering, setIsRegistering] = useState(false); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const [loading, setLoading] = useState(false); const [showPassword, setShowPassword] = useState(false); const { login } = useAuth(); const navigate = useNavigate(); const rotatingWords = ['Knowledge Graphs.', 'Logic Engines.', 'LLM Reasoning.', 'Entity Networks.', 'Semantic Search.']; const rotating = useTypewriter(rotatingWords); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(''); setLoading(true); try { if (isRegistering) { const regRes = await fetch(`${API_BASE}/auth/register`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password, scopes: ['read', 'write', 'admin'] }), }); if (!regRes.ok) { const errData = await regRes.json(); throw new Error(errData.detail || 'Registration failed'); } } const loginRes = await fetch(`${API_BASE}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }), }); if (!loginRes.ok) { const errData = await loginRes.json(); throw new Error(errData.detail || 'Login failed'); } const { access_token } = await loginRes.json(); const userRes = await fetch(`${API_BASE}/auth/me`, { headers: { Authorization: `Bearer ${access_token}` }, }); if (!userRes.ok) throw new Error('Failed to fetch user profile'); const user = await userRes.json(); login(access_token, user); navigate('/'); } catch (err: any) { setError(err.message); } finally { setLoading(false); } }; return (