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:
2026-03-15 16:32:34 +01:00
commit 830491cb0d
91 changed files with 5279 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
import { useQuery } from "@tanstack/react-query";
import { api } from "../../api/client";
import { Page } from "../../components/Page";
import { Table } from "../../components/Table";
const columns = [
{ key: "username", label: "Username" },
{ key: "name", label: "Display name" },
{ key: "role", label: "Role" },
{ key: "status", label: "Status" }
];
export function UsersPage() {
const query = useQuery({
queryKey: ["users"],
queryFn: api.users
});
const rows = query.data?.map((user) => ({
username: user.username,
name: user.display_name,
role: user.role,
status: user.is_active ? "active" : "disabled"
})) ?? [];
return (
<Page
title="Users"
subtitle="Create, disable, and manage platform identities."
actions={<button className="button">New user</button>}
>
{query.isError ? <p className="notice">Unable to load users from the API.</p> : null}
<Table
columns={columns}
rows={rows}
renderCell={(row, column) => <span>{row[column.key as keyof (typeof rows)[number]]}</span>}
/>
</Page>
);
}