// Value formatting shared by the record view and the detail view. Previously // each had its own near-identical fmtVal/renderCell pair, which drifted. const MONEY_HINTS = ["amount", "tax", "price", "cost", "total", "payment", "value"]; export const isMoneyField = (key: string) => { const k = key.toLowerCase(); return MONEY_HINTS.some((h) => k.includes(h)); }; export function formatCurrency(n: number, compact = false): string { return n.toLocaleString("en-IN", { style: "currency", currency: "INR", maximumFractionDigits: 0, ...(compact ? { notation: "compact", compactDisplay: "short" } : {}), }); } export function formatDate(value: string): string { const d = new Date(value); if (Number.isNaN(d.getTime())) return value; return d.toLocaleDateString("en-IN", { day: "2-digit", month: "short", year: "numeric" }); } /** Clock time, or null when the value carries no time component. */ export function formatTime(value: string): string | null { const d = new Date(value); if (Number.isNaN(d.getTime())) return null; if (!/[T\s]\d{2}:\d{2}/.test(value)) return null; return d.toLocaleTimeString("en-IN", { hour: "2-digit", minute: "2-digit" }); } /** "3 days ago" / "in 2 days" — for aging and timeline captions. */ export function formatRelative(value: string): string | null { const d = new Date(value); if (Number.isNaN(d.getTime())) return null; const diffDays = Math.round((d.getTime() - Date.now()) / 86_400_000); if (diffDays === 0) return "today"; const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" }); if (Math.abs(diffDays) < 31) return rtf.format(diffDays, "day"); return rtf.format(Math.round(diffDays / 30), "month"); } export function formatLabel(label: string): string { return label.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()); } /** Plain-text formatting of a view value, honouring its declared data_type. */ export function formatValue(value: unknown, dataType: string, fieldKey: string): string { if (value == null || value === "") return "—"; if (dataType === "number") { const n = Number(value); if (!Number.isFinite(n)) return String(value); return isMoneyField(fieldKey) ? formatCurrency(n) : n.toLocaleString("en-IN"); } if (dataType === "date" || dataType === "datetime") return formatDate(String(value)); return String(value); }