diff --git a/apps/web/src/components/approval/live-approval-panel.tsx b/apps/web/src/components/approval/live-approval-panel.tsx index 30264c2e..f3c06af7 100644 --- a/apps/web/src/components/approval/live-approval-panel.tsx +++ b/apps/web/src/components/approval/live-approval-panel.tsx @@ -28,6 +28,7 @@ import { GlassCardTitle, GlassCardContent, } from '@/components/ui/glass-card' +import { toast } from '@/components/ui/toast' import { StatusOrb } from '@/components/ui/status-orb' import { cn } from '@/lib/utils' import { ShieldX, Lock, AlertTriangle } from 'lucide-react' @@ -154,6 +155,7 @@ export function LiveApprovalPanel({ // Phase 20: CSRF 保護 - 必須有 Token 才能簽核 if (!csrfToken) { console.error('[HITL] CSRF token not available, cannot sign') + toast.error('安全驗證失敗,請重新整理頁面後再試') return } @@ -209,6 +211,7 @@ export function LiveApprovalPanel({ // Phase 20: CSRF 保護 - 必須有 Token 才能拒絕 if (!csrfToken) { console.error('[HITL] CSRF token not available, cannot reject') + toast.error('安全驗證失敗,請重新整理頁面後再試') return } @@ -334,7 +337,7 @@ export function LiveApprovalPanel({ onApprove={() => handleSign(approval.id, approval.riskLevel)} onReject={() => handleReject(approval.id)} holdDuration={2000} - isLoading={signingStates[approval.id] === 'signing'} + isLoading={signingStates[approval.id] === 'signing' || csrfLoading || !!csrfError} readOnly={isResolved} />