chore: initial project scaffold with admin web, backend, desktop client, and deployment setup
Add monorepo structure for NexaVPN WireGuard control plane including: - .gitignore for node_modules, build artifacts, and environment files - README with project overview, monorepo layout, and quick start guide - Admin web UI with React, Vite, TypeScript, and nginx reverse proxy - API client with type definitions for users, devices, policies, gateways, and audit logs - Admin pages for dashboard, users, devices, policies, g
This commit is contained in:
75
admin-web/src/api/client.ts
Normal file
75
admin-web/src/api/client.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
const API_BASE = import.meta.env.VITE_API_BASE_URL ?? "/api/v1";
|
||||
|
||||
export type User = {
|
||||
id: string;
|
||||
username: string;
|
||||
display_name: string;
|
||||
role: string;
|
||||
is_active: boolean;
|
||||
};
|
||||
|
||||
export type Device = {
|
||||
id: string;
|
||||
name: string;
|
||||
user_id?: string;
|
||||
platform: string;
|
||||
status: string;
|
||||
assigned_ip?: string;
|
||||
};
|
||||
|
||||
export type Policy = {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
priority: number;
|
||||
effect: string;
|
||||
full_tunnel: boolean;
|
||||
is_active: boolean;
|
||||
destinations?: string[];
|
||||
};
|
||||
|
||||
export type Gateway = {
|
||||
id: string;
|
||||
name: string;
|
||||
endpoint: string;
|
||||
public_key: string;
|
||||
listen_port: number;
|
||||
vpn_cidr: string;
|
||||
dns_servers: string[];
|
||||
is_active: boolean;
|
||||
};
|
||||
|
||||
export type AuditEvent = {
|
||||
id: string;
|
||||
event_type: string;
|
||||
entity_type: string;
|
||||
status: string;
|
||||
message: string;
|
||||
created_at: string;
|
||||
};
|
||||
|
||||
async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const token = localStorage.getItem("nexavpn_admin_token");
|
||||
const response = await fetch(`${API_BASE}${path}`, {
|
||||
...init,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
||||
...(init?.headers ?? {})
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Request failed: ${response.status}`);
|
||||
}
|
||||
|
||||
return response.json() as Promise<T>;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
users: () => request<User[]>("/admin/users"),
|
||||
devices: () => request<Device[]>("/admin/devices"),
|
||||
policies: () => request<Policy[]>("/admin/policies"),
|
||||
gateways: () => request<Gateway[]>("/admin/gateways"),
|
||||
audit: () => request<AuditEvent[]>("/admin/audit-logs")
|
||||
};
|
||||
Reference in New Issue
Block a user