- 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
41 lines
1.4 KiB
TypeScript
41 lines
1.4 KiB
TypeScript
interface Props {
|
|
pasos: string[]
|
|
pasoActual: number
|
|
onIrAPaso: (paso: number) => void
|
|
}
|
|
|
|
/** Stepper de progreso del wizard; permite volver a pasos ya visitados */
|
|
export default function Stepper({ pasos, pasoActual, onIrAPaso }: Props) {
|
|
return (
|
|
<nav aria-label="Progreso">
|
|
<ol className="flex flex-wrap items-baseline gap-x-6 gap-y-3 border-b border-neutral-200 pb-4">
|
|
{pasos.map((nombre, i) => {
|
|
const activo = i === pasoActual
|
|
const completado = i < pasoActual
|
|
return (
|
|
<li key={nombre}>
|
|
<button
|
|
type="button"
|
|
onClick={() => completado && onIrAPaso(i)}
|
|
disabled={!completado}
|
|
aria-current={activo ? 'step' : undefined}
|
|
className={`text-xs uppercase tracking-widest transition-colors duration-150 ${
|
|
activo
|
|
? 'font-bold text-accent'
|
|
: completado
|
|
? 'font-medium text-neutral-900 hover:text-accent'
|
|
: 'font-light text-neutral-400'
|
|
}`}
|
|
title={nombre}
|
|
>
|
|
<span className="mr-2">{String(i + 1).padStart(2, '0')}</span>
|
|
<span className="hidden md:inline">{nombre}</span>
|
|
</button>
|
|
</li>
|
|
)
|
|
})}
|
|
</ol>
|
|
</nav>
|
|
)
|
|
}
|