diff --git a/src/routes/_authenticated/planes.tsx b/src/routes/_authenticated/planes.tsx index a427728..adcb6fb 100644 --- a/src/routes/_authenticated/planes.tsx +++ b/src/routes/_authenticated/planes.tsx @@ -1,4 +1,4 @@ -import { createFileRoute, useRouter, Link } from "@tanstack/react-router" +import { createFileRoute, useRouter, Link, useNavigate } from "@tanstack/react-router" import { useMemo, useState } from "react" import { supabase, useSupabaseAuth } from "@/auth/supabase" import { Input } from "@/components/ui/input" @@ -10,6 +10,8 @@ import { Plus, RefreshCcw, Building2 } from "lucide-react" import { InfoChip } from "@/components/planes/InfoChip" import { CreatePlanDialog } from "@/components/planes/CreatePlanDialog" import { chipTint } from "@/components/planes/chipTint" +import { z } from 'zod' + export type PlanDeEstudios = { @@ -23,6 +25,11 @@ type PlanRow = PlanDeEstudios & { } | null } +const planSearchSchema = z.object({ + plan: z.string().nullable() +}) + + export const Route = createFileRoute("/_authenticated/planes")({ component: RouteComponent, loader: async () => { @@ -41,29 +48,31 @@ export const Route = createFileRoute("/_authenticated/planes")({ if (error) throw new Error(error.message) return (data ?? []) as PlanRow[] }, - + validateSearch: planSearchSchema, }) function RouteComponent() { const auth = useSupabaseAuth() - const [q, setQ] = useState("") + const { plan } = Route.useSearch() const [openCreate, setOpenCreate] = useState(false) const data = Route.useLoaderData() as PlanRow[] const router = useRouter() + const navigate = useNavigate({ from: Route.fullPath }) + const showFacultad = auth.claims?.role === "lci" || auth.claims?.role === "vicerrectoria" const showCarrera = showFacultad || auth.claims?.role === "secretario_academico" const filtered = useMemo(() => { - const term = q.trim().toLowerCase() + const term = plan?.trim().toLowerCase() if (!term || !data) return data return data.filter((p) => [p.nombre, p.nivel, p.estado, p.carreras?.nombre, p.carreras?.facultades?.nombre] .filter(Boolean) .some((v) => String(v).toLowerCase().includes(term)) ) - }, [q, data]) + }, [plan, data]) return ( @@ -72,7 +81,11 @@ function RouteComponent() { Planes de estudio - setQ(e.target.value)} placeholder="Buscar por nombre, nivel, estado…" /> + navigate({ search: { plan: e.target.value } })} + placeholder="Buscar por nombre, nivel, estado…" + /> router.invalidate()} title="Recargar"> diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 5722f0b..4d07da3 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -15,7 +15,7 @@ function App() { Acad-IA {isAuth ? ( - + @@ -23,7 +23,7 @@ function App() { ) : ( - + Iniciar sesión