Skip to content

Commit

Permalink
fix: arregle un error relacionado con el responsive
Browse files Browse the repository at this point in the history
  • Loading branch information
MirandaAriano committed Dec 12, 2024
1 parent 81cc16a commit 73a8365
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 77 deletions.
39 changes: 14 additions & 25 deletions FrontAdmin/src/components/Pages/Estadisticas/Estadisticas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,95 +7,84 @@ import SubMenuContent from '../../SubMenu/SubMenuContent';
function Estadisticas() {
const { isOpen, onOpen, onClose } = useDisclosure();

// Definir el ancho de la caja de SubMenuContent según el tamaño de la pantalla
const isMobile = useBreakpointValue({ base: true, xl: false });

// Estado para controlar la visibilidad del botón de hamburguesa
const [showHamburger, setShowHamburger] = useState(true);
const [lastScrollY, setLastScrollY] = useState(0);

// Función que maneja el desplazamiento
const handleScroll = () => {
if (window.scrollY > lastScrollY) {
// Si el desplazamiento es hacia abajo, ocultamos el botón
setShowHamburger(false);
} else {
// Si el desplazamiento es hacia arriba, mostramos el botón
setShowHamburger(true);
}
setLastScrollY(window.scrollY); // Actualizamos la posición del scroll
setLastScrollY(window.scrollY);
};

// Usamos useEffect para agregar el evento de scroll al montar el componente
useEffect(() => {
window.addEventListener('scroll', handleScroll);

// Limpiamos el evento cuando el componente se desmonta
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, [lastScrollY]);

return (
<Box display="flex" position="relative">
{/* SubMenuContent se muestra solo cuando no es pantalla pequeña */}
{!isMobile ? (
<Box width="300px" display="flex" flexDirection="column">
<SubMenuContent onClose={onClose} titleSubMenu="INFORMES" />
</Box>
) : (
// En pantallas pequeñas, solo mostramos el botón de hamburguesa si showHamburger es true
showHamburger && (
showHamburger && !isOpen && (
<Box
position="absolute"
top="0"
left="-25px" // Desplazar el botón 10px hacia la izquierda
p="4"
position="fixed"
bottom="760px"
left="10px"
zIndex="1000"
>
<IconButton
aria-label="Abrir menú"
icon={<HamburgerIcon color="white" />}
onClick={onOpen}
bg="blue.300"
/>
</Box>
)
)}

{/* El contenido principal (Outlet) */}
<Box
flex="1"
ml={isOpen && isMobile ? '250px' : '0'} // Si está abierto y es móvil, mueve el contenido a la derecha
ml={isOpen && isMobile ? '250px' : '0'}
transition="all 0.3s"
p="4"
>
<Outlet />
</Box>

{/* Barra lateral (SubMenu) visible en móvil si se abre */}
{isOpen && isMobile && (
<Box
position="absolute"
position="fixed"
top="0"
left="0"
width="250px"
height="100vh"
p="4"
zIndex="999"
bg="white"
boxShadow="xl"
>
<SubMenuContent onClose={onClose} titleSubMenu="INFORMES" />

{/* Botón de cierre dentro del SubMenuContent */}
<Box position="absolute" top="10px" right="10px">
<IconButton
aria-label="Cerrar menú"
icon={<CloseIcon />}
onClick={onClose}
size="sm" // Tamaño pequeño
color="black" // Color negro
variant="white" // Sin fondo
size="sm"
color="black"
variant="white"
bg="white"
_hover={{ bg: 'gray.500' }} // Cambia a gris cuando el cursor esté sobre el botón
_hover={{ bg: 'gray.500' }}
/>
</Box>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
Input,
} from '@chakra-ui/react';
import { FetchMaterias } from '../../../../API/Materias';
import { FetchAlumnosMaterias } from '../../../../API/Materias'; // Asumo que tienes esta función en tu API
import { FetchAlumnosMaterias } from '../../../../API/Materias';

interface Materia {
anio_cursada: number;
Expand All @@ -24,44 +24,39 @@ interface Materia {
}

const ListadoMaterias: React.FC = () => {
const [materias, setMaterias] = useState<Materia[]>([]); // Estado para las materias
const [filteredMaterias, setFilteredMaterias] = useState<Materia[]>([]); // Estado para las materias filtradas por búsqueda
const [alumnos, setAlumnos] = useState([]); // Estado para los alumnos
const [currentPage, setCurrentPage] = useState(1); // Estado para la página actual
const [itemsPerPage] = useState(10); // Número de elementos por página
const [searchQuery, setSearchQuery] = useState(''); // Estado para la búsqueda por nombre de materia
const [materias, setMaterias] = useState<Materia[]>([]);
const [filteredMaterias, setFilteredMaterias] = useState<Materia[]>([]);
const [alumnos, setAlumnos] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage] = useState(10);
const [searchQuery, setSearchQuery] = useState('');
const navigate = useNavigate();

// Maneja el clic sobre una materia para obtener los alumnos
const handleMateriaClick = async (codigoMateria: number) => {
try {
const alumnosData = await FetchAlumnosMaterias(codigoMateria); // Asumiendo que tienes una API para obtener los alumnos
setAlumnos(alumnosData); // Guarda los datos de los alumnos
navigate(`${codigoMateria}/alumnos`); // Navega a la ruta correspondiente
const alumnosData = await FetchAlumnosMaterias(codigoMateria);
setAlumnos(alumnosData);
navigate(`${codigoMateria}/alumnos`);
} catch (error) {
console.error('Error al obtener los alumnos:', error);
setAlumnos([]); // Respaldo a un array vacío en caso de error
setAlumnos([]);
}
};

// Filtra las materias por nombre, ignorando mayúsculas/minúsculas
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const query = event.target.value;
setSearchQuery(query);

// Filtra las materias según el query de búsqueda
const filtered = materias.filter((materia) =>
materia.nombre.toLowerCase().includes(query.toLowerCase())
);
setFilteredMaterias(filtered);
};

// Paginación
const indexOfLastMateria = currentPage * itemsPerPage;
const indexOfFirstMateria = indexOfLastMateria - itemsPerPage;
const currentMaterias = filteredMaterias.slice(indexOfFirstMateria, indexOfLastMateria);

// Cambiar de página
const paginate = (pageNumber: number) => setCurrentPage(pageNumber);

useEffect(() => {
Expand All @@ -71,18 +66,18 @@ const ListadoMaterias: React.FC = () => {
if (data && Array.isArray(data.results)) {
const sortedMaterias = data.results.sort((a: Materia, b: Materia) =>
a.nombre.localeCompare(b.nombre)
); // Ordenar alfabéticamente por el nombre
setMaterias(sortedMaterias); // Establecer las materias ordenadas
setFilteredMaterias(sortedMaterias); // Inicializamos también la lista filtrada
);
setMaterias(sortedMaterias);
setFilteredMaterias(sortedMaterias);
} else {
console.error('Datos inválidos:', data);
setMaterias([]); // Respaldo a un array vacío si los datos son inválidos
setFilteredMaterias([]); // Respaldo a un array vacío si los datos son inválidos
setMaterias([]);
setFilteredMaterias([]);
}
} catch (error) {
console.error('Network error:', error);
setMaterias([]); // Respaldo a un array vacío si ocurre un error
setFilteredMaterias([]); // Respaldo a un array vacío si ocurre un error
setMaterias([]);
setFilteredMaterias([]);
}
};
fetchData();
Expand All @@ -105,7 +100,6 @@ const ListadoMaterias: React.FC = () => {
Listado de Materias
</Heading>

{/* Campo de búsqueda */}
<Box w="full">
<Input
placeholder="Buscar por nombre de materia"
Expand All @@ -123,7 +117,7 @@ const ListadoMaterias: React.FC = () => {
p={2}
borderRadius="md"
_hover={{ bg: 'gray.100', cursor: 'pointer' }}
onClick={() => handleMateriaClick(materia.codigo_materia)} // Llama a la función cuando se haga clic
onClick={() => handleMateriaClick(materia.codigo_materia)}
>
<Text fontSize="md" color="gray.700">
{materia.nombre}
Expand All @@ -133,16 +127,15 @@ const ListadoMaterias: React.FC = () => {
</List>
</Box>

{/* Paginación */}
<HStack spacing={4} justify="center" mt={4}>
<Button
isDisabled={currentPage === 1}
onClick={() => paginate(currentPage - 1)}
color="white"
bg="blue.700" // Color azul más oscuro
bg="blue.700"
_hover={{ bg: 'blue.800' }}
>
{'Anterior <<'} {/* Símbolo "Anterior" */}
{'Anterior <<'}
</Button>
<Text>
Página {currentPage} de {Math.ceil(filteredMaterias.length / itemsPerPage)}
Expand All @@ -151,10 +144,10 @@ const ListadoMaterias: React.FC = () => {
isDisabled={currentPage === Math.ceil(filteredMaterias.length / itemsPerPage)}
onClick={() => paginate(currentPage + 1)}
color="white"
bg="blue.900" // Color azul más oscuro
bg="blue.900"
_hover={{ bg: 'blue.800' }}
>
{'Siguiente >>'} {/* Símbolo "Siguiente" */}
{'Siguiente >>'}
</Button>
</HStack>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
import { useParams, Link } from 'react-router-dom'; // Asegúrate de importar Link
import { useParams, Link } from 'react-router-dom';
import { FetchAlumnosMaterias } from '../../../../../API/Materias';
import { Input, Button, Box, Table, Thead, Tbody, Tr, Th, Td, Flex, Text, InputGroup, InputLeftElement } from '@chakra-ui/react';
import { SearchIcon } from '@chakra-ui/icons';
Expand All @@ -24,10 +24,10 @@ const ListadoAlumnosQueCursanMateria = () => {
const [error, setError] = useState<string | null>(null);
const [searchQuery, setSearchQuery] = useState('');
const [currentPage, setCurrentPage] = useState(1);
const [filteredAlumnos, setFilteredAlumnos] = useState<Alumno[]>([]); // Alumnos filtrados
const [filteredAlumnos, setFilteredAlumnos] = useState<Alumno[]>([]);
const { codigo_materia } = useParams<{ codigo_materia: string }>();

const alumnosPerPage = 10; // Máximo de alumnos por página
const alumnosPerPage = 10;

useEffect(() => {
const fetchData = async () => {
Expand All @@ -39,7 +39,7 @@ const ListadoAlumnosQueCursanMateria = () => {
const codigo_materiaNumber = parseInt(codigo_materia);
const data = await FetchAlumnosMaterias(codigo_materiaNumber);
setAlumnos(data.results);
setFilteredAlumnos(data.results); // Inicialmente se muestran todos
setFilteredAlumnos(data.results);
}
} catch (error: any) {
setError(error.message || 'Error al obtener los datos');
Expand All @@ -56,8 +56,8 @@ const ListadoAlumnosQueCursanMateria = () => {
setSearchQuery(query);

if (query === '') {
setFilteredAlumnos(alumnos); // Si no hay filtro, se muestran todos
setCurrentPage(1); // Reseteamos la página a 1
setFilteredAlumnos(alumnos);
setCurrentPage(1);
} else {
const filtered = alumnos.filter((alumno) => {
return (
Expand All @@ -69,28 +69,25 @@ const ListadoAlumnosQueCursanMateria = () => {
);
});
setFilteredAlumnos(filtered);
setCurrentPage(1); // Reseteamos la página a 1 cuando cambiamos el filtro
setCurrentPage(1);
}
};

const paginate = (pageNumber: number) => {
setCurrentPage(pageNumber);
};

// Calculamos los alumnos a mostrar según la página actual y los resultados filtrados
const indexOfLastAlumno = currentPage * alumnosPerPage;
const indexOfFirstAlumno = indexOfLastAlumno - alumnosPerPage;
const currentAlumnos = filteredAlumnos.slice(indexOfFirstAlumno, indexOfLastAlumno);

if (loading) return <Text>Cargando datos...</Text>;
if (error) return <Text color="red.500">Error: {error}</Text>;

// Número total de páginas basado en los resultados filtrados
const totalPages = filteredAlumnos.length > 0 ? Math.ceil(filteredAlumnos.length / alumnosPerPage) : 0;

return (
<Box p={5}>
{/* Input con lupa */}
<InputGroup mb={4}>
<InputLeftElement pointerEvents="none">
<SearchIcon color="gray.500" />
Expand Down Expand Up @@ -123,8 +120,8 @@ const ListadoAlumnosQueCursanMateria = () => {
<Tr
key={alumno.dni}
_hover={{
bg: 'gray.200', // Color de fondo cuando el cursor está sobre la fila
cursor: 'pointer', // Cambiar el cursor para indicar que es un enlace
bg: 'gray.200',
cursor: 'pointer',
}}
>
<Td textAlign="center">
Expand Down Expand Up @@ -153,7 +150,6 @@ const ListadoAlumnosQueCursanMateria = () => {
</Tbody>
</Table>

{/* Paginación */}
{totalPages > 0 && (
<Flex justify="center" align="center" gap={4}>
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
InputLeftElement,
} from '@chakra-ui/react';
import { SearchIcon } from '@chakra-ui/icons';
import { Link } from 'react-router-dom'; // Importa Link para la navegación
import { Link } from 'react-router-dom';

interface Alumnos {
full_name: string;
Expand All @@ -28,7 +28,7 @@ interface Alumnos {
}

interface TablaAlumnosProps {
fetchFunction: () => Promise<Alumnos[]>; // Función para obtener los alumnos
fetchFunction: () => Promise<Alumnos[]>;
title: string;
}

Expand Down Expand Up @@ -79,7 +79,6 @@ const TablaAlumnos: React.FC<TablaAlumnosProps> = ({ fetchFunction, title }) =>
return 0;
});

// Filtrar alumnos
const filteredAlumnos = sortedAlumnos.filter(alumno =>
alumno.full_name.toLowerCase().includes(searchTerm.toLowerCase()) ||
alumno.legajo.toString().includes(searchTerm) ||
Expand All @@ -88,7 +87,6 @@ const TablaAlumnos: React.FC<TablaAlumnosProps> = ({ fetchFunction, title }) =>
alumno.anio_ingreso.toString().includes(searchTerm)
);

// Si no hay alumnos, no mostrar paginación
const totalPages = filteredAlumnos.length > 0 ? Math.ceil(filteredAlumnos.length / alumnosPerPage) : 0;

// Paginación
Expand All @@ -98,7 +96,6 @@ const TablaAlumnos: React.FC<TablaAlumnosProps> = ({ fetchFunction, title }) =>

return (
<Box p={5}>
{/* Input de búsqueda */}
<InputGroup mb={4}>
<InputLeftElement pointerEvents="none">
<SearchIcon color="gray.300" />
Expand Down Expand Up @@ -128,13 +125,12 @@ const TablaAlumnos: React.FC<TablaAlumnosProps> = ({ fetchFunction, title }) =>
) : (
currentAlumnos.map(alumno => (
<Tr
key={alumno.dni} // Usamos el DNI como key
key={alumno.dni}
_hover={{
bg: 'gray.200', // Color de fondo cuando el cursor está sobre la fila
cursor: 'pointer', // Cambiar el cursor para indicar que es un enlace
bg: 'gray.200',
cursor: 'pointer',
}}
>
{/* Cada Td está envuelto en un Link */}
<Td textAlign="center">
<Link to={`/admin/alumnos/${alumno.dni}`} style={{ display: 'block', textDecoration: 'none', color: 'inherit' }}>
{alumno.full_name}
Expand Down

0 comments on commit 73a8365

Please sign in to comment.