import { FormEvent, useEffect, useState } from "react"; import { invoke } from "@tauri-apps/api/core"; type EnrollmentState = { assignedIp: string; resources: string[]; profileRevision: number; gatewayEndpoint: string; profilePath: string; lastSyncTime: string; tunnelStrategy: string; }; export function App() { const [serverUrl, setServerUrl] = useState("http://localhost"); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [connected, setConnected] = useState(false); const [state, setState] = useState(null); useEffect(() => { void invoke("load_state") .then((value) => { if (value) { setState(value); } }) .catch(() => undefined); }, []); async function onSubmit(event: FormEvent) { event.preventDefault(); setLoading(true); setError(null); try { const result = await invoke("enroll_device", { payload: { serverUrl, username, password } }); setState(result); } catch (err) { setError(err instanceof Error ? err.message : "Enrollment failed"); } finally { setLoading(false); } } async function toggleConnection() { const command = connected ? "disconnect_tunnel" : "connect_tunnel"; try { await invoke(command); setConnected((value) => !value); setError(null); } catch (err) { setError(err instanceof Error ? err.message : "Tunnel action failed"); } } return (

NexaVPN

Private access without manual WireGuard setup.

Enter your VPN address, username, and password. NexaVPN provisions and stores the profile for you.

{!state ? (
{error ?
{error}
: null}
) : (

Connection

{connected ? "Connected" : "Disconnected"}

Assigned VPN IP {state.assignedIp}
Gateway {state.gatewayEndpoint}
Profile revision {state.profileRevision}
Last sync {state.lastSyncTime}
Profile path {state.profilePath}
Tunnel strategy {state.tunnelStrategy}
{error ?
{error}
: null}

Allowed resources

    {state.resources.map((resource) => (
  • {resource}
  • ))}
)}
); }