'use client'; import { useSuspenseQuery } from '@tanstack/react-query'; import { Badge } from '@/components/ui/badge'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Separator } from '@/components/ui/separator'; import { quotationDocumentPreviewOptions } from '@/features/crm/quotations/document/queries'; function Field({ label, value }: { label: string; value: string | null | undefined }) { return (
{label}
{value || '-'}
); } export function QuotationDocumentPreview({ quotationId }: { quotationId: string }) { const { data } = useSuspenseQuery(quotationDocumentPreviewOptions(quotationId)); const { documentData, template } = data.preview; const topicGroups: Array<{ key: 'scope' | 'exclusion' | 'payment'; title: string }> = [ { key: 'scope', title: 'Scope' }, { key: 'exclusion', title: 'Exclusions' }, { key: 'payment', title: 'Payment Terms' } ]; return (
{documentData.company.name} Quotation Preview using {template.template.templateName} v{template.version.version}
{documentData.watermarkStatus ? ( {documentData.watermarkStatus} ) : ( Approved Ready )} {template.template.fileType}
Quotation Header Commercial identity and issue information. Customer Block Bill-to and attention context for the document.
Project Information Scope summary and reference data for the customer. Items Table Normalized line items prepared for template mapping.
Item
Description
Qty
Unit
Unit Price
Total
{documentData.items.map((item) => (
{item.itemNumber}
{item.description}
{item.productTypeLabel || '-'}
{item.quantity}
{item.unitLabel || '-'}
{item.unitPrice.toLocaleString()}
{item.totalPrice.toLocaleString()}
))}
Topics Scope, exclusions, and payment terms from topic records. {topicGroups.map((group) => { const entries = documentData.topics[group.key]; return (
{group.title}
{!entries.length ? (
No entries
) : ( entries.map((entry) => (
{entry.title}
    {entry.items.map((item) => (
  • {item}
  • ))}
)) )}
); })}
Price Summary
Subtotal {documentData.quotation.subtotal.toLocaleString()}
Tax {documentData.quotation.taxAmount.toLocaleString()}
Total {documentData.quotation.totalAmount.toLocaleString()}
Approval Block Prepared for watermark and approval snapshot flows. {!documentData.approval.approvers.length ? (
No approval actions recorded.
) : ( documentData.approval.approvers.map((item) => (
Step {item.stepNumber} - {item.roleName}
{item.actorName || '-'} {item.actedAt ? `on ${new Date(item.actedAt).toLocaleString()}` : ''}
)) )}
Signature Placeholders
); }