fix(auditoria): afluencia (validacion, update sin perder datos ni retroceder etapa, dedup cruzado, notas), alta cliente (registro tras firma, documentos por cliente, aviso de fallos) y reporte de clientes aplanado

This commit is contained in:
2026-09-18 16:05:18 +00:00
parent 4965a4488a
commit 656116c4e5
13 changed files with 295 additions and 59 deletions

View File

@@ -115,6 +115,12 @@ export default function AltaClientePage() {
const [registro, setRegistro] = useState<string>('')
const [sinConexion, setSinConexion] = useState(false)
const [errorValidacion, setErrorValidacion] = useState<string>('')
/** Falta un documento obligatorio (p. ej. INE) al avanzar del paso Documentos */
const [errorDocumentos, setErrorDocumentos] = useState('')
/** Documentos que no se pudieron subir tras registrar el alta */
const [avisoDocumentos, setAvisoDocumentos] = useState('')
/** El alta se está registrando en el servidor */
const [registrandoAlta, setRegistrandoAlta] = useState(false)
// ---------- Borradores ----------
type Pantalla = 'cargando' | 'entrada' | 'picker' | 'afluencia' | 'wizard'
@@ -327,15 +333,26 @@ export default function AltaClientePage() {
// responde, el flujo continúa solo local (los PDFs se generan igual). Con
// guardado progresivo activo se cierra por el endpoint de progreso.
const registrarAlta = async () => {
setRegistrandoAlta(true)
const res = datos.progresoId
? await completarProgreso(datos.progresoId, alta)
: await crearAltaCliente(alta)
toast.success("Alta de cliente completada")
if (res.ok) {
await subirDocumentos(res.id, alta)
const { fallidos } = await subirDocumentos(res.id, alta)
setRegistro(res.id)
setSinConexion(false)
setErrorValidacion('')
// El alta quedó registrada, pero algunos archivos no subieron: se avisa
// con el detalle para que el asesor los vuelva a adjuntar.
if (fallidos.length > 0) {
setAvisoDocumentos(
`El alta se registró, pero no se pudieron subir ${fallidos.length} documento(s): ` +
`${fallidos.map((f) => f.nombre).join(', ')}. Vuelve a adjuntarlos desde el expediente del cliente.`,
)
} else {
setAvisoDocumentos('')
}
// El alta ya quedó registrada: el borrador usado ya no hace falta
if (borradorId) {
eliminarBorrador(borradorId).catch(() => undefined)
@@ -350,6 +367,7 @@ export default function AltaClientePage() {
setSinConexion(true)
setErrorValidacion('')
}
setRegistrandoAlta(false)
}
// Pantalla de éxito tras registrar el alta (en lugar del redirect automático a Mi día)
@@ -559,6 +577,15 @@ export default function AltaClientePage() {
</div>
</div>
{avisoDocumentos !== '' && (
<p
role="alert"
className="mt-4 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-xs text-amber-800"
>
{avisoDocumentos}
</p>
)}
<div className="mt-6 flex flex-col gap-3 sm:flex-row sm:flex-wrap">
<button
type="button"
@@ -747,6 +774,14 @@ export default function AltaClientePage() {
)}
{paso === 6 && (
<>
{errorDocumentos !== '' && (
<p
role="alert"
className="mb-6 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-xs text-amber-700"
>
{errorDocumentos}
</p>
)}
{cargoDeBorrador && (
<p
role="note"
@@ -767,7 +802,14 @@ export default function AltaClientePage() {
}
onAnterior={anterior}
onSiguiente={() => {
void registrarAlta()
// La INE es obligatoria en el expediente: se avisa al pasar
// de paso (el asesor puede adjuntarla después o por la liga
// de firma), y el paso de firmas muestra lo que falte.
setErrorDocumentos(
alta.documentos.some((d) => d.slot === 'INE')
? ''
: 'Recuerda adjuntar la INE del cliente: es un documento obligatorio del expediente.',
)
siguiente()
guardarAvance(datos, paso + 1)
}}
@@ -804,6 +846,8 @@ export default function AltaClientePage() {
alta={alta}
onCambiarFirma={(f) => actualizar('firma', f)}
onAnterior={anterior}
onRegistrar={() => void registrarAlta()}
registrando={registrandoAlta}
/>
</TarjetaPaso>
</>