import React, { useState } from 'react'; import styled, { keyframes } from 'styled-components'; import { login } from '../services/api'; const fadeIn = keyframes` from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } `; const LoginContainer = styled.div` width: 100%; max-width: 400px; margin: 0 auto; padding: ${({ theme }) => theme.spacing.xl}; background: ${({ theme }) => theme.colors.glass.light}; backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-radius: ${({ theme }) => theme.borderRadius.xl}; box-shadow: ${({ theme }) => theme.shadows.lg}; animation: ${fadeIn} 0.5s ease-out; border: 1px solid ${({ theme }) => theme.colors.glass.light}; @media (prefers-color-scheme: dark) { background: ${({ theme }) => theme.colors.glass.dark}; border-color: ${({ theme }) => theme.colors.glass.dark}; } `; const LoginTitle = styled.h1` color: ${({ theme }) => theme.colors.text.primary}; font-size: ${({ theme }) => theme.typography.fontSize['3xl']}; font-weight: ${({ theme }) => theme.typography.fontWeight.bold}; text-align: center; margin-bottom: ${({ theme }) => theme.spacing.xl}; display: flex; align-items: center; justify-content: center; gap: ${({ theme }) => theme.spacing.sm}; &::before { content: '🔒'; font-size: 1.2em; } `; const Form = styled.form` display: flex; flex-direction: column; gap: ${({ theme }) => theme.spacing.lg}; `; const InputGroup = styled.div` position: relative; `; const Label = styled.label` display: block; margin-bottom: ${({ theme }) => theme.spacing.xs}; color: ${({ theme }) => theme.colors.text.primary}; font-size: ${({ theme }) => theme.typography.fontSize.sm}; font-weight: ${({ theme }) => theme.typography.fontWeight.medium}; `; const Input = styled.input` width: 100%; padding: ${({ theme }) => theme.spacing.md}; font-size: ${({ theme }) => theme.typography.fontSize.base}; border: 2px solid ${({ theme }) => theme.colors.glass.light}; border-radius: ${({ theme }) => theme.borderRadius.lg}; background: ${({ theme }) => theme.colors.glass.light}; color: ${({ theme }) => theme.colors.text.primary}; transition: all ${({ theme }) => theme.transitions.default}; &:focus { outline: none; border-color: ${({ theme }) => theme.colors.primary}; box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40; } &::placeholder { color: ${({ theme }) => theme.colors.text.secondary}; } @media (prefers-color-scheme: dark) { background: ${({ theme }) => theme.colors.glass.dark}; border-color: ${({ theme }) => theme.colors.glass.dark}; } `; const SubmitButton = styled.button` width: 100%; padding: ${({ theme }) => theme.spacing.md}; font-size: ${({ theme }) => theme.typography.fontSize.base}; font-weight: ${({ theme }) => theme.typography.fontWeight.semibold}; color: white; background: ${({ theme }) => theme.colors.primary}; border: none; border-radius: ${({ theme }) => theme.borderRadius.lg}; cursor: pointer; transition: all ${({ theme }) => theme.transitions.default}; display: flex; align-items: center; justify-content: center; gap: ${({ theme }) => theme.spacing.sm}; &:hover { background: ${({ theme }) => theme.colors.primary}dd; transform: translateY(-1px); } &:active { transform: translateY(0); } &:disabled { opacity: 0.6; cursor: not-allowed; transform: none; } &::after { content: '→'; font-size: 1.2em; transition: transform ${({ theme }) => theme.transitions.default}; } &:hover::after { transform: translateX(4px); } `; const ErrorMessage = styled.div` color: ${({ theme }) => theme.colors.status.error}; font-size: ${({ theme }) => theme.typography.fontSize.sm}; text-align: center; margin-top: ${({ theme }) => theme.spacing.sm}; padding: ${({ theme }) => theme.spacing.sm}; background: ${({ theme }) => theme.colors.status.error}20; border-radius: ${({ theme }) => theme.borderRadius.md}; animation: ${fadeIn} 0.3s ease-out; `; const LoginHint = styled.div` color: ${({ theme }) => theme.colors.text.secondary}; font-size: ${({ theme }) => theme.typography.fontSize.sm}; text-align: center; margin-top: ${({ theme }) => theme.spacing.md}; padding: ${({ theme }) => theme.spacing.sm}; background: ${({ theme }) => theme.colors.secondary}20; border-radius: ${({ theme }) => theme.borderRadius.md}; strong { color: ${({ theme }) => theme.colors.secondary}; } `; function LoginForm({ onLogin }) { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const [isLoading, setIsLoading] = useState(false); const handleSubmit = async (e) => { e.preventDefault(); setError(''); setIsLoading(true); try { const result = await login(username, password); // 保存token和用户信息 localStorage.setItem('token', result.token); localStorage.setItem('user', JSON.stringify(result.user)); onLogin(result.token, result.user); } catch (err) { setError(err.response?.data?.error || '登录失败,请重试'); } finally { setIsLoading(false); } }; return ( 工作待办
setUsername(e.target.value)} disabled={isLoading} required /> setPassword(e.target.value)} disabled={isLoading} required /> {isLoading ? '登录中...' : '登录'} {error && {error}}
{/* 管理员: 用户名 admin,密码 weiMonkey2024
*/} 普通用户: 请使用管理员分配的账号密码
); } export default LoginForm;