This commit is contained in:
Autumn-27 committed 2026-10-07 07:45:28 -04:00
1 parent b55ceb1fdd
commit a951e4aad3
6 files changed
+279 -44

No files matched your search

+53 -39
View File
@@ -17,13 +17,20 @@ export default function SetupPage() {
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const [checking, setChecking] = useState(true);
// 查不到初始化状态时不能默认当成"未初始化"——那样会把初始化表单摆给一个
// 其实已经设过密码的实例,用户照着填就会覆盖掉原密码。此时关闭入口。
const [unavailable, setUnavailable] = useState(false);
useEffect(() => {
api.authStatus()
api
.authStatus()
.then(({ initialized }) => {
if (initialized) router.replace("/login");
})
.catch(() => setError("无法连接到后端服务"))
.catch((err) => {
setError(err instanceof Error ? err.message : "无法连接到后端服务");
setUnavailable(true);
})
.finally(() => setChecking(false));
}, [router]);
@@ -61,13 +68,7 @@ export default function SetupPage() {
<div className="absolute size-60 rounded-full border border-primary-foreground/15" />
<div className="absolute size-40 rounded-full border border-primary-foreground/20" />
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src="/logo.png"
alt="ARTEX"
width={160}
height={160}
className="relative brightness-0 invert"
/>
<img src="/logo.png" alt="ARTEX" width={160} height={160} className="relative brightness-0 invert" />
</div>
</div>
@@ -75,38 +76,51 @@ export default function SetupPage() {
<div className="flex w-full items-center justify-center bg-background p-8 lg:w-2/3">
<div className="w-full max-w-md space-y-10 py-24 lg:py-32">
<div className="space-y-4 text-center">
<h2 className="text-2xl font-medium tracking-tight">初始化密码</h2>
<p className="mx-auto max-w-xl text-muted-foreground">首次使用 ARTEX,请为账户设置一个登录密码(至少 8 位)</p>
<h2 className="text-2xl font-medium tracking-tight">{unavailable ? "无法确认初始化状态" : "初始化密码"}</h2>
<p className="mx-auto max-w-xl text-muted-foreground">
{unavailable
? "后端或数据库暂时不可用。为避免覆盖实例上已有的密码,初始化入口已临时关闭——请恢复服务后重试。"
: "首次使用 ARTEX,请为账户设置一个登录密码(至少 8 位)"}
</p>
</div>
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
<div className="space-y-1.5">
<Label htmlFor="password">新密码</Label>
<Input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="至少 8 位"
autoFocus
autoComplete="new-password"
/>
{unavailable ? (
<div className="flex flex-col gap-4">
{error && <p className="text-center text-sm text-destructive">{error}</p>}
<Button type="button" className="w-full" onClick={() => window.location.reload()}>
重试
</Button>
</div>
<div className="space-y-1.5">
<Label htmlFor="confirm">确认密码</Label>
<Input
id="confirm"
type="password"
value={confirm}
onChange={(e) => setConfirm(e.target.value)}
placeholder="再次输入密码"
autoComplete="new-password"
/>
</div>
{error && <p className="text-sm text-destructive">{error}</p>}
<Button type="submit" className="w-full" disabled={loading || !password || !confirm}>
{loading ? "保存中..." : "设置密码并登录"}
</Button>
</form>
) : (
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
<div className="space-y-1.5">
<Label htmlFor="password">新密码</Label>
<Input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="至少 8 位"
autoFocus
autoComplete="new-password"
/>
</div>
<div className="space-y-1.5">
<Label htmlFor="confirm">确认密码</Label>
<Input
id="confirm"
type="password"
value={confirm}
onChange={(e) => setConfirm(e.target.value)}
placeholder="再次输入密码"
autoComplete="new-password"
/>
</div>
{error && <p className="text-sm text-destructive">{error}</p>}
<Button type="submit" className="w-full" disabled={loading || !password || !confirm}>
{loading ? "保存中..." : "设置密码并登录"}
</Button>
</form>
)}
</div>
</div>
</div>