"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import type { ApplicationStage, InterviewOutcome, SalaryRateBasis } from "@prisma/client"; import { AdminDialog } from "@/components/ui/admin-dialog"; import { advanceStage, agreeSalary, approveSalary, returnSalary, verifyDocuments, recordReferenceCheck, recordInterviewResult, requestInterviewWaiver, approveInterviewWaiver, selectCandidate, returnSelection, rejectApplication, onboardCandidate, } from "./actions"; const INPUT = "w-full rounded-lg border border-neutral-300 px-3 py-2 text-sm focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20"; const PRIMARY = "rounded-lg bg-primary-600 px-4 py-2 text-sm font-semibold text-white hover:bg-primary-700 disabled:opacity-60"; const SECONDARY = "rounded-lg border border-neutral-300 px-4 py-2 text-sm font-medium text-neutral-700 hover:bg-neutral-50 disabled:opacity-60"; const DANGER = "rounded-lg border border-danger-300 px-4 py-2 text-sm font-medium text-danger-700 hover:bg-danger-50 disabled:opacity-60"; export type ActionCardProps = { id: string; stage: ApplicationStage; isExHand: boolean; interviewResult: InterviewOutcome; interviewWaived: boolean; rejectedReason: string | null; salaryPending: boolean; waiverPending: boolean; selectionPending: boolean; employeeNo: string | null; salary: { rateBasis: SalaryRateBasis; basic: number; victualingPerDay: number; currency: string; approved: boolean } | null; perms: { manage: boolean; recordReference: boolean; recordInterview: boolean; requestWaiver: boolean; approveSalary: boolean; approveWaiver: boolean; select: boolean; onboard: boolean; }; }; function useAction() { const router = useRouter(); const [pending, setPending] = useState(false); const [error, setError] = useState(""); async function run(fn: () => Promise<{ ok: true } | { error: string }>) { setPending(true); setError(""); const res = await fn(); setPending(false); if ("error" in res) setError(res.error); else router.refresh(); return res; } return { pending, error, run }; } function Card({ title, sub, children }: { title: string; sub?: string; children: React.ReactNode }) { return (

{title}

{sub &&

{sub}

}
{children}
); } function RejectButton({ id }: { id: string }) { const router = useRouter(); const [open, setOpen] = useState(false); const [reason, setReason] = useState(""); const [pending, setPending] = useState(false); const [error, setError] = useState(""); async function submit(e: React.FormEvent) { e.preventDefault(); setPending(true); setError(""); const res = await rejectApplication(id, reason); setPending(false); if ("error" in res) setError(res.error); else { setOpen(false); router.refresh(); } } return ( <> setOpen(false)}>

Rejecting removes this candidate from the pipeline. The reason is recorded.