feat(web): add login page, auth store, API client, and route guard

- API client with axios interceptors: JWT attach + 401 auto-refresh
- Auth store (Zustand): login/logout/loadFromStorage with localStorage
- Login page: gradient background, Ant Design form, error handling
- Home page: dashboard with statistics cards
- App.tsx: PrivateRoute guard, /login route, auth state restoration
- MainLayout: dynamic user display, logout dropdown, menu navigation
- Users API service: CRUD with pagination support
This commit is contained in:
iven
2026-04-11 03:38:29 +08:00
parent a7cdf67d17
commit 4a03a639a6
9 changed files with 421 additions and 27 deletions

52
apps/web/src/api/auth.ts Normal file
View File

@@ -0,0 +1,52 @@
import client from './client';
export interface LoginRequest {
username: string;
password: string;
}
export interface UserInfo {
id: string;
username: string;
email?: string;
phone?: string;
display_name?: string;
avatar_url?: string;
status: string;
roles: RoleInfo[];
}
export interface RoleInfo {
id: string;
name: string;
code: string;
description?: string;
is_system: boolean;
}
export interface LoginResponse {
access_token: string;
refresh_token: string;
expires_in: number;
user: UserInfo;
}
export async function login(req: LoginRequest): Promise<LoginResponse> {
const { data } = await client.post<{ success: boolean; data: LoginResponse }>(
'/auth/login',
req
);
return data.data;
}
export async function refresh(refreshToken: string): Promise<LoginResponse> {
const { data } = await client.post<{ success: boolean; data: LoginResponse }>(
'/auth/refresh',
{ refresh_token: refreshToken }
);
return data.data;
}
export async function logout(): Promise<void> {
await client.post('/auth/logout');
}