feat(web): integrate session management and improve API error handling

This commit is contained in:
2026-03-11 17:19:14 +08:00
parent f1932676be
commit 168a5b5613
5 changed files with 88 additions and 76 deletions

View File

@@ -1,12 +1,10 @@
import { ReactNode } from "react";
import Sidebar from "@/components/sidebar";
import { ReactQueryProvider } from "@/components/query-provider";
import { SessionWatcher } from "@/components/session-watcher";
export default function DashboardLayout({ children }: { children: ReactNode }) {
return (
<div className="flex h-dvh bg-background">
<SessionWatcher />
<Sidebar />
{/* Main content */}

View File

@@ -4,8 +4,7 @@ import { useState } from "react";
import { useRouter } from "next/navigation";
import { Alert, Button, Card, CloseButton, Input, Label, TextField } from "@heroui/react";
import { Thunderbolt } from "@gravity-ui/icons";
const CSMS_URL = process.env.NEXT_PUBLIC_CSMS_URL ?? "http://localhost:3001";
import { api } from "@/lib/api";
export default function SetupPage() {
const router = useRouter();
@@ -38,28 +37,15 @@ export default function SetupPage() {
setLoading(true);
try {
const res = await fetch(`${CSMS_URL}/api/setup`, {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({
name: form.name,
email: form.email,
username: form.username,
password: form.password,
}),
await api.setup.create({
name: form.name,
email: form.email,
username: form.username,
password: form.password,
});
if (!res.ok) {
const data = await res.json().catch(() => ({}));
setError((data as { error?: string }).error ?? "初始化失败,请重试");
return;
}
// 初始化成功,跳转登录页
router.push("/login?setup=1");
} catch {
setError("网络错误,请稍后重试");
} catch (err) {
setError(err instanceof Error ? err.message : "初始化失败,请重试");
} finally {
setLoading(false);
}
@@ -74,7 +60,7 @@ export default function SetupPage() {
</div>
<div className="text-center">
<h1 className="text-2xl font-bold tracking-tight text-foreground">Helios EVCS</h1>
<p className="mt-1 text-sm text-muted"> · </p>
<p className="mt-1 text-sm text-muted"> · </p>
</div>
</div>