feat(client): 初始化前端壳与鉴权守卫(P1-5)

- 技术栈:React 18 + TypeScript + Vite + Tailwind

- API 层:ApiError + 401 自动刷新 + single-flight 重试

- 鉴权:内存 Access Token + Cookie Refresh + 启动 bootstrap

- RBAC:权限映射 + RequireAuth/RequirePermission 路由守卫

- 布局:OA 工作台壳层 + 侧边栏 + 5 个占位页面

- 样式:复用 hyb-web 视觉 token(单向同步)

- 文档:新增 client README,补充 server 联调说明
这个提交包含在:
2026-02-07 16:43:57 +08:00
父节点 f527633716
当前提交 c290e03fef
共修改 35 个文件,包含 4127 行新增和 0 行删除
@@ -0,0 +1,20 @@
import type { ReactNode } from "react";
type PageHeaderProps = {
title: string;
subtitle?: string;
actions?: ReactNode;
};
export function PageHeader({ title, subtitle, actions }: PageHeaderProps) {
return (
<div className="mb-6 flex flex-wrap items-start justify-between gap-4">
<div>
<h2 className="text-2xl font-bold text-slate-900">{title}</h2>
{subtitle ? <p className="mt-1 text-sm text-secondary">{subtitle}</p> : null}
</div>
{actions ? <div className="shrink-0">{actions}</div> : null}
</div>
);
}