vista de wizard de creación de materia

This commit is contained in:
2026-01-05 10:50:36 -06:00
parent 684a3d8662
commit d0e095c979
5 changed files with 1236 additions and 37 deletions

View File

@@ -17,7 +17,10 @@ import { Route as IndexRouteImport } from './routes/index'
import { Route as DemoTanstackQueryRouteImport } from './routes/demo/tanstack-query'
import { Route as PlanesListaRouteRouteImport } from './routes/planes/_lista/route'
import { Route as PlanesPlanIdRouteRouteImport } from './routes/planes/$planId/route'
import { Route as AsignaturasListaRouteRouteImport } from './routes/asignaturas/_lista/route'
import { Route as AsignaturasAsignaturaIdRouteRouteImport } from './routes/asignaturas/$asignaturaId/route'
import { Route as PlanesListaNuevoRouteImport } from './routes/planes/_lista/nuevo'
import { Route as AsignaturasListaNuevaRouteImport } from './routes/asignaturas/_lista/nueva'
const Stepper2Route = Stepper2RouteImport.update({
id: '/stepper2',
@@ -59,11 +62,27 @@ const PlanesPlanIdRouteRoute = PlanesPlanIdRouteRouteImport.update({
path: '/planes/$planId',
getParentRoute: () => rootRouteImport,
} as any)
const AsignaturasListaRouteRoute = AsignaturasListaRouteRouteImport.update({
id: '/asignaturas/_lista',
path: '/asignaturas',
getParentRoute: () => rootRouteImport,
} as any)
const AsignaturasAsignaturaIdRouteRoute =
AsignaturasAsignaturaIdRouteRouteImport.update({
id: '/asignaturas/$asignaturaId',
path: '/asignaturas/$asignaturaId',
getParentRoute: () => rootRouteImport,
} as any)
const PlanesListaNuevoRoute = PlanesListaNuevoRouteImport.update({
id: '/nuevo',
path: '/nuevo',
getParentRoute: () => PlanesListaRouteRoute,
} as any)
const AsignaturasListaNuevaRoute = AsignaturasListaNuevaRouteImport.update({
id: '/nueva',
path: '/nueva',
getParentRoute: () => AsignaturasListaRouteRoute,
} as any)
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
@@ -71,9 +90,12 @@ export interface FileRoutesByFullPath {
'/login': typeof LoginRoute
'/stepper': typeof StepperRoute
'/stepper2': typeof Stepper2Route
'/asignaturas/$asignaturaId': typeof AsignaturasAsignaturaIdRouteRoute
'/asignaturas': typeof AsignaturasListaRouteRouteWithChildren
'/planes/$planId': typeof PlanesPlanIdRouteRoute
'/planes': typeof PlanesListaRouteRouteWithChildren
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
'/asignaturas/nueva': typeof AsignaturasListaNuevaRoute
'/planes/nuevo': typeof PlanesListaNuevoRoute
}
export interface FileRoutesByTo {
@@ -82,9 +104,12 @@ export interface FileRoutesByTo {
'/login': typeof LoginRoute
'/stepper': typeof StepperRoute
'/stepper2': typeof Stepper2Route
'/asignaturas/$asignaturaId': typeof AsignaturasAsignaturaIdRouteRoute
'/asignaturas': typeof AsignaturasListaRouteRouteWithChildren
'/planes/$planId': typeof PlanesPlanIdRouteRoute
'/planes': typeof PlanesListaRouteRouteWithChildren
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
'/asignaturas/nueva': typeof AsignaturasListaNuevaRoute
'/planes/nuevo': typeof PlanesListaNuevoRoute
}
export interface FileRoutesById {
@@ -94,9 +119,12 @@ export interface FileRoutesById {
'/login': typeof LoginRoute
'/stepper': typeof StepperRoute
'/stepper2': typeof Stepper2Route
'/asignaturas/$asignaturaId': typeof AsignaturasAsignaturaIdRouteRoute
'/asignaturas/_lista': typeof AsignaturasListaRouteRouteWithChildren
'/planes/$planId': typeof PlanesPlanIdRouteRoute
'/planes/_lista': typeof PlanesListaRouteRouteWithChildren
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
'/asignaturas/_lista/nueva': typeof AsignaturasListaNuevaRoute
'/planes/_lista/nuevo': typeof PlanesListaNuevoRoute
}
export interface FileRouteTypes {
@@ -107,9 +135,12 @@ export interface FileRouteTypes {
| '/login'
| '/stepper'
| '/stepper2'
| '/asignaturas/$asignaturaId'
| '/asignaturas'
| '/planes/$planId'
| '/planes'
| '/demo/tanstack-query'
| '/asignaturas/nueva'
| '/planes/nuevo'
fileRoutesByTo: FileRoutesByTo
to:
@@ -118,9 +149,12 @@ export interface FileRouteTypes {
| '/login'
| '/stepper'
| '/stepper2'
| '/asignaturas/$asignaturaId'
| '/asignaturas'
| '/planes/$planId'
| '/planes'
| '/demo/tanstack-query'
| '/asignaturas/nueva'
| '/planes/nuevo'
id:
| '__root__'
@@ -129,9 +163,12 @@ export interface FileRouteTypes {
| '/login'
| '/stepper'
| '/stepper2'
| '/asignaturas/$asignaturaId'
| '/asignaturas/_lista'
| '/planes/$planId'
| '/planes/_lista'
| '/demo/tanstack-query'
| '/asignaturas/_lista/nueva'
| '/planes/_lista/nuevo'
fileRoutesById: FileRoutesById
}
@@ -141,6 +178,8 @@ export interface RootRouteChildren {
LoginRoute: typeof LoginRoute
StepperRoute: typeof StepperRoute
Stepper2Route: typeof Stepper2Route
AsignaturasAsignaturaIdRouteRoute: typeof AsignaturasAsignaturaIdRouteRoute
AsignaturasListaRouteRoute: typeof AsignaturasListaRouteRouteWithChildren
PlanesPlanIdRouteRoute: typeof PlanesPlanIdRouteRoute
PlanesListaRouteRoute: typeof PlanesListaRouteRouteWithChildren
DemoTanstackQueryRoute: typeof DemoTanstackQueryRoute
@@ -204,6 +243,20 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof PlanesPlanIdRouteRouteImport
parentRoute: typeof rootRouteImport
}
'/asignaturas/_lista': {
id: '/asignaturas/_lista'
path: '/asignaturas'
fullPath: '/asignaturas'
preLoaderRoute: typeof AsignaturasListaRouteRouteImport
parentRoute: typeof rootRouteImport
}
'/asignaturas/$asignaturaId': {
id: '/asignaturas/$asignaturaId'
path: '/asignaturas/$asignaturaId'
fullPath: '/asignaturas/$asignaturaId'
preLoaderRoute: typeof AsignaturasAsignaturaIdRouteRouteImport
parentRoute: typeof rootRouteImport
}
'/planes/_lista/nuevo': {
id: '/planes/_lista/nuevo'
path: '/nuevo'
@@ -211,9 +264,29 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof PlanesListaNuevoRouteImport
parentRoute: typeof PlanesListaRouteRoute
}
'/asignaturas/_lista/nueva': {
id: '/asignaturas/_lista/nueva'
path: '/nueva'
fullPath: '/asignaturas/nueva'
preLoaderRoute: typeof AsignaturasListaNuevaRouteImport
parentRoute: typeof AsignaturasListaRouteRoute
}
}
}
interface AsignaturasListaRouteRouteChildren {
AsignaturasListaNuevaRoute: typeof AsignaturasListaNuevaRoute
}
const AsignaturasListaRouteRouteChildren: AsignaturasListaRouteRouteChildren = {
AsignaturasListaNuevaRoute: AsignaturasListaNuevaRoute,
}
const AsignaturasListaRouteRouteWithChildren =
AsignaturasListaRouteRoute._addFileChildren(
AsignaturasListaRouteRouteChildren,
)
interface PlanesListaRouteRouteChildren {
PlanesListaNuevoRoute: typeof PlanesListaNuevoRoute
}
@@ -231,6 +304,8 @@ const rootRouteChildren: RootRouteChildren = {
LoginRoute: LoginRoute,
StepperRoute: StepperRoute,
Stepper2Route: Stepper2Route,
AsignaturasAsignaturaIdRouteRoute: AsignaturasAsignaturaIdRouteRoute,
AsignaturasListaRouteRoute: AsignaturasListaRouteRouteWithChildren,
PlanesPlanIdRouteRoute: PlanesPlanIdRouteRoute,
PlanesListaRouteRoute: PlanesListaRouteRouteWithChildren,
DemoTanstackQueryRoute: DemoTanstackQueryRoute,

View File

@@ -0,0 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/asignaturas/$asignaturaId')({
component: RouteComponent,
})
function RouteComponent() {
return <div>Hello "/asignaturas/$asignaturaId"!</div>
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
import { createFileRoute, Outlet } from '@tanstack/react-router'
export const Route = createFileRoute('/asignaturas/_lista')({
component: RouteComponent,
})
function RouteComponent() {
return (
<main className="bg-background min-h-screen w-full">
<div className="mx-auto flex w-full max-w-7xl flex-col gap-4 px-4 py-6 md:px-6 lg:px-8">
<Outlet />
</div>
</main>
)
}

View File

@@ -692,7 +692,7 @@ function PasoBasicos({
))}
</select>
</div> */}
<div className="grid gap-2">
<div className="grid gap-1">
<Label htmlFor="facultad">Facultad</Label>
<Select
value={wizard.datosBasicos.facultadId}
@@ -725,70 +725,87 @@ function PasoBasicos({
<div className="grid gap-1">
<Label htmlFor="carrera">Carrera</Label>
<select
id="carrera"
className="bg-background text-foreground ring-offset-background focus-visible:ring-ring h-10 w-full rounded-md border px-3 text-sm shadow-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"
<Select
value={wizard.datosBasicos.carreraId}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
onValueChange={(value) =>
onChange((w) => ({
...w,
datosBasicos: { ...w.datosBasicos, carreraId: e.target.value },
datosBasicos: { ...w.datosBasicos, carreraId: value },
}))
}
disabled={!wizard.datosBasicos.facultadId}
>
<option value="">Selecciona carrera</option>
<SelectTrigger
id="carrera"
className="w-full min-w-0 [&>span]:block! [&>span]:truncate!"
>
<SelectValue placeholder="Selecciona carrera…" />
</SelectTrigger>
<SelectContent>
{carrerasFiltradas.map((c) => (
<option key={c.id} value={c.id}>
<SelectItem key={c.id} value={c.id}>
{c.nombre}
</option>
</SelectItem>
))}
</select>
</SelectContent>
</Select>
</div>
<div className="grid gap-1">
<Label htmlFor="nivel">Nivel</Label>
<select
id="nivel"
className="bg-background text-foreground ring-offset-background focus-visible:ring-ring h-10 w-full rounded-md border px-3 text-sm shadow-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"
<Select
value={wizard.datosBasicos.nivel}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
onValueChange={(value) =>
onChange((w) => ({
...w,
datosBasicos: { ...w.datosBasicos, nivel: e.target.value },
datosBasicos: { ...w.datosBasicos, nivel: value },
}))
}
>
<option value="">Selecciona nivel</option>
<SelectTrigger
id="nivel"
className="w-full min-w-0 [&>span]:block! [&>span]:truncate!"
>
<SelectValue placeholder="Selecciona nivel…" />
</SelectTrigger>
<SelectContent>
{NIVELES.map((n) => (
<option key={n} value={n}>
<SelectItem key={n} value={n}>
{n}
</option>
</SelectItem>
))}
</select>
</SelectContent>
</Select>
</div>
<div className="grid gap-1">
<Label htmlFor="tipoCiclo">Tipo de ciclo</Label>
<select
id="tipoCiclo"
className="bg-background text-foreground ring-offset-background focus-visible:ring-ring h-10 w-full rounded-md border px-3 text-sm shadow-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"
<Select
value={wizard.datosBasicos.tipoCiclo}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
onValueChange={(value) =>
onChange((w) => ({
...w,
datosBasicos: {
...w.datosBasicos,
tipoCiclo: e.target.value as TipoCiclo,
tipoCiclo: value as TipoCiclo,
},
}))
}
>
<SelectTrigger
id="tipoCiclo"
className="w-full min-w-0 [&>span]:block! [&>span]:truncate!"
>
<SelectValue />
</SelectTrigger>
<SelectContent>
{TIPOS_CICLO.map((t) => (
<option key={t.value} value={t.value}>
<SelectItem key={t.value} value={t.value}>
{t.label}
</option>
</SelectItem>
))}
</select>
</SelectContent>
</Select>
</div>
<div className="grid gap-1">
@@ -803,7 +820,7 @@ function PasoBasicos({
...w,
datosBasicos: {
...w.datosBasicos,
numCiclos: Number(e.target.value || 0),
numCiclos: Number(e.target.value || 1),
},
}))
}