Files
sanderling/examples/folio-web/src/format.ts
T
pj af7b7e27b0 feat(folio-web): web sample app + CDP spec tests (#36)
* fix(runner): allow nil connection for web platform

* fix(testrun): skip SDK handshake for web platform

* feat(folio-web): add React/Vite web sample app

* feat(folio-web): add sanderling spec

* fix(chrome): use InsertText for multi-char text input

* feat(hierarchy): add Screen field populated from sanderling-screen attr

* fix(chrome): auto-detect viewport from CSS vars, fix InputText accumulation, expose route as screen

* fix(runner): fall back to hierarchy root screen when snapshot screen is empty

* fix(folio-web): broaden loggedIn extractor to all authenticated pages
2026-04-22 23:59:30 +07:00

68 lines
1.9 KiB
TypeScript

import type { Transaction } from './db'
const CURRENCY = '$'
export function formatCents(
cents: number,
opts: { signed?: boolean } = {},
): string {
const abs = Math.abs(cents)
const dollars = Math.floor(abs / 100)
const rem = abs % 100
const dollarsStr = dollars.toLocaleString('en-US')
const formatted = `${CURRENCY}${dollarsStr}.${rem.toString().padStart(2, '0')}`
if (cents < 0) return `-${formatted}`
if (opts.signed && cents > 0) return `+${formatted}`
return formatted
}
export function parseCents(input: string): number | null {
const trimmed = input.trim().replace(/,/g, '')
if (trimmed === '') return null
if (!/^\d+(\.\d{1,2})?$/.test(trimmed)) return null
const [whole, frac = ''] = trimmed.split('.')
const fracPadded = (frac + '00').slice(0, 2)
const total = Number(whole) * 100 + Number(fracPadded)
if (!Number.isFinite(total) || !Number.isInteger(total)) return null
if (total > Number.MAX_SAFE_INTEGER) return null
return total
}
export function signedAmount(t: Transaction): number {
return t.type === 'credit' ? t.amount : -t.amount
}
export function balanceOf(txns: Transaction[]): number {
let total = 0
for (const t of txns) total += signedAmount(t)
return total
}
export function initialsOf(name: string): string {
const parts = name.trim().split(/\s+/).filter(Boolean)
if (parts.length === 0) return '?'
if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase()
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase()
}
const DATE_FMT = new Intl.DateTimeFormat('en-US', {
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: '2-digit',
})
export function formatDate(ts: number): string {
return DATE_FMT.format(new Date(ts))
}
const CLOCK_FMT = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: '2-digit',
hour12: false,
})
export function formatClock(ts: number): string {
return CLOCK_FMT.format(new Date(ts))
}