refactor: update navigation links and search parameters across authenticated routes
This commit is contained in:
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user