From 8220955cd427a15e27368ef11dff5d3b5e4643ae Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 22 Feb 2026 08:03:55 -0600 Subject: [PATCH] Fix audit entry click navigation for Oversight Admin handleNavigateToAuditedItem silently failed because campaignProofs are loaded lazily (only when viewing a campaign), and errors went to a setError() state that was never rendered. Now the function fetches and caches proofs on demand when not already loaded, and uses alert() for visible error messages. Co-Authored-By: Claude Opus 4.6 --- frontend/App.tsx | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/frontend/App.tsx b/frontend/App.tsx index f10c60a..0e20f38 100755 --- a/frontend/App.tsx +++ b/frontend/App.tsx @@ -802,20 +802,38 @@ const AppContent: React.FC<{ msalInstance: any }> = ({ msalInstance }) => { }; - const handleNavigateToAuditedItem = (item: { campaignName: string; proofName: string; version: number }) => { - const proofToSelect = campaignProofs[item.campaignName]?.find(a => a.proofName === item.proofName); + const handleNavigateToAuditedItem = async (item: { campaignName: string; proofName: string; version: number }) => { + // Use cached proofs or fetch from API (e.g. Oversight Admin going straight to Auditing) + let proofs = campaignProofs[item.campaignName]; + if (!proofs) { + const campaign = campaigns.find(c => c.name === item.campaignName); + if (!campaign?._id) { + alert(`Campaign "${item.campaignName}" not found. It may have been deleted.`); + return; + } + try { + const rawProofs = await apiService.getProofs(campaign._id); + proofs = rawProofs.map(p => apiService.convertProofToFrontend(p)); + setCampaignProofs(prev => ({ ...prev, [item.campaignName]: proofs! })); + } catch (error) { + console.error('Failed to load proofs for campaign:', item.campaignName, error); + alert('Failed to load proofs. Please try again.'); + return; + } + } + + const proofToSelect = proofs.find(a => a.proofName === item.proofName); if (proofToSelect) { const versionExists = proofToSelect.versions.some((v: any) => v.version === item.version); if (versionExists) { setSelectedCampaign(item.campaignName); - // Add a temporary property to the proof object to indicate which version to show. setSelectedProof({ ...proofToSelect, initialVersion: item.version }); setCurrentView('Campaigns'); } else { - setError(`Version ${item.version} not found for proof ${item.proofName}. It may have been deleted.`); + alert(`Version ${item.version} not found for proof "${item.proofName}". It may have been deleted.`); } } else { - setError(`Proof ${item.proofName} not found in campaign ${item.campaignName}. It may have been deleted.`); + alert(`Proof "${item.proofName}" not found in campaign "${item.campaignName}". It may have been deleted.`); } };