89 lines
3.1 KiB
TypeScript
89 lines
3.1 KiB
TypeScript
import { type Component, createResource, For, Show } from "solid-js";
|
|
import { commandsApi } from "../api/client";
|
|
import { Button } from "./ui/Button";
|
|
import { Card } from "./ui/Card";
|
|
|
|
const CommandQueue: Component = () => {
|
|
const [commands, { refetch }] = createResource(commandsApi.list);
|
|
|
|
const updateCommandStatus = async (id: number, status: string) => {
|
|
try {
|
|
await commandsApi.updateStatus(id, { status });
|
|
refetch();
|
|
} catch (err) {
|
|
console.error("Failed to update command:", err);
|
|
alert(`Error: ${err}`);
|
|
}
|
|
};
|
|
|
|
const formatDate = (dateStr: string) => {
|
|
return new Date(dateStr).toLocaleString();
|
|
};
|
|
|
|
return (
|
|
<div class="space-y-4">
|
|
<h2 class="text-2xl font-semibold">Command Queue</h2>
|
|
|
|
<Card>
|
|
<Show when={!commands.loading} fallback={<div class="p-4">Loading...</div>}>
|
|
<For
|
|
each={commands()}
|
|
fallback={<div class="p-8 text-center text-gray-500">No commands in queue</div>}
|
|
>
|
|
{(cmd) => (
|
|
<div class="border-b p-4 hover:bg-gray-50">
|
|
<div class="flex justify-between items-start">
|
|
<div class="flex-1">
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<span
|
|
class={`px-2 py-1 rounded-full text-xs font-semibold ${
|
|
cmd.status === "verified"
|
|
? "bg-green-100 text-green-800"
|
|
: cmd.status === "rejected"
|
|
? "bg-red-100 text-red-800"
|
|
: "bg-yellow-100 text-yellow-800"
|
|
}`}
|
|
>
|
|
{cmd.status}
|
|
</span>
|
|
<span class="text-sm text-gray-500">{formatDate(cmd.received_at)}</span>
|
|
</div>
|
|
<pre class="text-sm bg-gray-100 p-3 rounded overflow-x-auto">
|
|
{JSON.stringify(cmd.command, null, 2)}
|
|
</pre>
|
|
<Show when={cmd.notes}>
|
|
<div class="mt-2 text-sm text-gray-600">
|
|
<strong>Notes:</strong> {cmd.notes}
|
|
</div>
|
|
</Show>
|
|
</div>
|
|
<Show when={cmd.status === "unverified"}>
|
|
<div class="ml-4 flex flex-col gap-2">
|
|
<Button
|
|
size="sm"
|
|
variant="success"
|
|
onClick={() => updateCommandStatus(cmd.id, "verified")}
|
|
>
|
|
Verify
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="danger"
|
|
onClick={() => updateCommandStatus(cmd.id, "rejected")}
|
|
>
|
|
Reject
|
|
</Button>
|
|
</div>
|
|
</Show>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</For>
|
|
</Show>
|
|
</Card>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default CommandQueue;
|