import type { DateTimeString } from '@/types/Opportunities'; const ZERO_TIME_PREFIX = '0001-01-01'; const dateFormat = new Intl.DateTimeFormat('en-GB', { day: 'numeric', month: 'short', year: 'numeric', }); const dateTimeFormat = new Intl.DateTimeFormat('en-GB', { day: 'numeric', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', }); const moneyFormat = new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'GBP', maximumFractionDigits: 0, }); // en-GB's compact suffixes are k, m and bn; amounts under £1,000 are left // whole. const shortMoneyFormat = new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'GBP', notation: 'compact', }); const countFormat = new Intl.NumberFormat('en-GB'); /** Treats null and Go's zero time.Time as "no date". */ export function parseDate(value: DateTimeString | null | undefined): Date | null { if (!value || value.startsWith(ZERO_TIME_PREFIX)) return null; const d = new Date(value); return Number.isNaN(d.getTime()) ? null : d; } /** A date for display, e.g. "3 Mar 2026", or a dash for no date. */ export function formatDate(value: DateTimeString | null | undefined): string { const d = parseDate(value); return d ? dateFormat.format(d) : '—'; } /** A date and time for display, e.g. "3 Mar 2026, 09:30", or a dash for none. */ export function formatDateTime(value: DateTimeString | null | undefined): string { const d = parseDate(value); return d ? dateTimeFormat.format(d) : '—'; } /** An amount in pounds for display, e.g. "£125,001", or a dash for none. */ export function formatMoney(value: number): string { return value > 0 ? moneyFormat.format(value) : '—'; } /** * An amount in pounds shortened with a suffix, e.g. "£250k", "£1.5m" or * "£36bn", or a dash for none. Amounts under £1,000 are shown whole. */ export function formatMoneyShort(value: number): string { return value > 0 ? shortMoneyFormat.format(value) : '—'; } /** A count for display, e.g. "4,854". */ export function formatCount(value: number): string { return countFormat.format(value); } /** * An amount in its currency for display, e.g. "€1,201", or a dash for none. * A currency code Intl doesn't know is shown after the number. */ export function formatValue(amount: number, currency: string): string { if (amount <= 0) return '—'; if (currency === '' || currency === 'GBP') return moneyFormat.format(amount); try { return new Intl.NumberFormat('en-GB', { style: 'currency', currency, maximumFractionDigits: 0, }).format(amount); } catch { return `${countFormat.format(Math.round(amount))} ${currency}`; } }