92 lines
2.4 KiB
TypeScript
92 lines
2.4 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { Container, Typography, Box, Alert } from '@mui/material';
|
|
import { useAuth } from '../../contexts/AuthContext';
|
|
import { EmailLoginForm } from './EmailLoginForm';
|
|
import { EmailCredentials } from '../../services/auth/authService';
|
|
import { logger } from '../../debugConfig';
|
|
|
|
const getLoginErrorMessage = (error: unknown): string => {
|
|
const status = (error as { status?: number } | null)?.status;
|
|
const code = (error as { code?: string } | null)?.code;
|
|
|
|
if (code === 'email_not_confirmed' || status === 401 && code === 'invalid_grant') {
|
|
return 'Please confirm your email before logging in';
|
|
}
|
|
|
|
if (status === 401 || code === 'invalid_grant') {
|
|
return 'Invalid email or password';
|
|
}
|
|
|
|
return error instanceof Error ? error.message : 'Login failed';
|
|
};
|
|
|
|
const LoginPage: React.FC = () => {
|
|
const navigate = useNavigate();
|
|
const { user, signIn, isAuthResolving } = useAuth();
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
logger.debug('login-page', '🔍 Login page loaded', {
|
|
hasUser: !!user,
|
|
isAuthResolving
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (!isAuthResolving && user) {
|
|
navigate('/dashboard');
|
|
}
|
|
}, [user, isAuthResolving, navigate]);
|
|
|
|
const handleLogin = async (credentials: EmailCredentials) => {
|
|
try {
|
|
setError(null);
|
|
await signIn(credentials.email, credentials.password);
|
|
} catch (error) {
|
|
logger.error('login-page', '❌ Login failed', error);
|
|
const message = getLoginErrorMessage(error);
|
|
setError(message);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
if (user && !isAuthResolving) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Container
|
|
sx={{
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
minHeight: '100vh',
|
|
gap: 4
|
|
}}
|
|
>
|
|
<Typography variant="h2" component="h1" gutterBottom>
|
|
ClassroomCopilot.ai
|
|
</Typography>
|
|
|
|
<Typography variant="h4" gutterBottom>
|
|
Login
|
|
</Typography>
|
|
|
|
{error && (
|
|
<Alert severity="error" sx={{ width: '100%', maxWidth: 400 }}>
|
|
{error}
|
|
</Alert>
|
|
)}
|
|
|
|
<Box sx={{ width: '100%', maxWidth: 400 }}>
|
|
<EmailLoginForm
|
|
role="email_teacher"
|
|
onSubmit={handleLogin}
|
|
/>
|
|
</Box>
|
|
</Container>
|
|
);
|
|
};
|
|
|
|
export default LoginPage;
|