- Se unificó el stepper en cinco pasos y se configuró para omitir el paso "Biblioteca" cuando el método sea MANUAL. - Se añadió el paso "Biblioteca" con un accordion múltiple para comparar cada sugerencia con alternativas de la biblioteca; se eliminaron los estados de "Buscando" y su badge. - Se incorporaron tres conjuntos hardcodeados de coincidencias (0, 2 y 5) que se asignan al azar si la sugerencia no trae datos de biblioteca; si no hay coincidencias la sugerencia se marca automáticamente como mantenida. - Se implementó BookSelectionAccordion para elegir conservar la sugerencia o sustituirla por una coincidencia; se preservó el estilo visual de las opciones. - Se añadieron validaciones y comportamientos de navegación: bloqueo de avance si quedan accordions por revisar, apertura y scroll al primer accordion sin resolver, y salto del paso "Biblioteca" en modo MANUAL.
76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
import { CircularProgress } from '@/components/CircularProgress'
|
|
import { StepWithTooltip } from '@/components/wizard/StepWithTooltip'
|
|
|
|
export function WizardResponsiveHeader({
|
|
wizard,
|
|
methods,
|
|
titleOverrides,
|
|
hiddenStepIds,
|
|
}: {
|
|
wizard: any
|
|
methods: any
|
|
titleOverrides?: Record<string, string>
|
|
hiddenStepIds?: Array<string>
|
|
}) {
|
|
const hidden = new Set(hiddenStepIds ?? [])
|
|
const visibleSteps = (wizard.steps as Array<any>).filter(
|
|
(s) => s && !hidden.has(s.id),
|
|
)
|
|
|
|
const idx = visibleSteps.findIndex((s) => s.id === methods.current.id)
|
|
const safeIdx = idx >= 0 ? idx : 0
|
|
const totalSteps = visibleSteps.length
|
|
const currentIndex = Math.min(safeIdx + 1, totalSteps)
|
|
const hasNextStep = safeIdx < totalSteps - 1
|
|
const nextStep = visibleSteps[safeIdx + 1]
|
|
|
|
const resolveTitle = (step: any) => titleOverrides?.[step?.id] ?? step?.title
|
|
|
|
return (
|
|
<>
|
|
<div className="block sm:hidden">
|
|
<div className="flex items-center gap-5">
|
|
<CircularProgress current={currentIndex} total={totalSteps} />
|
|
<div className="flex flex-col justify-center">
|
|
<h2 className="text-lg font-bold text-slate-900">
|
|
<StepWithTooltip
|
|
title={resolveTitle(methods.current)}
|
|
desc={methods.current.description}
|
|
/>
|
|
</h2>
|
|
{hasNextStep && nextStep ? (
|
|
<p className="text-sm text-slate-400">
|
|
Siguiente: {resolveTitle(nextStep)}
|
|
</p>
|
|
) : (
|
|
<p className="text-sm font-medium text-green-500">
|
|
¡Último paso!
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="hidden sm:block">
|
|
<wizard.Stepper.Navigation className="border-border/60 rounded-xl border bg-slate-50 p-2">
|
|
{visibleSteps.map((step: any, visibleIdx: number) => (
|
|
<wizard.Stepper.Step
|
|
key={step.id}
|
|
of={step.id}
|
|
icon={visibleIdx + 1}
|
|
className="whitespace-nowrap"
|
|
>
|
|
<wizard.Stepper.Title>
|
|
<StepWithTooltip
|
|
title={resolveTitle(step)}
|
|
desc={step.description}
|
|
/>
|
|
</wizard.Stepper.Title>
|
|
</wizard.Stepper.Step>
|
|
))}
|
|
</wizard.Stepper.Navigation>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|