mcgrizz/islands/statusManager.tsx

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>
);
}