// components/ProcessActions.tsx // Client component that drives the Process / Archive / Reopen buttons // for a single onboarding submission. Optimistically disables itself // while the API call is in flight and revalidates the page on success. "use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; interface Props { id: string; status: "draft" | "submitted" | "processing" | "processed" | "rejected"; directorCount: number; hasDuplicates: boolean; } export default function ProcessActions({ id, status, directorCount, hasDuplicates, }: Props) { const router = useRouter(); const [busy, setBusy] = useState<"process" | "archive" | "reopen" | null>(null); const [error, setError] = useState(null); async function call(action: "process" | "archive" | "reopen") { setBusy(action); setError(null); try { const res = await fetch(`/api/onboarding/${id}/${action}`, { method: "POST" }); if (!res.ok) { const body = await res.json().catch(() => ({ error: "Unknown error" })); throw new Error(body.error ?? `Request failed (${res.status})`); } router.refresh(); } catch (err) { setError(err instanceof Error ? err.message : "Action failed"); } finally { setBusy(null); } } const isDraft = status === "draft"; const isSubmitted = status === "submitted"; const isProcessed = status === "processed"; const isArchived = status === "rejected"; const canProcess = isSubmitted && directorCount > 0; return (

Actions

{hasDuplicates && canProcess ? (

Duplicate IDs detected — review before processing.

) : null} {error ? (

{error}

) : null} {(isSubmitted || isDraft) ? ( ) : null} {isProcessed ? ( ) : null} {(isSubmitted || isProcessed || isDraft) && !isArchived ? ( ) : null} {isArchived ? (

This submission has been archived.

) : null}
); }