From c6e4a9e3c95594699e78bd60516e192c4755e29a Mon Sep 17 00:00:00 2001 From: kieran Date: Wed, 5 Mar 2025 16:26:47 +0000 Subject: [PATCH] chore: formatting --- src/api.ts | 8 +- src/main.tsx | 2 +- src/pages/vm-billing.tsx | 139 ++++++++++---------- src/pages/vm-graphs.tsx | 278 ++++++++++++++++++++++++--------------- 4 files changed, 246 insertions(+), 181 deletions(-) diff --git a/src/api.ts b/src/api.ts index b2ec5ce..c301d42 100644 --- a/src/api.ts +++ b/src/api.ts @@ -116,7 +116,7 @@ export class LNVpsApi { constructor( readonly url: string, readonly publisher: EventPublisher | undefined, - ) { } + ) {} async getAccount() { const { data } = await this.#handleResponse>( @@ -147,9 +147,9 @@ export class LNVpsApi { } async getVmTimeSeries(id: number) { - const { data } = await this.#handleResponse>>( - await this.#req(`/api/v1/vm/${id}/time-series`, "GET"), - ); + const { data } = await this.#handleResponse< + ApiResponse> + >(await this.#req(`/api/v1/vm/${id}/time-series`, "GET")); return data; } diff --git a/src/main.tsx b/src/main.tsx index f420f64..72624dc 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -61,7 +61,7 @@ const router = createBrowserRouter([ }, { path: "/vm/graphs", - element: + element: , }, { path: "/tos", diff --git a/src/pages/vm-billing.tsx b/src/pages/vm-billing.tsx index 95f3d6e..959d7ea 100644 --- a/src/pages/vm-billing.tsx +++ b/src/pages/vm-billing.tsx @@ -7,76 +7,77 @@ import { AsyncButton } from "../components/button"; import CostLabel from "../components/cost"; export function VmBillingPage() { - const location = useLocation() as { state?: VmInstance }; - const params = useParams(); - const login = useLogin(); - const navigate = useNavigate(); - const [payment, setPayment] = useState(); - const [state, setState] = useState(location?.state); - - async function reloadVmState() { - if (!state) return; - const newState = await login?.api.getVm(state.id); - setState(newState); - return newState; - } - - const renew = useCallback( - async function () { - if (!login?.api || !state) return; - const p = await login?.api.renewVm(state.id); - setPayment(p); - }, - [login?.api, state], - ); - - useEffect(() => { - if (params["action"] === "renew" && login && state) { - renew() - } - }, [login, state, params, renew]); + const location = useLocation() as { state?: VmInstance }; + const params = useParams(); + const login = useLogin(); + const navigate = useNavigate(); + const [payment, setPayment] = useState(); + const [state, setState] = useState(location?.state); + async function reloadVmState() { if (!state) return; - const expireDate = new Date(state.expires); - const days = - (expireDate.getTime() - new Date().getTime()) / 1000 / 24 / 60 / 60; - return ( -
- - < Back - -
-
Renewal for #{state.id}
- -
- {days > 0 && ( -
- Expires: {expireDate.toDateString()} ({Math.floor(days)} days) -
- )} - {days < 0 && params["action"] !== "renew" - &&
Expired
} - {!payment && ( -
- Extend Now -
- )} - {payment && ( - <> -

Renew VPS

- { - setPayment(undefined); - if (!login?.api || !state) return; - const s = await reloadVmState(); - if (params["action"] === "renew") { - navigate("/vm", { state: s }); - } - }} - /> - - )} + const newState = await login?.api.getVm(state.id); + setState(newState); + return newState; + } + + const renew = useCallback( + async function () { + if (!login?.api || !state) return; + const p = await login?.api.renewVm(state.id); + setPayment(p); + }, + [login?.api, state], + ); + + useEffect(() => { + if (params["action"] === "renew" && login && state) { + renew(); + } + }, [login, state, params, renew]); + + if (!state) return; + const expireDate = new Date(state.expires); + const days = + (expireDate.getTime() - new Date().getTime()) / 1000 / 24 / 60 / 60; + return ( +
+ + < Back + +
+
Renewal for #{state.id}
+ +
+ {days > 0 && ( +
+ Expires: {expireDate.toDateString()} ({Math.floor(days)} days)
- ); + )} + {days < 0 && params["action"] !== "renew" && ( +
Expired
+ )} + {!payment && ( +
+ Extend Now +
+ )} + {payment && ( + <> +

Renew VPS

+ { + setPayment(undefined); + if (!login?.api || !state) return; + const s = await reloadVmState(); + if (params["action"] === "renew") { + navigate("/vm", { state: s }); + } + }} + /> + + )} +
+ ); } diff --git a/src/pages/vm-graphs.tsx b/src/pages/vm-graphs.tsx index b2b8644..b61effe 100644 --- a/src/pages/vm-graphs.tsx +++ b/src/pages/vm-graphs.tsx @@ -2,120 +2,184 @@ import { Link, useLocation } from "react-router-dom"; import { TimeSeriesData, VmInstance } from "../api"; import useLogin from "../hooks/login"; import { useEffect, useState } from "react"; -import { ResponsiveContainer, XAxis, YAxis, Tooltip, LineChart, Line, Legend } from "recharts"; +import { + ResponsiveContainer, + XAxis, + YAxis, + Tooltip, + LineChart, + Line, + Legend, +} from "recharts"; export function VmGraphsPage() { - const { state } = useLocation() as { state?: VmInstance }; - const login = useLogin(); - const [data, setData] = useState>(); + const { state } = useLocation() as { state?: VmInstance }; + const login = useLogin(); + const [data, setData] = useState>(); - useEffect(() => { - if (!state) return; - login?.api.getVmTimeSeries(state.id).then(setData); - }, [login]); + useEffect(() => { + if (!state) return; + login?.api.getVmTimeSeries(state.id).then(setData); + }, [login]); - const maxRam = data?.reduce((acc, v) => { - const mb = v.memory_size / 1024 / 1024; - return acc < mb ? mb : acc; + const maxRam = + data?.reduce((acc, v) => { + const mb = v.memory_size / 1024 / 1024; + return acc < mb ? mb : acc; }, 0) ?? 0; - const KB = 1024; - const MB = 1024 * 1024; - function scaleLabel(v: number) { - switch (net_scale) { - case MB: return "MiB"; - case KB: return "KiB"; - } - return "B"; + const KB = 1024; + const MB = 1024 * 1024; + function scaleLabel(v: number) { + switch (net_scale) { + case MB: + return "MiB"; + case KB: + return "KiB"; } - const net_scale = data?.reduce((acc, v) => { - const b = Math.max(v.net_in, v.net_out); - if (b > MB && b > acc) { - return MB; - } else if (b > KB && b > acc) { - return KB; - } else { - return acc; - } + return "B"; + } + const net_scale = + data?.reduce((acc, v) => { + const b = Math.max(v.net_in, v.net_out); + if (b > MB && b > acc) { + return MB; + } else if (b > KB && b > acc) { + return KB; + } else { + return acc; + } }, 0) ?? 0; - const net_scale_label = scaleLabel(net_scale); - const disk_scale = data?.reduce((acc, v) => { - const b = Math.max(v.disk_read, v.disk_write); - if (b > MB && b > acc) { - return MB; - } else if (b > KB && b > acc) { - return KB; - } else { - return acc; - } + const net_scale_label = scaleLabel(net_scale); + const disk_scale = + data?.reduce((acc, v) => { + const b = Math.max(v.disk_read, v.disk_write); + if (b > MB && b > acc) { + return MB; + } else if (b > KB && b > acc) { + return KB; + } else { + return acc; + } }, 0) ?? 0; - const disk_scale_label = scaleLabel(disk_scale); - const sortedData = (data ?? []) - .sort((a, b) => a.timestamp - b.timestamp) - .map((v) => ({ - timestamp: new Date(v.timestamp * 1000).toLocaleTimeString(), - CPU: 100 * v.cpu, - RAM: v.memory / 1024 / 1024, - NET_IN: v.net_in / net_scale, - NET_OUT: v.net_out / net_scale, - DISK_READ: v.disk_read / disk_scale, - DISK_WRITE: v.disk_write / disk_scale, - })); - const toolTip = { - if (active && payload && payload.length) { - const data = payload[0].payload as TimeSeriesData; - return
-
{data.timestamp}
- {payload.map((p) =>
{p.name}: {Number(p.value).toFixed(2)}{p.unit}
)} - -
; - } - }} />; - return
- - < Back - -

CPU

- - - - - - {toolTip} - - -

Memory

- - - - - - {toolTip} - - -

Network

- - - - - - - {toolTip} - - - -

Disk

- - - - - - - {toolTip} - - - + const disk_scale_label = scaleLabel(disk_scale); + const sortedData = (data ?? []) + .sort((a, b) => a.timestamp - b.timestamp) + .map((v) => ({ + timestamp: new Date(v.timestamp * 1000).toLocaleTimeString(), + CPU: 100 * v.cpu, + RAM: v.memory / 1024 / 1024, + NET_IN: v.net_in / net_scale, + NET_OUT: v.net_out / net_scale, + DISK_READ: v.disk_read / disk_scale, + DISK_WRITE: v.disk_write / disk_scale, + })); + const toolTip = ( + { + if (active && payload && payload.length) { + const data = payload[0].payload as TimeSeriesData; + return ( +
+
{data.timestamp}
+ {payload.map((p) => ( +
+ {p.name}: {Number(p.value).toFixed(2)} + {p.unit} +
+ ))} +
+ ); + } + }} + /> + ); + return ( +
+ + < Back + +

CPU

+ + + + + + {toolTip} + + +

Memory

+ + + + + + {toolTip} + + +

Network

+ + + + + + + {toolTip} + + + +

Disk

+ + + + + + + {toolTip} + + +
- -} \ No newline at end of file + ); +}