Files
FRASA-CAS/apps/alta-clientes/src/components/SignaturePad.tsx
Consult AS Technology ecd4edac02 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
2026-08-21 22:27:36 +00:00

49 lines
1.3 KiB
TypeScript

import { useRef, useEffect } from 'react'
import SignatureCanvas from 'react-signature-canvas'
interface Props {
onFirma: (dataUrl: string) => void
}
/** Pad de firma del cliente; exporta PNG base64 al terminar cada trazo */
export default function SignaturePad({ onFirma }: Props) {
const ref = useRef<SignatureCanvas | null>(null)
useEffect(() => {
// Notifica firma vacía al montar (estado inicial)
onFirma('')
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const limpiar = () => {
ref.current?.clear()
onFirma('')
}
const alTerminar = () => {
const pad = ref.current
if (!pad) return
onFirma(pad.isEmpty() ? '' : pad.getTrimmedCanvas().toDataURL('image/png'))
}
return (
<div>
<div className="border border-neutral-900 bg-white">
<SignatureCanvas
ref={ref}
onEnd={alTerminar}
canvasProps={{ className: 'h-40 w-full', 'aria-label': 'Firma del cliente' }}
penColor="black"
/>
</div>
<button
type="button"
onClick={limpiar}
className="mt-4 border border-neutral-900 bg-transparent px-5 py-2.5 text-xs font-bold uppercase tracking-widest text-neutral-900 transition-colors duration-150 hover:bg-neutral-900 hover:text-white"
>
Limpiar firma
</button>
</div>
)
}