import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useMutation, useQuery } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { useAuth } from '../contexts/AuthContext'; import { useToast } from '../contexts/ToastContext'; import { useTheme } from '../contexts/ThemeContext'; import { X, Mail } from 'lucide-react'; import { api } from '../api/client'; import { Card, CardHeader, CardContent } from '../components/Card'; import { Button } from '../components/Button'; export function LoginPage() { const navigate = useNavigate(); const { t } = useTranslation(); const { login } = useAuth(); const { showToast } = useToast(); const { mode } = useTheme(); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [showForgotPassword, setShowForgotPassword] = useState(false); const [forgotEmail, setForgotEmail] = useState(''); // Check if advanced auth is enabled const { data: advancedAuthStatus } = useQuery({ queryKey: ['advancedAuthStatus'], queryFn: () => api.getAdvancedAuthStatus(), }); const loginMutation = useMutation({ mutationFn: () => login(username, password), onSuccess: () => { showToast(t('login.loginSuccess')); navigate('/'); }, onError: (error: Error) => { showToast(error.message || t('login.loginFailed'), 'error'); }, }); const forgotPasswordMutation = useMutation({ mutationFn: (email: string) => api.forgotPassword({ email }), onSuccess: (data) => { showToast(data.message, 'success'); setShowForgotPassword(false); setForgotEmail(''); }, onError: (error: Error) => { showToast(error.message, 'error'); }, }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!username || !password) { showToast(t('login.enterCredentials'), 'error'); return; } loginMutation.mutate(); }; const handleForgotPassword = (e: React.FormEvent) => { e.preventDefault(); if (!forgotEmail) { showToast('Please enter your email address', 'error'); return; } forgotPasswordMutation.mutate(forgotEmail); }; return (
Bambuddy

{t('login.title')}

{t('login.subtitle')}

setUsername(e.target.value)} className="block w-full px-4 py-3 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:outline-none focus:ring-2 focus:ring-bambu-green/50 focus:border-bambu-green transition-colors" placeholder={advancedAuthStatus?.advanced_auth_enabled ? t('login.usernameOrEmailPlaceholder') || 'Enter your username or email' : t('login.usernamePlaceholder')} autoComplete="username" />
setPassword(e.target.value)} className="block w-full px-4 py-3 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:outline-none focus:ring-2 focus:ring-bambu-green/50 focus:border-bambu-green transition-colors" placeholder={t('login.passwordPlaceholder')} autoComplete="current-password" />
{advancedAuthStatus?.advanced_auth_enabled && (
)}
{/* Forgot Password Modal */} {showForgotPassword && (
setShowForgotPassword(false)} > e.stopPropagation()} >

{t('login.forgotPasswordTitle')}

{advancedAuthStatus?.advanced_auth_enabled ? (

{t('login.forgotPasswordEmailMessage') || 'Enter your email address and we\'ll send you a new password.'}

setForgotEmail(e.target.value)} className="block w-full px-4 py-3 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:outline-none focus:ring-2 focus:ring-bambu-green/50 focus:border-bambu-green transition-colors" placeholder={t('login.emailPlaceholder') || 'your.email@example.com'} />
) : (

{t('login.forgotPasswordMessage')}

{t('login.howToReset')}

  1. {t('login.resetStep1')}
  2. {t('login.resetStep2')}
  3. {t('login.resetStep3')}
  4. {t('login.resetStep4')}
)}
)}
); }