'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 (
);
}
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
);
}