From d653ca00954c37da0824549ca6348496f23953c4 Mon Sep 17 00:00:00 2001 From: Alexandre Brandizzi Date: Fri, 25 Sep 2026 01:50:27 -0300 Subject: [PATCH] fix(vendor-portal): hold uplift submit until the evidence check settles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Picking a video as uplift evidence reads its movie header before the file is stored in form state. A submit that landed inside that window validated the previous (usually empty) evidence, showed the missing-evidence error and dropped the request, forcing a second click. The submit button is now disabled and reads "Checking evidence…" while the latest pick is being checked, and the submit handler ignores submissions in that window. --- .../_components/uplift-request-form.tsx | 15 +++++++-- src/test/app/v/uplift-request-form.test.tsx | 32 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/app/v/[token]/dispatch/_components/uplift-request-form.tsx b/src/app/v/[token]/dispatch/_components/uplift-request-form.tsx index fa50f2b9..0ee1744a 100644 --- a/src/app/v/[token]/dispatch/_components/uplift-request-form.tsx +++ b/src/app/v/[token]/dispatch/_components/uplift-request-form.tsx @@ -43,12 +43,15 @@ export function UpliftRequestForm({ const [reason, setReason] = useState(initialReason); const [evidenceFile, setEvidenceFile] = useState(); const [formError, setFormError] = useState(""); + const [checkingEvidence, setCheckingEvidence] = useState(false); const latestSelection = useRef(0); const showApprovalFields = mode === "revise" || isApprovalRequired(requested, currentNte); const submit = (event: React.FormEvent) => { event.preventDefault(); + // The picked file is not in state until its check settles; submitting now would validate the old one. + if (checkingEvidence) return; const amount = Number.parseFloat(requested); const validationError = validateUpliftAmount(requested, currentNte, reason, { file: evidenceFile, @@ -64,11 +67,13 @@ export function UpliftRequestForm({ const chooseFile = async (file?: File) => { const selection = ++latestSelection.current; + setCheckingEvidence(Boolean(file)); const validationMessage = file ? await validateVendorDocument(file, mediaUsage) : undefined; // A newer pick may have settled while this one's video metadata was still loading. if (selection !== latestSelection.current) return; setFormError(validationMessage ?? ""); setEvidenceFile(file); + setCheckingEvidence(false); }; const shownError = errorMessage || formError; @@ -147,8 +152,14 @@ export function UpliftRequestForm({ {shownError}
- {mode === "revise" && (