- Cotizador (/quote): 4 propuestas con formulas validadas del Excel, comparador, combobox de unidades, vigencia, PDF ANEXO A - Alta Clientes (/client): wizard 8 pasos, validacion CURP RENAPO, OCR de INE, checklist de expediente, firma digital, 5 PDFs legales - Cobranza (/pay): planes de enganche, mora, vista cobranza del dia, recibos PDF, bitacora, dashboard con filtros - Landing (/): entrada al ecosistema - Design system StudioBlank (monocromo, acento #1B4332) en las 4 apps - 123 tests vitest
37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
const formatoMXN = new Intl.NumberFormat('es-MX', {
|
|
style: 'currency',
|
|
currency: 'MXN',
|
|
})
|
|
|
|
/** Formato monetario MXN, p. ej. $4,579,000.00 */
|
|
export function formatoMoneda(valor: number): string {
|
|
return formatoMXN.format(valor)
|
|
}
|
|
|
|
/** Fracción (0.02) a texto porcentaje (2%) */
|
|
export function formatoPorcentaje(fraccion: number): string {
|
|
return `${(fraccion * 100).toLocaleString('es-MX', { maximumFractionDigits: 2 })}%`
|
|
}
|
|
|
|
/** Fecha en formato largo es-MX: "20 de agosto de 2026" */
|
|
export function formatoFechaLarga(fecha: Date): string {
|
|
return fecha.toLocaleDateString('es-MX', { day: 'numeric', month: 'long', year: 'numeric' })
|
|
}
|
|
|
|
/** ISO 'YYYY-MM-DD' a fecha legible corta: "08/10/2027" */
|
|
export function formatoFechaCorta(iso: string): string {
|
|
return new Date(`${iso}T00:00:00`).toLocaleDateString('es-MX', {
|
|
day: '2-digit',
|
|
month: '2-digit',
|
|
year: 'numeric',
|
|
})
|
|
}
|
|
|
|
/** Fecha ISO del día (para nombre de archivo): 'YYYY-MM-DD' */
|
|
export function fechaISOHoy(fecha: Date = new Date()): string {
|
|
const y = fecha.getFullYear()
|
|
const m = String(fecha.getMonth() + 1).padStart(2, '0')
|
|
const d = String(fecha.getDate()).padStart(2, '0')
|
|
return `${y}-${m}-${d}`
|
|
}
|