-
-
- ) =>
- onChange((w) => ({
- ...w,
- datosBasicos: { ...w.datosBasicos, nombrePlan: e.target.value },
- }))
- }
- />
-
-
- {/*
-
-
-
*/}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ) =>
- onChange((w) => ({
- ...w,
- datosBasicos: {
- ...w.datosBasicos,
- numCiclos: Number(e.target.value || 1),
- },
- }))
- }
- />
-
-
- )
-}
-
-// Paso 3: detalles por modo
-function PasoDetalles({
- wizard,
- onChange,
- onGenerarIA,
- isLoading,
-}: {
- wizard: NewPlanWizardState
- onChange: React.Dispatch>
- onGenerarIA: () => void
- isLoading: boolean
-}) {
- if (wizard.modoCreacion === 'MANUAL') {
- return (
-
-
- Creación manual
-
- Se creará un plan en blanco con estructura mínima.
-
-
-
- )
- }
-
- if (wizard.modoCreacion === 'IA') {
- return (
-
-
-
-
-
-
- ) =>
- onChange((w) => ({
- ...w,
- iaConfig: {
- ...(w.iaConfig || ({} as any)),
- poblacionObjetivo: e.target.value,
- },
- }))
- }
- />
-
-
-
-
-
-
- Opcional: se pueden adjuntar recursos IA más adelante.
-
-
-
-
- {wizard.resumen.previewPlan && (
-
-
- Preview IA
-
- Materias aprox.: {wizard.resumen.previewPlan.numMateriasAprox}
-
-
-
-
- {wizard.resumen.previewPlan.secciones?.map((s) => (
- -
-
- {s.titulo}:
- {' '}
- {s.resumen}
-
- ))}
-
-
-
- )}
-
- )
- }
-
- if (
- wizard.modoCreacion === 'CLONADO' &&
- wizard.subModoClonado === 'INTERNO'
- ) {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
- ) => {
- const term = e.target.value.toLowerCase()
- // Podrías guardar este término en estado local si quisieras.
- void term
- }}
- />
-
-
-
-
- {PLANES_EXISTENTES.filter(
- (p) =>
- (!wizard.datosBasicos.facultadId ||
- p.facultadId === wizard.datosBasicos.facultadId) &&
- (!wizard.datosBasicos.carreraId ||
- p.carreraId === wizard.datosBasicos.carreraId),
- ).map((p) => (
-
- onChange((w) => ({ ...w, clonInterno: { planOrigenId: p.id } }))
- }
- role="button"
- tabIndex={0}
- >
-
-
- {p.nombre}
-
- {p.estado} · {p.anio}
-
-
- ID: {p.id}
-
-
- ))}
-
-
- )
- }
-
- if (
- wizard.modoCreacion === 'CLONADO' &&
- wizard.subModoClonado === 'TRADICIONAL'
- ) {
- return (
-
-
-
- ) =>
- onChange((w) => ({
- ...w,
- clonTradicional: {
- ...(w.clonTradicional || ({} as any)),
- archivoWordPlanId: e.target.files?.[0]
- ? `file_${e.target.files[0].name}`
- : null,
- },
- }))
- }
- />
-
-
-
- ) =>
- onChange((w) => ({
- ...w,
- clonTradicional: {
- ...(w.clonTradicional || ({} as any)),
- archivoMapaExcelId: e.target.files?.[0]
- ? `file_${e.target.files[0].name}`
- : null,
- },
- }))
- }
- />
-
-
-
- ) =>
- onChange((w) => ({
- ...w,
- clonTradicional: {
- ...(w.clonTradicional || ({} as any)),
- archivoMateriasExcelId: e.target.files?.[0]
- ? `file_${e.target.files[0].name}`
- : null,
- },
- }))
- }
- />
-
-
- Sube al menos Word y uno de los Excel para continuar.
-
-
- )
- }
-
- return (
-
-
- Selecciona un modo
-
- Elige una opción en el paso anterior para continuar.
-
-
-
- )
-}
-
-// Paso 4: resumen
-function PasoResumen({ wizard }: { wizard: NewPlanWizardState }) {
- const modo = wizard.modoCreacion
- const sub = wizard.subModoClonado
- return (
-
-
- Resumen
-
- Verifica la información antes de crear.
-
-
-
-
-
- Nombre:
-
- {wizard.datosBasicos.nombrePlan || '—'}
-
-
-
- Facultad/Carrera:
-
- {wizard.datosBasicos.facultadId || '—'} /{' '}
- {wizard.datosBasicos.carreraId || '—'}
-
-
-
- Nivel:
-
- {wizard.datosBasicos.nivel || '—'}
-
-
-
- Ciclos:
-
- {wizard.datosBasicos.numCiclos} ({wizard.datosBasicos.tipoCiclo})
-
-
-
- Modo:
-
- {modo === 'MANUAL' && 'Manual'}
- {modo === 'IA' && 'Generado con IA'}
- {modo === 'CLONADO' &&
- sub === 'INTERNO' &&
- 'Clonado desde plan del sistema'}
- {modo === 'CLONADO' &&
- sub === 'TRADICIONAL' &&
- 'Importado desde documentos tradicionales'}
-
-
- {wizard.resumen.previewPlan && (
-
-
Preview IA
-
- Materias aprox.: {wizard.resumen.previewPlan.numMateriasAprox}
-
-
- )}
-
-
-
- )
-}
diff --git a/src/routes/stepper.tsx b/src/routes/stepper.tsx
deleted file mode 100644
index b7cfb7b..0000000
--- a/src/routes/stepper.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import { createFileRoute } from '@tanstack/react-router'
-
-import { defineStepper } from '@/components/stepper'
-import { Button } from '@/components/ui/button'
-
-export const Route = createFileRoute('/stepper')({
- component: MyFirstStepper,
-})
-
-const stepperInstance = defineStepper(
- { id: 'step-1', title: 'Step 1' },
- { id: 'step-2', title: 'Step 2' },
- { id: 'step-3', title: 'Step 3' },
-)
-
-export function MyFirstStepper() {
- return (
-
- {({ methods }) => (
- <>
-
- {methods.all.map((step) => (
- methods.goTo(step.id)}
- >
-
- {step.title}
-
-
- ))}
-
- {methods.switch({
- 'step-1': (step) => ,
- 'step-2': (step) => ,
- 'step-3': (step) => ,
- })}
-
- {!methods.isLast && (
-
- )}
-
-
- >
- )}
-
- )
-}
-
-const Content = ({ id }: { id: string }) => {
- return (
-
- Content for {id}
-
- )
-}
diff --git a/src/routes/stepper2.tsx b/src/routes/stepper2.tsx
deleted file mode 100644
index 25ef11b..0000000
--- a/src/routes/stepper2.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import { createFileRoute } from '@tanstack/react-router'
-
-import { CircularProgress } from '@/components/CircularProgress'
-import { defineStepper } from '@/components/stepper' // Tu wrapper
-import { Button } from '@/components/ui/button'
-
-export const Route = createFileRoute('/stepper2')({
- component: MobileStepperView,
-})
-
-// 1. Definimos los pasos igual que siempre
-const myStepper = defineStepper(
- { id: 'contact', title: 'Contact Details' },
- { id: 'shipping', title: 'Shipping Information' },
- { id: 'billing', title: 'Billing Address' },
- { id: 'review', title: 'Payment Review' },
-)
-
-export default function MobileStepperView() {
- return (
- // Usa el Provider del wrapper para tener el contexto
-
- {({ methods }) => {
- // Calculamos índices para el gráfico
- const currentIndex =
- methods.all.findIndex((s) => s.id === methods.current.id) + 1
- const totalSteps = methods.all.length
- const nextStep = methods.all[currentIndex] // El paso siguiente (si existe)
-
- return (
-
- {/* --- AQUÍ ESTÁ LA MAGIA (Tu UI Personalizada) --- */}
-
- {/* El Gráfico Circular */}
-
-
- {/* Los Textos */}
-
-
- {methods.current.title}
-
- {nextStep && (
-
- Next: {nextStep.title}
-
- )}
-
-
- {/* ----------------------------------------------- */}
-
- {/* El contenido de los pasos (Switch) */}
-
- {methods.switch({
- contact: () =>
Formulario Contacto...
,
- shipping: () =>
Formulario Envío...
,
- billing: () =>
Formulario Facturación...
,
- review: () =>
Resumen...
,
- })}
-
-
- {/* Controles de Navegación (Footer) */}
-
-
-
-
-
- )
- }}
-
- )
-}