import { useEffect, useState } from 'react' import { Link, useNavigate, useParams } from 'react-router-dom' import { formatINR } from '@sims/domain' import { Badge, Button, ConfirmDialog, DataTable, EmptyState, ErrorState, Notice, RecordHeader, Skeleton, Toolbar, useToast, } from '@sims/ui' import { createShare, documentAction, downloadDocumentPdf, fetchPdfBlob, getClient, getDocumentFull, revokeShare, type Client, type Doc, type Share, } from '../api' import { SendDialog } from '../components/SendDialog' import { DOC_TONE, useData } from './Clients' import { PaymentForm } from './client-forms' /** One pending confirmation — replaces the browser confirm() popup with the styled dialog. */ interface Confirm { title: string; body: string; label: string; tone?: 'danger'; run: () => void } const TITLE: Record = { QUOTATION: 'Quotation', PROFORMA: 'Proforma Invoice', INVOICE: 'Tax Invoice', RECEIPT: 'Receipt', CREDIT_NOTE: 'Credit Note', } /** Friendly text for the send-route's 409s (the spec's token-death banner). */ function friendly(msg: string): string { if (msg === 'gmail-token-dead') return 'Gmail token dead — reconnect by running gmail-connect on the server, then retry.' if (msg === 'gmail-not-connected') return 'Gmail is not connected — run gmail-connect on the server first.' return msg } /** Document page: PDF preview, state-driven action bar, event timeline + email log. */ export function DocumentView() { const id = useParams()['id'] ?? '' const nav = useNavigate() const full = useData(() => getDocumentFull(id), [id]) const doc = full.data?.document const client = useData( () => (doc !== undefined ? getClient(doc.clientId) : Promise.resolve(undefined)), [doc?.clientId], ) const toast = useToast() const [busy, setBusy] = useState() const [paying, setPaying] = useState(false) const [sending, setSending] = useState(false) const [confirm, setConfirm] = useState() // PDF preview via blob URL — an