From 7fb7931cc36b0a3fd0e33c5c432a4c0ef227c256 Mon Sep 17 00:00:00 2001 From: Benjtalkshow Date: Mon, 1 Jun 2026 15:18:48 +0100 Subject: [PATCH] fix(decline-applicant): remove runtime crash and clean up state Three issues from PR #253 that landed unaddressed: 1. components/bounty/application-review-dashboard.tsx had a fake useEffect stub at the bottom of the file (function useEffect(arg0, arg1) { throw new Error('Function not implemented.'); }) because useEffect was used at line 67 but not imported. The dashboard crashed at runtime whenever the parent re-rendered with new applications. 2. The same file mirrored the applications prop into a reviewApplications local state and synced via the broken effect. The useDeclineApplicant hook already optimistically updates the React Query cache, so the parent re-render delivers the filtered list automatically. Dropped the local mirror, drive directly from the prop. 3. hooks/use-bounty-application.ts wrote both declineReason and declinedReason with the same value on the optimistic update. One was a typo. Kept declineReason since it matches the mutation input name. Removed the unused useMemo import along the way. --- .../bounty/application-review-dashboard.tsx | 27 ++++++------------- hooks/use-bounty-application.ts | 2 -- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/components/bounty/application-review-dashboard.tsx b/components/bounty/application-review-dashboard.tsx index 0cafb9dc..896d397b 100644 --- a/components/bounty/application-review-dashboard.tsx +++ b/components/bounty/application-review-dashboard.tsx @@ -1,5 +1,5 @@ "use client"; -import { useMemo, useState } from "react"; +import { useState } from "react"; import { Users, CheckCircle, @@ -59,14 +59,14 @@ export function ApplicationReviewDashboard({ applications, }: ApplicationReviewDashboardProps) { const [selectedForCompare, setSelectedForCompare] = useState([]); - const [reviewApplications, setReviewApplications] = useState(applications); const [declineTarget, setDeclineTarget] = useState(null); const [declineReason, setDeclineReason] = useState(""); + const { mutate: selectApplicant, isPending: isSelecting } = useSelectApplicant(); - useEffect(() => { - setReviewApplications(applications); - }, [applications]); + const { mutate: declineApplicant, isPending: isDeclining } = + useDeclineApplicant(); + const handleSelectApplicant = (applicantAddress: string) => { selectApplicant({ bountyId, @@ -75,20 +75,13 @@ export function ApplicationReviewDashboard({ }); }; - const { mutate: declineApplicant, isPending: isDeclining } = - useDeclineApplicant(); - const handleDeclineApplicant = () => { if (!declineTarget) return; - const previousApplications = reviewApplications; const applicantAddress = declineTarget.applicantAddress; const reason = declineReason.trim(); - setReviewApplications((current) => - current.filter((app) => app.applicantAddress !== applicantAddress), - ); - + // Drop the declined applicant from the comparison set if it was selected setSelectedForCompare((current) => current.filter((id) => id !== declineTarget.id), ); @@ -106,13 +99,13 @@ export function ApplicationReviewDashboard({ setDeclineReason(""); }, onError: () => { - setReviewApplications(previousApplications); toast.error("Failed to decline applicant"); }, }, ); }; - const visibleApplications = reviewApplications; + + const visibleApplications = applications; const toggleCompare = (id: string) => { if (selectedForCompare.includes(id)) { setSelectedForCompare(selectedForCompare.filter((i) => i !== id)); @@ -314,7 +307,3 @@ export function ApplicationReviewDashboard({ ); } -function useEffect(arg0: () => void, arg1: Application[][]) { - throw new Error("Function not implemented."); -} - diff --git a/hooks/use-bounty-application.ts b/hooks/use-bounty-application.ts index 8fcfd806..86cc8c78 100644 --- a/hooks/use-bounty-application.ts +++ b/hooks/use-bounty-application.ts @@ -184,7 +184,6 @@ type DeclinedApplicationRecord = { bountyId?: string; applicantAddress?: string; status?: string; - declinedReason?: string; declineReason?: string; declinedAt?: string; }; @@ -237,7 +236,6 @@ export function useDeclineApplicant() { ...application, status: "DECLINED", declineReason: reason?.trim() || undefined, - declinedReason: reason?.trim() || undefined, declinedAt, } : application,