Replace API route handlers with server actions across the app

- Delete 10 API routes (stats, system-health, update-check, jobs/trigger,
  backup/restore, person, titles import/resolve, registration/status) and
  move logic into server actions in lib/actions/settings.ts and
  lib/actions/watchlist.ts
- Refactor SystemHealthCards to accept initialData prop and hydrate Jotai
  atoms via useHydrateAtoms; replace useSystemHealth SWR hook with a
  lightweight useSystemHealthRefresh that calls getSystemHealthAction
- Convert BackupRestoreSection to use restoreBackupAction + useTransition
  instead of a raw fetch call
- Split SystemStatusCard, BackgroundJobsCard, and StorageCard into
  standalone components reading from systemHealthDataAtom
- Make SetupPage async with connection() to opt into dynamic rendering
This commit is contained in:
2026-03-06 17:31:14 -05:00
parent 73b07f5ff6
commit 8d8c49a7f0
21 changed files with 396 additions and 630 deletions
+15 -31
View File
@@ -3,6 +3,7 @@
import { useAtom } from "jotai";
import { useEffect } from "react";
import { toast } from "sonner";
import { getUpdateCheckAction } from "@/lib/actions/settings";
import { updateToastShownAtom } from "@/lib/atoms/update-check";
export function UpdateToast() {
@@ -11,38 +12,21 @@ export function UpdateToast() {
useEffect(() => {
if (shown) return;
async function check() {
try {
const res = await fetch("/api/admin/update-check");
if (!res.ok) return;
getUpdateCheckAction().then((data) => {
if (!data?.updateAvailable) return;
const data = (await res.json()) as {
updateAvailable: boolean;
currentVersion: string;
latestVersion: string | null;
releaseUrl: string | null;
};
if (data.updateAvailable) {
setShown(true);
toast.info(`Sofa v${data.latestVersion} is available`, {
description: `You're running v${data.currentVersion}.`,
duration: 15_000,
action: data.releaseUrl
? {
label: "View release",
onClick: () =>
window.open(data.releaseUrl as string, "_blank"),
}
: undefined,
});
}
} catch {
// Silently ignore network errors
}
}
check();
setShown(true);
toast.info(`Sofa v${data.latestVersion} is available`, {
description: `You're running v${data.currentVersion}.`,
duration: 15_000,
action: data.releaseUrl
? {
label: "View release",
onClick: () => window.open(data.releaseUrl as string, "_blank"),
}
: undefined,
});
});
}, [shown, setShown]);
return null;