8 changed files with 144 additions and 86 deletions
@ -0,0 +1,57 @@ |
|||
import { useState } from 'react'; |
|||
import { DEFAULT_CREDENTIALS } from '../../constants/auth'; |
|||
|
|||
interface LoginFormProps { |
|||
onSubmit: (username: string, password: string) => void; |
|||
} |
|||
|
|||
export function LoginForm({ onSubmit }: LoginFormProps) { |
|||
const [username, setUsername] = useState(DEFAULT_CREDENTIALS.username); |
|||
const [password, setPassword] = useState(DEFAULT_CREDENTIALS.password); |
|||
|
|||
const handleSubmit = (e: React.FormEvent) => { |
|||
e.preventDefault(); |
|||
onSubmit(username, password); |
|||
}; |
|||
|
|||
return ( |
|||
<form className="mt-8 space-y-6" onSubmit={handleSubmit}> |
|||
<div className="space-y-4"> |
|||
<div> |
|||
<label htmlFor="username" className="block text-sm font-medium"> |
|||
用户名/邮箱 |
|||
</label> |
|||
<input |
|||
id="username" |
|||
type="text" |
|||
required |
|||
value={username} |
|||
onChange={(e) => setUsername(e.target.value)} |
|||
className="mt-1 block w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" |
|||
placeholder="请输入用户名或邮箱" |
|||
/> |
|||
</div> |
|||
<div> |
|||
<label htmlFor="password" className="block text-sm font-medium"> |
|||
密码 |
|||
</label> |
|||
<input |
|||
id="password" |
|||
type="password" |
|||
required |
|||
value={password} |
|||
onChange={(e) => setPassword(e.target.value)} |
|||
className="mt-1 block w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" |
|||
placeholder="请输入密码" |
|||
/> |
|||
</div> |
|||
</div> |
|||
<button |
|||
type="submit" |
|||
className="w-full rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" |
|||
> |
|||
登录 |
|||
</button> |
|||
</form> |
|||
); |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
export const DEFAULT_CREDENTIALS = { |
|||
username: 'admin', |
|||
email: 'admin@example.com', |
|||
password: 'admin123' |
|||
}; |
|||
@ -1,79 +0,0 @@ |
|||
import { useState } from 'react'; |
|||
import { useNavigate } from 'react-router-dom'; |
|||
|
|||
export function LoginPage() { |
|||
const navigate = useNavigate(); |
|||
// 默认账号密码
|
|||
const defaultCredentials = { |
|||
username: 'admin', |
|||
email: 'admin@example.com', |
|||
password: 'admin123' |
|||
}; |
|||
|
|||
// 初始化时使用默认值
|
|||
const [username, setUsername] = useState(defaultCredentials.username); |
|||
const [password, setPassword] = useState(defaultCredentials.password); |
|||
|
|||
const handleSubmit = (e: React.FormEvent) => { |
|||
e.preventDefault(); |
|||
|
|||
// 验证登录
|
|||
const isValidLogin = |
|||
(username === defaultCredentials.username || username === defaultCredentials.email) && |
|||
password === defaultCredentials.password; |
|||
|
|||
if (isValidLogin) { |
|||
navigate('/dashboard'); |
|||
} else { |
|||
alert('用户名/邮箱或密码错误'); |
|||
} |
|||
}; |
|||
|
|||
return ( |
|||
<div className="flex min-h-screen items-center justify-center bg-background"> |
|||
<div className="w-full max-w-md space-y-8 rounded-lg border bg-card p-8 shadow-lg"> |
|||
<div className="text-center"> |
|||
<h2 className="text-2xl font-bold">登录</h2> |
|||
</div> |
|||
<form className="mt-8 space-y-6" onSubmit={handleSubmit}> |
|||
<div className="space-y-4"> |
|||
<div> |
|||
<label htmlFor="username" className="block text-sm font-medium"> |
|||
用户名/邮箱 |
|||
</label> |
|||
<input |
|||
id="username" |
|||
type="text" |
|||
required |
|||
value={username} |
|||
onChange={(e) => setUsername(e.target.value)} |
|||
className="mt-1 block w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" |
|||
placeholder="请输入用户名或邮箱" |
|||
/> |
|||
</div> |
|||
<div> |
|||
<label htmlFor="password" className="block text-sm font-medium"> |
|||
密码 |
|||
</label> |
|||
<input |
|||
id="password" |
|||
type="password" |
|||
required |
|||
value={password} |
|||
onChange={(e) => setPassword(e.target.value)} |
|||
className="mt-1 block w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" |
|||
placeholder="请输入密码" |
|||
/> |
|||
</div> |
|||
</div> |
|||
<button |
|||
type="submit" |
|||
className="w-full rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" |
|||
> |
|||
登录 |
|||
</button> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
); |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
import { useNavigate } from 'react-router-dom'; |
|||
import { LoginForm } from '../../components/auth/LoginForm'; |
|||
import { DEFAULT_CREDENTIALS } from '../../constants/auth'; |
|||
|
|||
export function LoginPage() { |
|||
const navigate = useNavigate(); |
|||
|
|||
const handleLogin = (username: string, password: string) => { |
|||
const isValidLogin = |
|||
(username === DEFAULT_CREDENTIALS.username || username === DEFAULT_CREDENTIALS.email) && |
|||
password === DEFAULT_CREDENTIALS.password; |
|||
|
|||
if (isValidLogin) { |
|||
navigate('/dashboard'); |
|||
} else { |
|||
alert('用户名/邮箱或密码错误'); |
|||
} |
|||
}; |
|||
|
|||
return ( |
|||
<div className="flex min-h-screen items-center justify-center bg-background"> |
|||
<div className="w-full max-w-md space-y-8 rounded-lg border bg-card p-8 shadow-lg"> |
|||
<div className="text-center"> |
|||
<h2 className="text-2xl font-bold">登录</h2> |
|||
</div> |
|||
<LoginForm onSubmit={handleLogin} /> |
|||
</div> |
|||
</div> |
|||
); |
|||
} |
|||
Loading…
Reference in new issue