From b4570f56b4bc392b4dfa21cae384f10af32d8ad4 Mon Sep 17 00:00:00 2001 From: Guillermo Arrieta Medina Date: Thu, 25 Dec 2025 19:20:12 -0600 Subject: [PATCH] =?UTF-8?q?Primera=20versi=C3=B3n=20adecuada=20del=20lista?= =?UTF-8?q?do=20de=20planes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bun.lock | 15 ++++++++ package.json | 1 + src/components/planes/Filtro.tsx | 39 ++++++++++++++------- src/components/ui/tooltip.tsx | 59 ++++++++++++++++++++++++++++++++ src/routes/planes.tsx | 39 ++++++++------------- 5 files changed, 117 insertions(+), 36 deletions(-) create mode 100644 src/components/ui/tooltip.tsx diff --git a/bun.lock b/bun.lock index 4314434..189f5f9 100644 --- a/bun.lock +++ b/bun.lock @@ -11,6 +11,7 @@ "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-slot": "^1.2.4", + "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.0.6", "@tanstack/react-devtools": "^0.7.0", "@tanstack/react-query": "^5.66.5", @@ -279,6 +280,8 @@ "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="], + "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="], + "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], @@ -295,6 +298,8 @@ "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="], + "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="], + "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.53", "", {}, "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ=="], @@ -1311,6 +1316,14 @@ "@radix-ui/react-portal/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], + "@radix-ui/react-tooltip/@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], + + "@radix-ui/react-tooltip/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], + + "@radix-ui/react-tooltip/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-visually-hidden/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="], @@ -1381,6 +1394,8 @@ "@radix-ui/react-portal/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + "@radix-ui/react-visually-hidden/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + "@tanstack/devtools/@tanstack/devtools-client/@tanstack/devtools-event-client": ["@tanstack/devtools-event-client@0.3.5", "", {}, "sha512-RL1f5ZlfZMpghrCIdzl6mLOFLTuhqmPNblZgBaeKfdtk5rfbjykurv+VfYydOFXj0vxVIoA2d/zT7xfD7Ph8fw=="], "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], diff --git a/package.json b/package.json index 93f36d2..95a361f 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-slot": "^1.2.4", + "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.0.6", "@tanstack/react-devtools": "^0.7.0", "@tanstack/react-query": "^5.66.5", diff --git a/src/components/planes/Filtro.tsx b/src/components/planes/Filtro.tsx index 7f27d81..fc65423 100644 --- a/src/components/planes/Filtro.tsx +++ b/src/components/planes/Filtro.tsx @@ -17,6 +17,11 @@ import { PopoverContent, PopoverTrigger, } from '@/components/ui/popover' +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from '@/components/ui/tooltip' import { cn } from '@/lib/utils' export type Option = { value: string; label: string } @@ -28,6 +33,7 @@ type Props = { placeholder?: string className?: string ariaLabel?: string + disabled?: boolean } const Filtro: React.FC = ({ @@ -37,6 +43,7 @@ const Filtro: React.FC = ({ placeholder = 'Seleccionar…', className, ariaLabel, + disabled, }) => { const [open, setOpen] = useState(false) @@ -46,18 +53,26 @@ const Filtro: React.FC = ({ return ( - - - + + + + + + + +

{label}

+
+
diff --git a/src/components/ui/tooltip.tsx b/src/components/ui/tooltip.tsx new file mode 100644 index 0000000..715bf76 --- /dev/null +++ b/src/components/ui/tooltip.tsx @@ -0,0 +1,59 @@ +import * as React from "react" +import * as TooltipPrimitive from "@radix-ui/react-tooltip" + +import { cn } from "@/lib/utils" + +function TooltipProvider({ + delayDuration = 0, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function Tooltip({ + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +function TooltipTrigger({ + ...props +}: React.ComponentProps) { + return +} + +function TooltipContent({ + className, + sideOffset = 0, + children, + ...props +}: React.ComponentProps) { + return ( + + + {children} + + + + ) +} + +export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } diff --git a/src/routes/planes.tsx b/src/routes/planes.tsx index ad1ca96..e92124e 100644 --- a/src/routes/planes.tsx +++ b/src/routes/planes.tsx @@ -1,16 +1,5 @@ import { createFileRoute } from '@tanstack/react-router' -import { - Activity, - BookOpenText, - Calculator, - FlaskConical, - Laptop, - PencilRuler, - Plus, - Scale, - Stethoscope, - X, -} from 'lucide-react' +import * as Icons from 'lucide-react' import { useMemo, useState } from 'react' import type { Option } from '@/components/planes/Filtro' @@ -28,7 +17,7 @@ function RouteComponent() { type Carrera = { id: string; nombre: string; facultadId: string } type Plan = { id: string - Icono: any + icon: string nombrePrograma: string nivel: string ciclos: string @@ -88,7 +77,7 @@ function RouteComponent() { const planes: Array = [ { id: 'p1', - Icono: Laptop, + icon: 'Laptop', nombrePrograma: 'Ingeniería en Sistemas Computacionales', nivel: 'Licenciatura', ciclos: '8 semestres', @@ -99,7 +88,7 @@ function RouteComponent() { }, { id: 'p2', - Icono: Stethoscope, + icon: 'Stethoscope', nombrePrograma: 'Médico Cirujano', nivel: 'Licenciatura', ciclos: '10 semestres', @@ -110,7 +99,7 @@ function RouteComponent() { }, { id: 'p3', - Icono: Calculator, + icon: 'Calculator', nombrePrograma: 'Licenciatura en Actuaría', nivel: 'Licenciatura', ciclos: '9 semestres', @@ -121,7 +110,7 @@ function RouteComponent() { }, { id: 'p4', - Icono: PencilRuler, + icon: 'PencilRuler', nombrePrograma: 'Licenciatura en Arquitectura', nivel: 'Licenciatura', ciclos: '10 semestres', @@ -132,7 +121,7 @@ function RouteComponent() { }, { id: 'p5', - Icono: Activity, + icon: 'Activity', nombrePrograma: 'Licenciatura en Fisioterapia', nivel: 'Licenciatura', ciclos: '8 semestres', @@ -143,7 +132,7 @@ function RouteComponent() { }, { id: 'p6', - Icono: Scale, + icon: 'Scale', nombrePrograma: 'Licenciatura en Derecho', nivel: 'Licenciatura', ciclos: '10 semestres', @@ -154,7 +143,7 @@ function RouteComponent() { }, { id: 'p7', - Icono: FlaskConical, + icon: 'FlaskConical', nombrePrograma: 'Químico Farmacéutico Biólogo', nivel: 'Licenciatura', ciclos: '9 semestres', @@ -221,7 +210,7 @@ function RouteComponent() {
- +
@@ -242,7 +231,7 @@ function RouteComponent() { aria-label="Nuevo plan de estudios" title="Nuevo plan de estudios" > - + Nuevo plan de estudios
@@ -276,6 +265,7 @@ function RouteComponent() { onChange={setCarreraSel} placeholder="Carrera" ariaLabel="Filtro por carrera" + disabled={facultadSel === 'todas'} />
@@ -297,7 +287,7 @@ function RouteComponent() { title="Reiniciar filtros" aria-label="Reiniciar filtros" > - + Limpiar
@@ -305,10 +295,11 @@ function RouteComponent() {
{filteredPlans.map((p) => { const fac = facultades.find((f) => f.id === p.facultadId)! + const IconComp = (Icons as any)[p.icon] ?? Icons.BookOpenText return (