71 lines
1.8 KiB
TypeScript
71 lines
1.8 KiB
TypeScript
import { JSX } from "preact";
|
|
import { Button } from "../components/Button.tsx";
|
|
import { ManageAction } from "../routes/api/manage.ts";
|
|
import { useEffect, useState } from "preact/hooks";
|
|
import { IS_BROWSER } from "$fresh/runtime.ts";
|
|
|
|
export function StatusManager(
|
|
props: JSX.HTMLAttributes<HTMLDivElement> & {
|
|
onAction?: (res: string) => void;
|
|
},
|
|
) {
|
|
const sendCommand = async (action: ManageAction) => {
|
|
const res = await fetch("/api/manage", {
|
|
method: "POST",
|
|
body: action,
|
|
});
|
|
const body = await res.text();
|
|
props.onAction && props.onAction(body);
|
|
};
|
|
|
|
const [status, setStatus] = useState("");
|
|
|
|
const getStatus = () => {
|
|
globalThis.statusSource = globalThis.statusSource || new EventSource('/api/manage');
|
|
|
|
globalThis.statusSource.addEventListener('status', (e) => {
|
|
setStatus(e.data);
|
|
})
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (IS_BROWSER) getStatus();
|
|
}, []);
|
|
|
|
return (
|
|
<div {...props}>
|
|
{!!status && <small>Server is {status}</small>}
|
|
<div class="flex gap-4">
|
|
<Button
|
|
color="wasabi"
|
|
disabled={!status || status === "running"}
|
|
onClick={() => sendCommand(ManageAction.start)}
|
|
>
|
|
Start
|
|
</Button>
|
|
<Button
|
|
color="fire"
|
|
disabled={!status || status === "stopped"}
|
|
onClick={() => sendCommand(ManageAction.stop)}
|
|
>
|
|
Stop
|
|
</Button>
|
|
<Button
|
|
color="sky"
|
|
disabled={!status}
|
|
onClick={() => sendCommand(ManageAction.restart)}
|
|
>
|
|
Restart
|
|
</Button>
|
|
<Button
|
|
color="grape"
|
|
disabled={!status}
|
|
onClick={() => sendCommand(ManageAction.kill)}
|
|
>
|
|
Kill
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|