spb/autoscholar
Public
1"use client";2import { RESEARCH_MODE_LABELS } from "@autoscholar/schemas";3import { useRouter } from "next/navigation";4import { useToast } from "@/components/Toast";5import { type ApiError, api } from "@/lib/client/api";67export function SettingsControls({8 settings,9}: {10 settings: { dispatchPaused: boolean; publishingHalted: boolean; haltedModes: string[] };11}) {12 const router = useRouter();13 const toast = useToast();14 const set = async (key: string, value: unknown, msg: string) => {15 try {16 await api("/api/admin/settings", { json: { key, value } });17 toast.push("success", msg);18 router.refresh();19 } catch (e) {20 toast.push("error", (e as ApiError).message);21 }22 };23 return (24 <section className="surface p-4">25 <h2 className="title-3">Emergency controls</h2>26 <div className="mt-3 grid gap-3 sm:grid-cols-2">27 <label className="flex items-start gap-2 text-sm">28 <input29 type="checkbox"30 checked={settings.dispatchPaused}31 onChange={(e) =>32 set(33 "dispatch.paused",34 e.target.checked,35 e.target.checked ? "All new dispatches paused." : "Dispatch resumed.",36 )37 }38 className="mt-1"39 />40 <span>41 <strong>Pause all new research dispatches</strong>42 <span className="muted block text-xs">Workers stop leasing jobs; running jobs continue.</span>43 </span>44 </label>45 <label className="flex items-start gap-2 text-sm">46 <input47 type="checkbox"48 checked={settings.publishingHalted}49 onChange={(e) =>50 set(51 "publishing.halted",52 e.target.checked,53 e.target.checked54 ? "Automatic publication halted globally."55 : "Automatic publication resumed.",56 )57 }58 className="mt-1"59 />60 <span>61 <strong>Halt automatic publication</strong>62 <span className="muted block text-xs">Passing runs stop at awaiting approval.</span>63 </span>64 </label>65 <fieldset className="sm:col-span-2 text-sm">66 <legend className="label mb-1">Halt automatic publication for research modes</legend>67 <div className="flex flex-wrap gap-3">68 {Object.entries(RESEARCH_MODE_LABELS).map(([k, l]) => (69 <label key={k} className="flex items-center gap-1">70 <input71 type="checkbox"72 checked={settings.haltedModes.includes(k)}73 onChange={(e) =>74 set(75 "publishing.haltedModes",76 e.target.checked77 ? [...settings.haltedModes, k]78 : settings.haltedModes.filter((x) => x !== k),79 `Mode halt updated for ${l}.`,80 )81 }82 />83 {l}84 </label>85 ))}86 </div>87 </fieldset>88 </div>89 </section>90 );91}92