Files
termi-blog/admin/src/pages/login-page.tsx

125 lines
5.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 { LockKeyhole, ShieldCheck } from 'lucide-react'
import { useState } from 'react'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
export function LoginPage({
submitting,
localLoginEnabled,
proxyAuthEnabled,
onLogin,
}: {
submitting: boolean
localLoginEnabled: boolean
proxyAuthEnabled: boolean
onLogin: (payload: { username: string; password: string }) => Promise<void>
}) {
const [username, setUsername] = useState('admin')
const [password, setPassword] = useState('admin123')
return (
<div className="flex min-h-screen items-center justify-center px-4 py-10">
<div className="grid w-full max-w-5xl gap-6 lg:grid-cols-[1.1fr_0.9fr]">
<Card className="overflow-hidden border-primary/12 bg-gradient-to-br from-card via-card to-primary/5">
<CardHeader className="space-y-4">
<div className="inline-flex w-fit items-center gap-2 rounded-full border border-primary/20 bg-primary/10 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.28em] text-primary">
<ShieldCheck className="h-3.5 w-3.5" />
Termi
</div>
<div className="space-y-3">
<CardTitle className="text-4xl leading-tight">
线
</CardTitle>
<CardDescription className="max-w-xl text-base leading-7">
API
</CardDescription>
</div>
</CardHeader>
<CardContent className="grid gap-4 sm:grid-cols-3">
{[
['React 应用', '独立后台界面'],
['shadcn/ui', '统一的组件基础'],
['Loco API', '后端继续专注数据与规则'],
].map(([title, description]) => (
<div
key={title}
className="rounded-2xl border border-border/70 bg-background/75 p-4"
>
<div className="text-sm font-semibold">{title}</div>
<p className="mt-2 text-sm leading-6 text-muted-foreground">{description}</p>
</div>
))}
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-3">
<span className="flex h-11 w-11 items-center justify-center rounded-2xl border border-primary/20 bg-primary/10 text-primary">
<LockKeyhole className="h-5 w-5" />
</span>
</CardTitle>
<CardDescription>
{localLoginEnabled
? '当前登录复用后端管理员账号;如果前面接了 TinyAuth / Pocket ID也可以直接由反向代理完成 SSO。'
: proxyAuthEnabled
? '当前后台已切到代理侧 SSO 模式,请从受保护的后台域名入口进入。'
: '当前后台未开放本地账号密码登录,请检查部署配置。'}
</CardDescription>
</CardHeader>
<CardContent>
{localLoginEnabled ? (
<form
className="space-y-5"
onSubmit={(event) => {
event.preventDefault()
void onLogin({ username, password })
}}
>
<div className="space-y-2">
<Label htmlFor="username"></Label>
<Input
id="username"
value={username}
onChange={(event) => setUsername(event.target.value)}
autoComplete="username"
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="password"></Label>
<Input
id="password"
type="password"
value={password}
onChange={(event) => setPassword(event.target.value)}
autoComplete="current-password"
required
/>
</div>
<Button className="w-full" size="lg" disabled={submitting}>
{submitting ? '登录中...' : '进入后台'}
</Button>
</form>
) : (
<div className="space-y-4 rounded-2xl border border-border/70 bg-background/70 p-4 text-sm leading-7 text-muted-foreground">
<p> Caddy + TinyAuth + Pocket ID </p>
<p> SSO </p>
<Button className="w-full" size="lg" onClick={() => window.location.reload()}>
</Button>
</div>
)}
</CardContent>
</Card>
</div>
</div>
)
}