From 734d4916c0ed169ad231abded9ac5ae03ee49f0a Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Sat, 4 Jul 2026 06:31:30 +0000 Subject: [PATCH] Add "Retry all failed" button to /recent outreach MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Retries every failed/timed-out row in one click instead of clicking each Retry. Runs the existing retryRecentOutreach sequentially (the browser concurrency cap already throttles the worker) with a live "Retrying x/N…" counter, then refreshes so the live status/progress bar takes over. Co-Authored-By: Claude Opus 4.8 --- app/(marketing)/recent/outreach-form.tsx | 60 ++++++++++++++++++++---- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/app/(marketing)/recent/outreach-form.tsx b/app/(marketing)/recent/outreach-form.tsx index 6b2b0f33..0590a99b 100644 --- a/app/(marketing)/recent/outreach-form.tsx +++ b/app/(marketing)/recent/outreach-form.tsx @@ -131,14 +131,21 @@ export function RecentOutreachForm({
History - {progress.inFlight ? ( - - - Live · updating… - - ) : ( - Idle - )} + + h.status === "failed" || h.status === "timed_out") + .map((h) => h.id)} + /> + {progress.inFlight ? ( + + + Live · updating… + + ) : ( + Idle + )} +
{history.map((h) => ( @@ -322,6 +329,43 @@ export function RecentOutreachForm({ ); } +function RetryAllFailedButton({ messageIds }: { messageIds: string[] }) { + const router = useRouter(); + const [pending, start] = useTransition(); + const [progress, setProgress] = useState<{ done: number; total: number } | null>(null); + + if (messageIds.length === 0) return null; + + return ( + + + + ); +} + function RetryOutreachButton({ messageId }: { messageId: string }) { const router = useRouter(); const [pending, start] = useTransition();