/** * Form 16 Quick Actions – RE actions for the Quick Actions sidebar. * Shown only for Form 16 requests when RE user and no credit note yet. * Location: custom (Form 16 only); does not modify shared workflow components. */ import { useState, useEffect } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Loader2, Receipt, X, RotateCcw } from 'lucide-react'; import { getCreditNoteByRequestId, cancelForm16Submission, setForm16ResubmissionNeeded, } from '@/services/form16Api'; import { toast } from 'sonner'; interface Form16QuickActionsProps { requestId: string; request: any; onRefresh?: () => void; } export function Form16QuickActions({ requestId, request, onRefresh }: Form16QuickActionsProps) { const [creditNote, setCreditNote] = useState<{ id: number; status: string } | null>(null); const [loading, setLoading] = useState(true); const [actionLoading, setActionLoading] = useState<'cancel' | 'resubmit' | null>(null); const form16 = request?.form16Submission; const hasSubmission = !!form16; const hasCreditNote = !!creditNote && creditNote.status !== 'withdrawn'; useEffect(() => { if (!requestId) { setLoading(false); return; } let cancelled = false; (async () => { try { const note = await getCreditNoteByRequestId(requestId); if (!cancelled) setCreditNote(note ? { id: typeof note.id === 'number' ? note.id : Number(note.id), status: note.status || '' } : null); } catch { if (!cancelled) setCreditNote(null); } finally { if (!cancelled) setLoading(false); } })(); return () => { cancelled = true; }; }, [requestId]); const handleCancelSubmission = async () => { if (!requestId || !window.confirm('Cancel this Form 16 submission? The request will be marked as rejected.')) return; setActionLoading('cancel'); try { await cancelForm16Submission(requestId); toast.success('Submission cancelled'); onRefresh?.(); } catch (e) { toast.error(e instanceof Error ? e.message : 'Failed to cancel submission'); } finally { setActionLoading(null); } }; const handleResubmissionNeeded = async () => { if (!requestId || !window.confirm('Mark this submission as resubmission needed? The dealer will need to resubmit Form 16.')) return; setActionLoading('resubmit'); try { await setForm16ResubmissionNeeded(requestId); toast.success('Marked as resubmission needed'); onRefresh?.(); } catch (e) { toast.error(e instanceof Error ? e.message : 'Failed to update'); } finally { setActionLoading(null); } }; if (loading || !hasSubmission || hasCreditNote) return null; return ( Form 16 actions View the document in the Documents tab. Cancel submission or mark resubmission needed. ); }