refactor: update navigation links and search parameters across authenticated routes

This commit is contained in:
2025-08-29 16:51:22 -06:00
parent f8de39e6d1
commit 6c3dd54d5f
6 changed files with 41 additions and 26 deletions

View File

@@ -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 (
<div className="space-y-4">
@@ -72,7 +81,11 @@ function RouteComponent() {
<CardTitle className="text-xl">Planes de estudio</CardTitle>
<div className="flex w-full items-center gap-2 md:w-auto">
<div className="relative w-full md:w-80">
<Input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Buscar por nombre, nivel, estado…" />
<Input
value={plan ?? ''}
onChange={e => navigate({ search: { plan: e.target.value } })}
placeholder="Buscar por nombre, nivel, estado…"
/>
</div>
<Button variant="outline" size="icon" onClick={() => router.invalidate()} title="Recargar">
<RefreshCcw className="h-4 w-4" />