refactor: 前端 antd 组件使用最佳实践重构
- 修正 API 响应类型,增加 ProjectResponse 包装类型 - ConfigProvider 配置中文 locale (zhCN) - 生产入口启用 ErrorBoundary,使用 Result 组件 - ReactQueryDevtools 仅开发环境渲染 - Sider 增加 collapsible 配置,使用 antd 默认折叠行为 - 项目页面拆分为 ProjectToolbar/ProjectTable/ProjectFormModal - 搜索改用 Input.Search,表单增加 whitespace 校验 - 404/ErrorBoundary/Dashboard 使用 antd Result/Typography/Card/Descriptions - 清理未使用的 ProtectedRoute 和冗余样式类 - styles.css 仅保留必要布局样式,无 antd 内部类覆盖 - 更新测试覆盖,避免依赖 antd 内部类名 - 更新 docs/development/frontend.md 开发规范
This commit is contained in:
18
src/web/hooks/use-meta.ts
Normal file
18
src/web/hooks/use-meta.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import type { MetaResponse } from "../../shared/api";
|
||||
|
||||
export function useMeta() {
|
||||
return useQuery({
|
||||
queryFn: fetchMeta,
|
||||
queryKey: ["meta"],
|
||||
refetchInterval: 30000,
|
||||
staleTime: 5000,
|
||||
});
|
||||
}
|
||||
|
||||
async function fetchMeta(): Promise<MetaResponse> {
|
||||
const response = await fetch("/api/meta");
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
return response.json() as Promise<MetaResponse>;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import type {
|
||||
CreateProjectRequest,
|
||||
Project,
|
||||
ProjectListResponse,
|
||||
ProjectResponse,
|
||||
ProjectStatus,
|
||||
UpdateProjectRequest,
|
||||
} from "../../shared/api";
|
||||
@@ -81,7 +82,8 @@ async function archiveProject(id: string): Promise<Project> {
|
||||
const body = (await response.json().catch(() => null)) as null | { error?: string };
|
||||
throw new Error(body?.error ?? `HTTP ${response.status}`);
|
||||
}
|
||||
return response.json() as Promise<Project>;
|
||||
const data = (await response.json()) as ProjectResponse;
|
||||
return data.project;
|
||||
}
|
||||
|
||||
async function createProject(data: CreateProjectRequest): Promise<Project> {
|
||||
@@ -94,7 +96,8 @@ async function createProject(data: CreateProjectRequest): Promise<Project> {
|
||||
const body = (await response.json().catch(() => null)) as null | { error?: string };
|
||||
throw new Error(body?.error ?? `HTTP ${response.status}`);
|
||||
}
|
||||
return response.json() as Promise<Project>;
|
||||
const result = (await response.json()) as ProjectResponse;
|
||||
return result.project;
|
||||
}
|
||||
|
||||
async function deleteProject(id: string): Promise<void> {
|
||||
@@ -111,7 +114,8 @@ async function fetchProject(id: string): Promise<Project> {
|
||||
const body = (await response.json().catch(() => null)) as null | { error?: string };
|
||||
throw new Error(body?.error ?? `HTTP ${response.status}`);
|
||||
}
|
||||
return response.json() as Promise<Project>;
|
||||
const data = (await response.json()) as ProjectResponse;
|
||||
return data.project;
|
||||
}
|
||||
|
||||
async function fetchProjectList(params: {
|
||||
@@ -141,7 +145,8 @@ async function restoreProject(id: string): Promise<Project> {
|
||||
const body = (await response.json().catch(() => null)) as null | { error?: string };
|
||||
throw new Error(body?.error ?? `HTTP ${response.status}`);
|
||||
}
|
||||
return response.json() as Promise<Project>;
|
||||
const data = (await response.json()) as ProjectResponse;
|
||||
return data.project;
|
||||
}
|
||||
|
||||
async function updateProject(id: string, data: UpdateProjectRequest): Promise<Project> {
|
||||
@@ -154,5 +159,6 @@ async function updateProject(id: string, data: UpdateProjectRequest): Promise<Pr
|
||||
const body = (await response.json().catch(() => null)) as null | { error?: string };
|
||||
throw new Error(body?.error ?? `HTTP ${response.status}`);
|
||||
}
|
||||
return response.json() as Promise<Project>;
|
||||
const result = (await response.json()) as ProjectResponse;
|
||||
return result.project;
|
||||
}
|
||||
|
||||
@@ -22,11 +22,7 @@ export function useSidebarCollapsed() {
|
||||
writeSidebarCollapsed(nextCollapsed);
|
||||
};
|
||||
|
||||
const toggleCollapsed = () => {
|
||||
setCollapsed(!collapsed);
|
||||
};
|
||||
|
||||
return { collapsed, setCollapsed, toggleCollapsed };
|
||||
return { collapsed, setCollapsed };
|
||||
}
|
||||
|
||||
export function writeSidebarCollapsed(collapsed: boolean, storage: Storage = window.localStorage) {
|
||||
|
||||
Reference in New Issue
Block a user