From 6c3dd54d5f70e7f9de3b1c11176924f060d1cdb6 Mon Sep 17 00:00:00 2001 From: Alejandro Rosales Date: Fri, 29 Aug 2025 16:51:22 -0600 Subject: [PATCH] refactor: update navigation links and search parameters across authenticated routes --- src/routes/_authenticated.tsx | 3 ++- src/routes/_authenticated/asignaturas.tsx | 4 ++-- src/routes/_authenticated/dashboard.tsx | 21 +++++++++--------- src/routes/_authenticated/plan/$planId.tsx | 10 ++++----- src/routes/_authenticated/planes.tsx | 25 ++++++++++++++++------ src/routes/index.tsx | 4 ++-- 6 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/routes/_authenticated.tsx b/src/routes/_authenticated.tsx index 015d453..f0838fb 100644 --- a/src/routes/_authenticated.tsx +++ b/src/routes/_authenticated.tsx @@ -102,7 +102,7 @@ function Layout() { {/* Brand */} - + @@ -165,6 +165,7 @@ function Sidebar({ onNavigate }: { onNavigate?: () => void }) { [...planesKeys.root, 'all'] as const, } -async function fetchPlanIdsByScope(search: Pick): Promise { +async function fetchPlanIdsByScope(search: Pick): Promise { const { planId, carreraId, facultadId } = search if (planId) return [planId] if (carreraId) { @@ -369,7 +369,7 @@ function RouteComponent() { Nueva asignatura diff --git a/src/routes/_authenticated/dashboard.tsx b/src/routes/_authenticated/dashboard.tsx index d44b1ed..38c1efc 100644 --- a/src/routes/_authenticated/dashboard.tsx +++ b/src/routes/_authenticated/dashboard.tsx @@ -1,4 +1,4 @@ -import { createFileRoute, Link, useRouter } from '@tanstack/react-router' +import { createFileRoute, Link, useNavigate, useRouter } from '@tanstack/react-router' import { useSuspenseQuery, queryOptions, useQueryClient } from '@tanstack/react-query' import { supabase, useSupabaseAuth } from '@/auth/supabase' import * as Icons from 'lucide-react' @@ -178,6 +178,8 @@ function RouteComponent() { const isAdmin = !!auth.claims?.claims_admin const role = auth.claims?.role as 'lci' | 'vicerrectoria' | 'secretario_academico' | 'jefe_carrera' | 'planeacion' | undefined + const navigate = useNavigate({ from: Route.fullPath }) + // Mensaje contextual const roleHint = useMemo(() => { switch (role) { @@ -227,7 +229,7 @@ function RouteComponent() { if (e.key === 'Enter') { const q = (e.target as HTMLInputElement).value.trim() if (!q) return - router.navigate({ to: '/planes', search: { q } }) + navigate({ to: '/planes', search: { plan: q } }) } }} /> @@ -246,7 +248,7 @@ function RouteComponent() { {/* Atajos rápidos (según rol) */}
- + Nuevo plan - - - - + + + +
{/* Calidad + Salud */} @@ -344,9 +346,8 @@ function HealthRow({ label, value, to }: { label: string; value: number; to: str return ( {label} {value} diff --git a/src/routes/_authenticated/plan/$planId.tsx b/src/routes/_authenticated/plan/$planId.tsx index a7e64c2..efeda6f 100644 --- a/src/routes/_authenticated/plan/$planId.tsx +++ b/src/routes/_authenticated/plan/$planId.tsx @@ -65,7 +65,7 @@ function RouteComponent() {
@@ -345,10 +345,10 @@ function AsignaturaPreviewCard({ asignatura }: { asignatura: AsignaturaLite }) { const tipo = (extra?.tipo ?? "").toLowerCase() const tipoChip = tipo.includes("oblig") ? "bg-emerald-50 text-emerald-700 border-emerald-200" : - tipo.includes("opt") ? "bg-amber-50 text-amber-800 border-amber-200" : - tipo.includes("taller") ? "bg-indigo-50 text-indigo-700 border-indigo-200" : - tipo.includes("lab") ? "bg-sky-50 text-sky-700 border-sky-200" : - "bg-neutral-100 text-neutral-700 border-neutral-200" + tipo.includes("opt") ? "bg-amber-50 text-amber-800 border-amber-200" : + tipo.includes("taller") ? "bg-indigo-50 text-indigo-700 border-indigo-200" : + tipo.includes("lab") ? "bg-sky-50 text-sky-700 border-sky-200" : + "bg-neutral-100 text-neutral-700 border-neutral-200" return (
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…" + />
) : ( - +