Files
ReporterStationManagementSy…/src/pages/Login/index.tsx
T
2026-08-01 23:09:49 +08:00

97 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react'
import { ShieldCheck, LogIn, Loader2 } from 'lucide-react'
import { useRole } from '../../context'
import { api } from '../../api'
/**
* 登录页面 — 支持工号/姓名登录,演示模式可切换角色
*/
export function LoginPage() {
const { login, setRole } = useRole()
const [code, setCode] = useState('')
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const handleLogin = async (e: React.FormEvent) => {
e.preventDefault()
if (!code.trim()) { setError('请输入工号或姓名'); return }
setLoading(true)
setError('')
try {
const res = await api.auth.login(code.trim())
login(res.token, res.role, res.name, res.station)
} catch (err) {
setError(err instanceof Error ? err.message : '登录失败')
} finally {
setLoading(false)
}
}
const handleDemo = (role: 'headquarters' | 'station' | 'reporter') => {
const demoNames: Record<typeof role, { name: string; station: string | null }> = {
headquarters: { name: '林致远', station: null },
station: { name: '苏明远', station: '北京记者站' },
reporter: { name: '林晓', station: '北京记者站' },
}
const demo = demoNames[role]
localStorage.setItem('auth_role', role)
localStorage.setItem('auth_name', demo.name)
localStorage.setItem('auth_station', String(demo.station))
setRole(role)
}
return (
<div className="login-page">
<div className="login-card">
<div className="login-header">
<div className="login-logo">
<ShieldCheck size={32} />
</div>
<h1></h1>
<p></p>
</div>
<form onSubmit={handleLogin} className="login-form">
<div className="form-field">
<label htmlFor="code"> / </label>
<input
id="code"
type="text"
value={code}
onChange={e => setCode(e.target.value)}
placeholder="如:PERSON_001 或 林晓"
disabled={loading}
autoFocus
/>
</div>
{error && <div className="login-error">{error}</div>}
<button type="submit" className="login-btn" disabled={loading}>
{loading ? <Loader2 size={18} className="spin" /> : <LogIn size={18} />}
<span>{loading ? '登录中...' : '登 录'}</span>
</button>
</form>
<div className="login-divider">
<span>使</span>
</div>
<div className="demo-buttons">
<button onClick={() => handleDemo('reporter')} className="demo-btn">
</button>
<button onClick={() => handleDemo('station')} className="demo-btn">
</button>
<button onClick={() => handleDemo('headquarters')} className="demo-btn">
</button>
</div>
<div className="login-hint">
<p>PERSON_001PERSON_006PERSON_007</p>
</div>
</div>
</div>
)
}