feat: ecosistema FRASA — apps Cotizador, Alta Clientes, Cobranza y Landing
- 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
This commit is contained in:
51
apps/alta-clientes/src/forms/EconomicosCampos.tsx
Normal file
51
apps/alta-clientes/src/forms/EconomicosCampos.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { useFormContext } from 'react-hook-form'
|
||||
import { CampoNumero, CampoTexto } from '../components/Campos'
|
||||
import SectionCard from '../components/SectionCard'
|
||||
import { formatoMoneda } from '../lib/formatters'
|
||||
|
||||
interface Props {
|
||||
prefix: string
|
||||
}
|
||||
|
||||
/** Campos de datos económicos con totales calculados de solo lectura */
|
||||
export default function EconomicosCampos({ prefix }: Props) {
|
||||
const { watch } = useFormContext()
|
||||
const p = (campo: string) => `${prefix}${campo}`
|
||||
|
||||
const ingresosMensuales = Number(watch(p('ingresosMensuales'))) || 0
|
||||
const otrosIngresos = Number(watch(p('otrosIngresos'))) || 0
|
||||
const gastosLuz = Number(watch(p('gastosLuz'))) || 0
|
||||
const gastosOtros = Number(watch(p('gastosOtros'))) || 0
|
||||
|
||||
return (
|
||||
<SectionCard titulo="Datos económicos">
|
||||
<CampoNumero nombre={p('ingresosMensuales')} etiqueta="Ingresos mensuales" />
|
||||
<CampoNumero nombre={p('otrosIngresos')} etiqueta="Otros ingresos" />
|
||||
<label htmlFor={`${prefix}totalIngresos`} className="block">
|
||||
<span className="mb-1 block text-xs font-bold uppercase tracking-widest text-neutral-500">Total ingresos</span>
|
||||
<input
|
||||
id={`${prefix}totalIngresos`}
|
||||
type="text"
|
||||
readOnly
|
||||
value={formatoMoneda(ingresosMensuales + otrosIngresos)}
|
||||
className="w-full border border-neutral-200 bg-neutral-50 px-3 py-2.5 text-sm font-bold text-neutral-900"
|
||||
/>
|
||||
</label>
|
||||
<CampoNumero nombre={p('gastosLuz')} etiqueta="Gastos luz" />
|
||||
<CampoNumero nombre={p('gastosOtros')} etiqueta="Otros gastos" />
|
||||
<label htmlFor={`${prefix}gastosTotal`} className="block">
|
||||
<span className="mb-1 block text-xs font-bold uppercase tracking-widest text-neutral-500">Gastos total</span>
|
||||
<input
|
||||
id={`${prefix}gastosTotal`}
|
||||
type="text"
|
||||
readOnly
|
||||
value={formatoMoneda(gastosLuz + gastosOtros)}
|
||||
className="w-full border border-neutral-200 bg-neutral-50 px-3 py-2.5 text-sm font-bold text-neutral-900"
|
||||
/>
|
||||
</label>
|
||||
<CampoTexto nombre={p('dependientes.personas')} etiqueta="Dependientes económicos (personas)" />
|
||||
<CampoTexto nombre={p('dependientes.parentesco')} etiqueta="Parentesco" />
|
||||
<CampoTexto nombre={p('dependientes.edad')} etiqueta="Edad" />
|
||||
</SectionCard>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user