diff --git a/src/routes/_authenticated/asignaturas.tsx b/src/routes/_authenticated/asignaturas.tsx index 61bf08b..b6a1160 100644 --- a/src/routes/_authenticated/asignaturas.tsx +++ b/src/routes/_authenticated/asignaturas.tsx @@ -169,6 +169,36 @@ function RouteComponent() { const [groupBy, setGroupBy] = useState<'semestre' | 'ninguno'>('semestre') const [flag, setFlag] = useState<'' | 'sinBibliografia' | 'sinCriterios' | 'sinContenidos'>(search.f ?? '') +const [facultad, setFacultad] = useState("todas") +const [carrera, setCarrera] = useState("todas") + + +// 🟣 Lista única de facultades +const facultadesList = useMemo(() => { + const unique = new Map() + planes?.forEach((p) => { + const fac = p.carrera?.facultad + if (fac?.id && fac?.nombre) unique.set(fac.id, fac.nombre) + }) + return Array.from(unique.entries()) +}, [planes]) + +// 🎓 Lista de carreras según la facultad seleccionada +const carrerasList = useMemo(() => { + const unique = new Map() + planes?.forEach((p) => { + if ( + p.carrera?.id && + p.carrera?.nombre && + (!facultad || facultad === "todas" || p.carrera?.facultad?.id === facultad) + ) { + unique.set(p.carrera.id, p.carrera.nombre) + } + }) + return Array.from(unique.entries()) +}, [planes, facultad]) + + // NEW: Clonado individual const [cloneOpen, setCloneOpen] = useState(false) const [cloneTarget, setCloneTarget] = useState(null) @@ -217,28 +247,30 @@ function RouteComponent() { return { sinBibliografia, sinCriterios, sinContenidos } }, [asignaturas]) - // Filtrado const filtered = useMemo(() => { - const t = q.trim().toLowerCase() - return asignaturas.filter(a => { - const matchesQ = - !t || - [a.nombre, a.clave, a.tipo, a.objetivos, a.plan?.nombre, a.plan?.carrera?.nombre, a.plan?.carrera?.facultad?.nombre] - .filter(Boolean) - .some(v => String(v).toLowerCase().includes(t)) + const t = q.trim().toLowerCase() + return asignaturas.filter(a => { + const matchesQ = + !t || + [a.nombre, a.clave, a.tipo, a.objetivos, a.plan?.nombre, a.plan?.carrera?.nombre, a.plan?.carrera?.facultad?.nombre] + .filter(Boolean) + .some(v => String(v).toLowerCase().includes(t)) - const semOK = sem === 'todos' || String(a.semestre ?? '—') === sem - const tipoOK = tipo === 'todos' || (a.tipo ?? '—') === tipo + const semOK = sem === 'todos' || String(a.semestre ?? '—') === sem + const tipoOK = tipo === 'todos' || (a.tipo ?? '—') === tipo + const carreraOK = carrera === 'todas' || a.plan?.carrera?.id === carrera + const facultadOK = facultad === 'todas' || a.plan?.carrera?.facultad?.id === facultad - const flagOK = - !flag || - (flag === 'sinBibliografia' && (!a.bibliografia || a.bibliografia.length === 0)) || - (flag === 'sinCriterios' && (!a.criterios_evaluacion || !a.criterios_evaluacion.trim())) || - (flag === 'sinContenidos' && (!a.contenidos || Object.keys(a.contenidos ?? {}).length === 0)) + const flagOK = + !flag || + (flag === 'sinBibliografia' && (!a.bibliografia || a.bibliografia.length === 0)) || + (flag === 'sinCriterios' && (!a.criterios_evaluacion || !a.criterios_evaluacion.trim())) || + (flag === 'sinContenidos' && (!a.contenidos || Object.keys(a.contenidos ?? {}).length === 0)) + + return matchesQ && semOK && tipoOK && flagOK && carreraOK && facultadOK + }) +}, [q, sem, tipo, flag, carrera, facultad, asignaturas]) - return matchesQ && semOK && tipoOK && flagOK - }) - }, [q, sem, tipo, flag, asignaturas]) // Agrupación const groups = useMemo(() => { @@ -257,7 +289,7 @@ function RouteComponent() { }, [filtered, groupBy]) // Helpers - const clearFilters = () => { setQ(''); setSem('todos'); setTipo('todos'); setFlag('') } + const clearFilters = () => { setQ(''); setSem('todos'); setTipo('todos'); setCarrera('todas'); setFlag('') } // NEW: util para clonar 1 asignatura async function cloneOne(src: Asignatura, overrides: { @@ -394,7 +426,7 @@ function RouteComponent() { {/* Filtros */} -
+
- - { + setFacultad(val) + setCarrera("todas") // reset de carrera al cambiar facultad + }} + > + + + + + Todas las facultades + {facultadesList.map(([id, nombre]) => ( + + {nombre} + + ))}
+ {facultad && facultad !== "todas" && (
- - setCarrera(val)} + > + + + - Por semestre - Sin agrupación + Todas las carreras + {carrerasList.map(([id, nombre]) => ( + + {nombre} + + ))}
+ )}
+ {/* Chips de salud */}