2025-10-09 17:23:15 +08:00
|
|
|
import { useState } from 'react';
|
|
|
|
|
import { useNavigate } from 'react-router-dom';
|
2025-10-10 11:15:56 +08:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2025-10-09 17:23:15 +08:00
|
|
|
import {
|
|
|
|
|
Box,
|
|
|
|
|
Button,
|
|
|
|
|
Checkbox,
|
|
|
|
|
Container,
|
|
|
|
|
FormControlLabel,
|
|
|
|
|
TextField,
|
|
|
|
|
Typography,
|
|
|
|
|
Link,
|
2025-10-09 18:11:35 +08:00
|
|
|
AppBar,
|
|
|
|
|
Toolbar,
|
|
|
|
|
Card,
|
2025-10-10 15:09:04 +08:00
|
|
|
CardContent,
|
|
|
|
|
Alert
|
2025-10-09 17:23:15 +08:00
|
|
|
} from '@mui/material';
|
2025-10-10 11:15:56 +08:00
|
|
|
import LanguageSwitcher from '../components/LanguageSwitcher';
|
2025-10-10 15:09:04 +08:00
|
|
|
import userService from '../services/user_service';
|
2025-10-09 17:23:15 +08:00
|
|
|
|
|
|
|
|
const Login = () => {
|
2025-10-10 11:15:56 +08:00
|
|
|
const { t } = useTranslation();
|
2025-10-09 18:11:35 +08:00
|
|
|
const [email, setEmail] = useState('');
|
|
|
|
|
const [password, setPassword] = useState('');
|
|
|
|
|
const [rememberEmail, setRememberEmail] = useState(false);
|
2025-10-09 17:23:15 +08:00
|
|
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
2025-10-09 18:11:35 +08:00
|
|
|
const [emailError, setEmailError] = useState(false);
|
|
|
|
|
const [passwordError, setPasswordError] = useState(false);
|
2025-10-10 15:09:04 +08:00
|
|
|
const [loginError, setLoginError] = useState('');
|
2025-10-09 17:23:15 +08:00
|
|
|
const navigate = useNavigate();
|
|
|
|
|
|
2025-10-10 11:15:56 +08:00
|
|
|
console.log(t, t('en'), t('login'));
|
|
|
|
|
|
2025-10-10 15:09:04 +08:00
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
2025-10-09 17:23:15 +08:00
|
|
|
e.preventDefault();
|
2025-10-09 18:11:35 +08:00
|
|
|
|
|
|
|
|
const hasEmail = !!email.trim();
|
|
|
|
|
const hasPassword = !!password.trim();
|
|
|
|
|
setEmailError(!hasEmail);
|
|
|
|
|
setPasswordError(!hasPassword);
|
2025-10-10 15:09:04 +08:00
|
|
|
setLoginError('');
|
|
|
|
|
|
2025-10-09 18:11:35 +08:00
|
|
|
if (!hasEmail || !hasPassword) return;
|
|
|
|
|
|
2025-10-09 17:23:15 +08:00
|
|
|
setIsSubmitting(true);
|
2025-10-10 15:09:04 +08:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const response = await userService.login({ email, password });
|
|
|
|
|
|
|
|
|
|
// if (response.code === 0) {
|
|
|
|
|
// // 登录成功,跳转到主页
|
|
|
|
|
// navigate('/');
|
|
|
|
|
// } else {
|
|
|
|
|
// // 登录失败,显示错误信息
|
|
|
|
|
// setLoginError(response.message || t('login.loginFailed'));
|
|
|
|
|
// }
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
// 处理网络错误或其他异常
|
|
|
|
|
setLoginError(error.message || t('login.networkError'));
|
|
|
|
|
} finally {
|
|
|
|
|
setIsSubmitting(false);
|
|
|
|
|
}
|
2025-10-09 17:23:15 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
2025-10-09 18:11:35 +08:00
|
|
|
<Box sx={{ minHeight: '100vh', width: '100vw', bgcolor: 'background.default', display: 'flex', flexDirection: 'column' }}>
|
|
|
|
|
{/* 顶部栏使用主题主色 */}
|
|
|
|
|
<AppBar position="static" color="primary" enableColorOnDark>
|
2025-10-10 11:15:56 +08:00
|
|
|
<Toolbar sx={{ minHeight: 60, justifyContent: 'space-between' }}>
|
2025-10-09 18:11:35 +08:00
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
width: 40,
|
|
|
|
|
height: 40,
|
|
|
|
|
bgcolor: 'common.white',
|
|
|
|
|
color: 'primary.main',
|
|
|
|
|
borderRadius: '50%',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
fontWeight: 700,
|
|
|
|
|
fontSize: '1.1rem',
|
|
|
|
|
}}
|
|
|
|
|
aria-label="Brand"
|
|
|
|
|
>
|
|
|
|
|
T
|
|
|
|
|
</Box>
|
2025-10-10 11:15:56 +08:00
|
|
|
<LanguageSwitcher />
|
2025-10-09 18:11:35 +08:00
|
|
|
</Toolbar>
|
|
|
|
|
</AppBar>
|
|
|
|
|
|
|
|
|
|
{/* 主体卡片 */}
|
|
|
|
|
<Container maxWidth="sm" sx={{ flex: 1, display: 'flex', alignItems: 'center' }}>
|
|
|
|
|
<Card sx={{ width: '100%' }}>
|
|
|
|
|
<CardContent sx={{ p: 4 }}>
|
2025-10-10 11:15:56 +08:00
|
|
|
<Typography variant="subtitle1" color="text.secondary" sx={{ mb: 1, display: 'block' }}>
|
|
|
|
|
T-Systems Enterprise RAG Empowerment System
|
2025-10-09 18:11:35 +08:00
|
|
|
</Typography>
|
|
|
|
|
<Typography variant="h5" fontWeight={700} sx={{ mb: 2 }}>
|
2025-10-10 11:15:56 +08:00
|
|
|
{t('login.login')}
|
|
|
|
|
<br /> {t('login.emailLabel')} & {t('login.passwordLabel')}
|
2025-10-09 18:11:35 +08:00
|
|
|
</Typography>
|
|
|
|
|
|
|
|
|
|
<Box component="form" onSubmit={handleSubmit} noValidate>
|
2025-10-10 15:09:04 +08:00
|
|
|
{loginError && (
|
|
|
|
|
<Alert severity="error" sx={{ mb: 2 }}>
|
|
|
|
|
{loginError}
|
|
|
|
|
</Alert>
|
|
|
|
|
)}
|
|
|
|
|
|
2025-10-09 18:11:35 +08:00
|
|
|
<TextField
|
2025-10-09 17:23:15 +08:00
|
|
|
fullWidth
|
2025-10-09 18:11:35 +08:00
|
|
|
id="email"
|
|
|
|
|
name="email"
|
|
|
|
|
type="email"
|
2025-10-10 11:15:56 +08:00
|
|
|
placeholder={t('login.emailPlaceholder')}
|
2025-10-09 18:11:35 +08:00
|
|
|
autoComplete="email"
|
|
|
|
|
value={email}
|
|
|
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
|
|
|
error={emailError}
|
|
|
|
|
required
|
|
|
|
|
sx={{ mb: 2 }}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<TextField
|
2025-10-09 17:23:15 +08:00
|
|
|
fullWidth
|
2025-10-09 18:11:35 +08:00
|
|
|
id="password"
|
|
|
|
|
name="password"
|
|
|
|
|
type="password"
|
2025-10-10 11:15:56 +08:00
|
|
|
placeholder={t('login.passwordPlaceholder')}
|
2025-10-09 18:11:35 +08:00
|
|
|
autoComplete="current-password"
|
|
|
|
|
value={password}
|
|
|
|
|
onChange={(e) => setPassword(e.target.value)}
|
|
|
|
|
error={passwordError}
|
|
|
|
|
required
|
|
|
|
|
sx={{ mb: 2 }}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
|
|
|
|
|
<FormControlLabel
|
|
|
|
|
control={
|
|
|
|
|
<Checkbox
|
|
|
|
|
checked={rememberEmail}
|
|
|
|
|
onChange={(e) => setRememberEmail(e.target.checked)}
|
|
|
|
|
id="rememberEmail"
|
|
|
|
|
/>
|
|
|
|
|
}
|
2025-10-10 11:15:56 +08:00
|
|
|
label={t('login.rememberMe')}
|
2025-10-09 18:11:35 +08:00
|
|
|
/>
|
|
|
|
|
</Box>
|
|
|
|
|
|
|
|
|
|
<Button type="submit" variant="contained" fullWidth disabled={isSubmitting}>
|
2025-10-10 11:15:56 +08:00
|
|
|
{isSubmitting ? 'Processing...' : t('login.login')}
|
2025-10-09 18:11:35 +08:00
|
|
|
</Button>
|
|
|
|
|
</Box>
|
|
|
|
|
|
|
|
|
|
<Box sx={{ mt: 2, textAlign: 'center' }}>
|
|
|
|
|
<Box mt={0.5}>
|
2025-10-10 11:15:56 +08:00
|
|
|
{t('login.signInTip')} <Link href="#">{t('login.signUp')}</Link>.
|
2025-10-09 18:11:35 +08:00
|
|
|
</Box>
|
2025-10-09 17:23:15 +08:00
|
|
|
</Box>
|
2025-10-09 18:11:35 +08:00
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
|
|
|
|
</Container>
|
|
|
|
|
|
|
|
|
|
{/* 页脚 */}
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
borderTop: '1px solid',
|
|
|
|
|
borderColor: 'divider',
|
|
|
|
|
height: 50,
|
|
|
|
|
display: 'flex',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
|
px: 2,
|
|
|
|
|
color: 'text.secondary',
|
|
|
|
|
bgcolor: 'background.paper',
|
|
|
|
|
}}
|
|
|
|
|
>
|
2025-10-09 17:23:15 +08:00
|
|
|
<Box>© Deutsche Telekom AG</Box>
|
2025-10-09 18:11:35 +08:00
|
|
|
<Box sx={{ display: 'flex', gap: 2 }}>
|
2025-10-09 17:23:15 +08:00
|
|
|
<Link href="#" color="inherit">Imprint</Link>
|
|
|
|
|
<Link href="#" color="inherit">Data privacy</Link>
|
2025-10-09 18:11:35 +08:00
|
|
|
</Box>
|
|
|
|
|
</Box>
|
|
|
|
|
</Box>
|
2025-10-09 17:23:15 +08:00
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default Login;
|