SPB Git

spb/autoscholar

Public
1.6 KB · 56 lines tsx
1"use client";2import { useRouter } from "next/navigation";3import { useToast } from "@/components/Toast";4import { type ApiError, api } from "@/lib/client/api";56export function WorkerActions({ id, status, draining }: { id: string; status: string; draining: boolean }) {7  const router = useRouter();8  const toast = useToast();9  const run = async (path: string, body: unknown, msg: string) => {10    try {11      await api(path, { json: body });12      toast.push("success", msg);13      router.refresh();14    } catch (e) {15      toast.push("error", (e as ApiError).message);16    }17  };18  return (19    <div className="flex gap-2">20      <button21        type="button"22        className="btn btn-sm"23        onClick={() =>24          run(25            `/api/admin/workers/${id}/drain`,26            { drain: !draining },27            draining ? "Drain cleared." : "Draining: no new jobs will be leased; running jobs finish.",28          )29        }30      >31        {draining ? "Stop draining" : "Drain"}32      </button>33      {status === "quarantined" ? (34        <button35          type="button"36          className="btn btn-sm"37          onClick={() => run(`/api/admin/workers/${id}/quarantine`, { reason: null }, "Quarantine lifted.")}38        >39          Lift quarantine40        </button>41      ) : (42        <button43          type="button"44          className="btn btn-sm btn-danger"45          onClick={() => {46            const reason = prompt("Quarantine reason (recorded in the audit log):");47            if (reason) run(`/api/admin/workers/${id}/quarantine`, { reason }, "Worker quarantined.");48          }}49        >50          Quarantine51        </button>52      )}53    </div>54  );55}56
Files · main
Menu

Theme