Skip to content

Archivos de la Carpeta src/pages

La carpeta src/pages contiene los componentes de alto nivel que representan las diferentes "páginas" o vistas principales de tu aplicación. Estas páginas suelen ser la capa que compone varios componentes y características para formar una vista completa.


login.page.tsx

Este archivo define la página de Inicio de Sesión, que sirve como la interfaz principal para que los usuarios accedan a la aplicación.

  • Descripción: LoginPage es un componente de página simple que se encarga de renderizar la interfaz de inicio de sesión. Delega la lógica de autenticación y la presentación del formulario a componentes especializados, manteniendo esta página limpia y enfocada en su propósito principal.
  • Propósito: Proporcionar una vista dedicada para el proceso de inicio de sesión, integrando el layout público y el componente de login.
  • Funcionalidad clave:
    • <PublicLayout>: Este componente (importado de ../components/layouts/public-layout/public.layout.tsx) envuelve el contenido del login, proporcionando una estructura visual común para las rutas que no requieren autenticación (por ejemplo, un diseño sin barra lateral de navegación).
    • <Login />: Este componente (importado de ../features/login/login.tsx) es el corazón de la funcionalidad de inicio de sesión. Contiene el formulario, la lógica para manejar las credenciales del usuario y la interacción con la API de autenticación. LoginPage simplemente lo renderiza, desacoplando la lógica de la vista principal.
  • Rol en la aplicación: LoginPage es el punto de entrada principal para los usuarios que buscan autenticarse. Su diseño modular asegura que la lógica de la UI y la autenticación estén bien separadas, facilitando el mantenimiento y la reutilización.
tsx
// src/pages/login.page.tsx
import React from "react";
import PublicLayout from "../components/layouts/public-layout/public.layout";
import Login from "../features/login/login";

const LoginPage: React.FC = () => {
  return (
    <PublicLayout>
      <Login />
    </PublicLayout>
  );
};

export default LoginPage;

dashboard.tsx

Este archivo define la página principal del Dashboard, que actúa como una vista general de los estudiantes en el sistema.

  • Descripción: Dashboard es un componente de página que se encarga de obtener la lista completa de estudiantes y presentarlos en un formato de tabla. Maneja los estados de carga y error para proporcionar una experiencia de usuario fluida.
  • Propósito: Mostrar una visión general de todos los estudiantes registrados, sirviendo como la página principal para la gestión y visualización rápida.
  • Funcionalidad clave:
    • useStudentsList(): Este hook personalizado (importado de ../hooks/use.students.list.ts) es el responsable de la lógica de obtención de la lista completa de estudiantes de la API. Retorna el array de students, junto con los estados loading (para indicar si los datos se están cargando) y error (para capturar cualquier fallo en la operación).
    • Manejo de Estados de Carga y Error:
      • Si loading es true, la página muestra un mensaje "Cargando estudiantes...".
      • Si error contiene un valor, se renderiza un mensaje de error correspondiente.
    • <Grid>: Un componente genérico de layout (importado de ../components/common/grid/grid.tsx) utilizado para estructurar el contenido de la página, ofreciendo flexibilidad en el diseño.
    • <StudentTable>: Este componente presentacional (importado de ../components/student-table/student.table.tsx) es el encargado de renderizar la tabla de estudiantes. Recibe los students obtenidos, un title dinámico (que incluye el conteo total de estudiantes), y la viewProfilePath base para navegar a perfiles individuales.
  • Rol en la aplicación: Dashboard es una página central para la administración de estudiantes. Su enfoque en la delegación de responsabilidades a hooks y componentes presentacionales asegura una arquitectura limpia y eficiente.
tsx
// src/pages/dashboard.tsx
import { Grid } from "../components/common/grid/grid";
import { useStudentsList } from "../hooks/use.students.list";
import { StudentTable } from "../components/student-table/student.table";

export default function Dashboard() {
  const { students, error, loading } = useStudentsList();

  // Muestra un mensaje de carga mientras se obtienen los datos.
  if (loading) return <p>Cargando estudiantes...</p>;
  // Muestra un mensaje de error si la carga de datos falla.
  if (error) return <p>Error: {error}</p>;

  // Renderiza la tabla de estudiantes dentro de un componente Grid.
  return (
    <Grid>
      <StudentTable
        students={students} // Pasa la lista completa de estudiantes.
        title={`Estudiantes (${students.length})`} // Título dinámico con el conteo de estudiantes.
        viewProfilePath="/dashboard/student" // Ruta base para navegar al perfil de un estudiante.
      />
    </Grid>
  );
}

student.profile.tsx

Este archivo define la página del Perfil del Estudiante, la cual permite visualizar los detalles de un estudiante específico y ofrece la funcionalidad para editar su información o eliminarlo.

  • Descripción: StudentProfile es un componente de página que recupera el ID de un estudiante de la URL, utiliza un custom hook (useStudentProfile) para obtener los datos del estudiante y gestionar la lógica de edición/eliminación. Alterna entre la vista de detalles y un formulario de actualización dependiendo del estado de edición.
  • Propósito: Mostrar una vista detallada del perfil de un estudiante, permitiendo a los usuarios autorizados modificar o eliminar los datos del estudiante.
  • Funcionalidad:
    • useParams<{ id: string }>(): Hook de react-router-dom que extrae el id del estudiante de la URL (por ejemplo, /dashboard/student/123).
    • useAuth().token: Obtiene el token de autenticación del contexto global de autenticación. Este token se pasa directamente al useStudentProfile hook, asumiendo que useStudentProfile está tipado para aceptar el token como string | null | undefined, lo que permite un manejo más conciso.
    • useStudentProfile(id, token): Este es el custom hook central de la página. Encapsula toda la lógica para:
      • Obtener los datos del estudiante dado su id y token.
      • Manejar el estado de carga (loading) y error (error).
      • Gestionar el estado de edición (isEditing) y los datos temporales del formulario (updatedData).
      • Proveer funciones para la edición (handleEdit, handleChange, handleSubmitEdit), eliminación de archivos (handleDeleteFile) y eliminación del estudiante (handleDelete).
      • Indicar si el estudiante ha sido eliminado (isDeleted).
    • useNavigate(): Hook de react-router-dom para la navegación programática.
    • useEffect para Redirección: Cuando isDeleted cambia a true (indicando que el estudiante fue eliminado exitosamente), el efecto redirige al usuario a la página /dashboard.
    • Manejo de Estados Iniciales:
      • Si error es verdadero, muestra un mensaje de error.
      • Si student no está cargado (es null o undefined), muestra un mensaje de "Cargando...".
    • Renderizado Condicional:
      • Si isEditing es true, renderiza el componente UpdateStudentForm. Este formulario recibe los datos del estudiante para la edición (updatedData), y los handlers para los cambios (handleChange), el envío (handleSubmitEdit) y la eliminación de archivos (handleDeleteFile).
      • Si isEditing es false, renderiza el componente StudentDetails. Este componente muestra la información del estudiante (student) y provee botones/acciones para activar el modo de edición (onEdit) y la eliminación (onDelete).
  • Rol en la aplicación: StudentProfile actúa como una página de detalle y gestión para un estudiante individual. Coordina la obtención de datos, el manejo de diferentes modos (vista/edición) y la interacción con los componentes UI específicos para esas tareas.
tsx
// src/pages/student.profile.tsx

import { useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { useAuth } from "../components/auth/auth.context";
import { useStudentProfile } from "../hooks/use.profile.students";
import UpdateStudentForm from "../components/common/forms/update-student/update.student.form";
import StudentDetails from "../components/common/details-views/student.profile.details";

/**
 * Componente StudentProfile.
 * Página que muestra el perfil detallado de un estudiante y permite su edición/eliminación.
 * Actúa como orquestador para la lógica de datos y la alternancia de vistas (detalles vs. edición).
 */
const StudentProfile = () => {
  const { id } = useParams<{ id: string }>();
  // Desestructura 'token' directamente de useAuth.
  // Se asume que useAuth().token es de tipo `string | null | undefined`,
  // y que useStudentProfile() acepta este tipo para el token.
  const { token } = useAuth(); 

  // Utiliza el hook useStudentProfile para gestionar toda la lógica del perfil:
  // - Obtención de datos del estudiante.
  // - Manejo de estados (carga, error, edición, eliminación).
  // - Funciones para interactuar con los datos (editar, eliminar, manejar archivos).
  const {
    student,
    error,
    isEditing,
    updatedData,
    handleEdit,
    handleChange,
    handleSubmitEdit,
    handleDelete,
    handleDeleteFile,
    isDeleted,
  } = useStudentProfile(id, token); // Pasa 'token' directamente aquí.

  const navigate = useNavigate();

  // Efecto secundario para redirigir al dashboard si el estudiante ha sido eliminado con éxito.
  // Se ejecuta cada vez que 'isDeleted' o 'navigate' cambian.
  useEffect(() => {
    if (isDeleted) {
      navigate("/dashboard");
    }
  }, [isDeleted, navigate]);

  // Renderizado condicional basado en el estado de error o carga.
  // Muestra un mensaje de error si la carga de datos falló.
  if (error) {
    return <div>{error}</div>;
  }

  // Muestra un mensaje de carga si los datos del estudiante aún no están disponibles.
  if (!student) {
    return <div>Cargando...</div>;
  }

  // Renderiza el contenido principal de la página.
  return (
    <div>
      {/* Renderizado condicional: muestra el formulario de edición o los detalles del estudiante. */}
      {isEditing ? (
        // Si 'isEditing' es true, muestra el formulario para actualizar el estudiante.
        <UpdateStudentForm
          student={updatedData!} // Pasa los datos actuales para el formulario (el '!' afirma que no será null aquí).
          onChange={handleChange} // Handler para cambios en los campos del formulario.
          onSubmit={handleSubmitEdit} // Handler para el envío del formulario.
          onDeleteFile={handleDeleteFile} // Handler para eliminar archivos.
        />
      ) : (
        // Si 'isEditing' es false, muestra los detalles del estudiante.
        <StudentDetails
          student={student} // Pasa los datos del estudiante para mostrar.
          onEdit={handleEdit} // Handler para activar el modo de edición.
          onDelete={handleDelete} // Handler para eliminar al estudiante.
        />
      )}
    </div>
  );
};

export default StudentProfile;

add.student.tsx

Este archivo define la página "Agregar Estudiante", que permite a los usuarios crear nuevos registros de estudiantes en el sistema.

  • Descripción: AddStudent es un componente de página que orquesta la lógica de autenticación, el estado del formulario, la gestión del envío y la retroalimentación al usuario. Utiliza hooks personalizados y componentes presentacionales para mantener una arquitectura limpia y modular.
  • Propósito: Proporcionar una interfaz de usuario clara y funcional para que los usuarios autenticados puedan ingresar y guardar la información de nuevos estudiantes.
  • Funcionalidad clave:
    • Control de Autenticación: Al inicio, la página verifica si el usuario tiene un token de autenticación. Si no está autenticado, muestra un mensaje claro y prohíbe el acceso al formulario de adición. Esto es crucial para la seguridad y el control de acceso.
    • Uso de useAuth(): Este hook se emplea para obtener el token del contexto de autenticación, asegurando que solo usuarios válidos puedan realizar la operación.
    • Uso de useAddStudent(): Este es el hook personalizado central de la página. Encapsula toda la lógica relacionada con el formulario de adición de estudiantes:
      • Manejo del estado de los datos del formulario (studentData).
      • Gestión de los cambios en los campos de entrada (handleChange).
      • Ejecución de la lógica de envío (handleSubmit).
      • Provisión de mensajes de éxito (successMessage) o error (errorMessage) después del intento de adición.
      • Proporciona una formKey, una técnica muy útil para reiniciar completamente el formulario (forzando la re-montura del componente AddStudentForm) después de un envío exitoso, lo que limpia los campos para una nueva entrada.
    • Retroalimentación al Usuario con react-toastify: Utiliza el hook useEffect para mostrar notificaciones toast al usuario cuando hay un successMessage o un errorMessage. Esto mejora la experiencia del usuario al proporcionar retroalimentación visual no intrusiva sobre el resultado de la operación.
    • Componente AddStudentForm: La página delega la renderización del formulario a este componente presentacional. Recibe los datos del estudiante, el manejador de cambios y el manejador de envío como propiedades, manteniendo el formulario desacoplado y reutilizable.
  • Rol en la aplicación: AddStudent funciona como un punto de entrada para la creación de nuevos registros. Su estructura modular y el uso de hooks la hacen fácil de entender y mantener.
tsx
// src/pages/add.student.tsx
import { useEffect } from "react";
import { AddStudentForm } from "../components/common/forms/add-student/add.student.form";
import { useAuth } from "../components/auth/auth.context";
import { useAddStudent } from "../hooks/use.add.students";
import { toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";

export default function AddStudent() {
  const { token } = useAuth();
  const {
    successMessage,
    errorMessage,
    handleSubmit, // Se utiliza directamente handleSubmit del hook
    studentData,
    handleChange,
    formKey,
  } = useAddStudent(token); // El hook useAddStudent ahora acepta 'token' directamente.

  // handleAddStudent fue eliminado, ya que era un envoltorio redundante.

  useEffect(() => {
    if (successMessage) {
      toast.success(successMessage, { position: "top-right", autoClose: 5000 });
    }
    if (errorMessage) {
      toast.error(errorMessage, { position: "top-right", autoClose: 5000 });
    }
  }, [successMessage, errorMessage]);

  // Si no hay token, se muestra un mensaje indicando que no está autenticado.
  if (!token) {
    return (
      <div>
        <h1>Agregar Estudiante</h1>
        <p style={{ color: "red" }}>
          No estás autenticado. Inicia sesión para agregar estudiantes.
        </p>
      </div>
    );
  }

  // Renderizado del formulario para agregar estudiante.
  return (
    <div>
      <h1>Agregar Estudiante</h1>
      <AddStudentForm
        key={formKey} // La clave es crucial para forzar el reinicio del formulario.
        studentData={studentData}
        handleChange={handleChange}
        handleSubmit={handleSubmit} // Se pasa handleSubmit directamente.
      />
    </div>
  );
}

school.class.tsx

Este archivo define la página "Clase Escolar", la cual se encarga de mostrar una lista de estudiantes filtrada por un colegio y un curso específicos. Actúa como un orquestador que combina datos de diferentes fuentes para presentar una vista cohesiva.

  • Descripción: SchoolClass es un componente de página que utiliza hooks personalizados (useStudentsList, useSchoolClass) para obtener la lista completa de estudiantes, aplicar filtros de colegio y curso, y luego renderizar una tabla de estudiantes con la información relevante.
  • Propósito: Presentar una vista detallada de los estudiantes que pertenecen a una clase específica (definida por colegio y curso), facilitando la gestión y visualización por parte de los administradores.
  • Funcionalidad clave:
    • Obtención de datos de estudiantes (useStudentsList): Utiliza el hook useStudentsList para recuperar la lista completa de estudiantes, su estado de carga (loading) y posibles errores (error). Este hook encapsula la lógica de fetching de datos de la API.
    • Lógica de Clase Escolar (useSchoolClass): Este hook se encarga de obtener la información necesaria para definir la clase (colegio y curso) a partir de los parámetros de la URL. Proporciona normalizedSchool y normalizedCourse para usar en el título de la tabla y getFilteredStudentsBySchoolAndCourse, una función que toma la lista completa de estudiantes y devuelve solo aquellos que coinciden con el colegio y el curso.
    • Filtrado en la Página: La lógica principal de filtrado por colegio y curso se aplica directamente en esta página utilizando useMemo y la función getFilteredStudentsBySchoolAndCourse del hook useSchoolClass. Esto asegura que el componente StudentTable reciba solo los datos ya procesados y filtrados.
    • Manejo de Estados de Carga, Error y Vacío:
      • Muestra un mensaje "Cargando estudiantes..." mientras los datos están siendo fetched.
      • Muestra un mensaje de error si ocurre un problema durante la carga de los estudiantes.
      • Muestra un mensaje claro si no se encontraron estudiantes para el colegio y curso seleccionados (es decir, la lista studentsForTable está vacía después del filtrado).
    • Componente StudentTable: La página delega la renderización de la lista de estudiantes a este componente presentacional. Se le pasan los studentsForTable (ya filtrados), un title que se construye dinámicamente usando los nombres normalizados del colegio y curso, y la viewProfilePath base para navegar al perfil individual de un estudiante.
    • Componente Grid: Se utiliza un componente Grid genérico (../components/common/grid/grid.tsx) para el layout general de la página.
  • Rol en la aplicación: SchoolClass es una página clave para la visualización segmentada de estudiantes, permitiendo a los usuarios enfocarse en grupos específicos. Su diseño modular con hooks y componentes presentacionales facilita la gestión de la lógica de datos y la presentación de la UI.
tsx
// src/pages/school.class.tsx
import { useMemo } from "react"; // Asegúrate de importar useMemo
import { Grid } from "../components/common/grid/grid";
import { useStudentsList } from "../hooks/use.students.list";
import { StudentTable } from "../components/student-table/student.table";
import { useSchoolClass } from "../hooks/use.school.class";

export default function SchoolClass() {
  // Obtiene la lista completa de estudiantes y su estado de carga/error
  const { students, error, loading } = useStudentsList();

  // Obtiene los nombres normalizados del colegio/curso y la función de filtrado principal
  const {
    normalizedSchool,
    normalizedCourse,
    getFilteredStudentsBySchoolAndCourse,
  } = useSchoolClass();

  // Paso CRUCIAL: Aplicar el filtro de colegio y curso aquí
  const studentsForTable = useMemo(() => {
    if (!students) {
      return [];
    }
    return getFilteredStudentsBySchoolAndCourse(students);
  }, [students, getFilteredStudentsBySchoolAndCourse]);

  // Manejo de estados de carga, error y "sin estudiantes"
  if (loading) {
    return <p>Cargando estudiantes...</p>;
  }

  if (error) {
    return <p>Error al cargar estudiantes: {error}</p>;
  }

  if (studentsForTable.length === 0) {
    return (
      <p>
        No se encontraron estudiantes para{" "}
        <strong>
          {normalizedSchool} - {normalizedCourse}
        </strong>
        .
      </p>
    );
  }

  // Renderiza la tabla de estudiantes con los datos ya filtrados
  return (
    <Grid>
      <StudentTable
        students={studentsForTable} // ¡Aquí se pasan los estudiantes ya filtrados!
        title={`${normalizedSchool} - ${normalizedCourse}`}
        // filterBySchoolAndCourse ya NO es una prop de StudentTable
        viewProfilePath="/dashboard/student"
      />
    </Grid>
  );
}

statistics.tsx

Este archivo define la página "Estadísticas", la cual permite visualizar datos analíticos de los estudiantes mediante gráficos y tablas interactivas. Actúa como centro de control para filtrar, analizar y presentar datos clave relacionados con la matrícula y características del alumnado.

  • Descripción: Statistics es un componente de página que utiliza un hook personalizado (useStudentsList) para obtener estudiantes desde el backend, y permite filtrarlos por fuente, colegio y curso. Luego, delega el análisis y visualización de datos a componentes especializados, siguiendo un enfoque modular y desacoplado.

  • Propósito: Brindar una vista interactiva y analítica del cuerpo estudiantil que ayude a los administradores a identificar patrones, distribuciones y comportamientos clave para la toma de decisiones.

  • Funcionalidad clave:

    • Obtención de datos (useStudentsList): Hook que proporciona la lista completa de estudiantes, junto con su estado de carga (loading) y posibles errores (error).
    • Filtros dinámicos (source, school, course): Mantenidos mediante useState, permiten filtrar los datos mostrados en los componentes visuales. Los valores están basados en enums centralizados importados desde ../interface/common/enums/enums.
    • handleFilterChange: Función que actualiza el estado de los filtros y se pasa como prop al componente StatisticsFilterControls.
    • calculateStatistics: Función que procesa los estudiantes filtrados y devuelve un objeto FilteredStatistics con los datos agrupados para cada gráfico o sección.
    • Manejo de estados:
      • Muestra "Cargando estadísticas..." mientras se cargan los datos.
      • Muestra un mensaje de error si ocurre una falla.
      • Muestra "No hay datos disponibles." si la lista está vacía tras la carga.
    • Componentes visuales (secciones):
      • StatisticsFilterControls: Selector de filtros para la vista.
      • GeneralStudentStatsSection: Estadísticas generales y feedback positivo.
      • CommunicationPreferenceSection: Preferencias de comunicación.
      • EnrollmentSourceSection: Fuente de inscripción de los estudiantes.
      • GenderDistributionSection: Distribución por género.
      • CaptatorsTableSection: Tabla con información de captadores.
      • StudentsByLevelSection: Estudiantes distribuidos por nivel académico.
      • FeedbackBySchoolCourseSection: Feedback agrupado por escuela y curso.
    • Constantes globales (Constants.allFeedbacks): Se importa desde utils/constants y centraliza los valores disponibles de feedback para usarlos en visualizaciones.
  • Rol en la aplicación: Statistics es una página clave para el monitoreo y análisis del sistema, ya que permite visualizar de manera intuitiva el estado general del alumnado. Su arquitectura modular mejora el mantenimiento, la extensibilidad y la claridad del código.

tsx
// src/pages/statistics.tsx
import { useState } from "react";
import { useStudentsList } from "../hooks/use.students.list";
import { calculateStatistics } from "../components/statistics/statistics.filters";
import { Source, School, Course } from "../interface/common/enums/enums";
import { Grid } from "../components/common/grid/grid";
import { StatisticsFilterControls } from "../components/statistics/filters/statistics.filter.controls";
import { GeneralStudentStatsSection } from "../components/statistics/sections/general.student.stats.section";
import { CommunicationPreferenceSection } from "../components/statistics/sections/communication.preference.section";
import { EnrollmentSourceSection } from "../components/statistics/sections/enrollment.source.section";
import { GenderDistributionSection } from "../components/statistics/sections/gender.distribution.section";
import { CaptatorsTableSection } from "../components/statistics/sections/captators.table.section";
import { StudentsByLevelSection } from "../components/statistics/sections/students.by.level.section";
import { FeedbackBySchoolCourseSection } from "../components/statistics/sections/feedback.by.school.course.section";

import Constants from "../utils/constants";

const Statistics = () => {
  const { students, error, loading } = useStudentsList();
  const [source, setSource] = useState<Source | null>(null);
  const [school, setSchool] = useState<School | null>(null);
  const [course, setCourse] = useState<Course | null>(null);

  const handleFilterChange = (filters: {
    source?: Source | null;
    school?: School | null;
    course?: Course | null;
  }) => {
    if (filters.source !== undefined) setSource(filters.source);
    if (filters.school !== undefined) setSchool(filters.school);
    if (filters.course !== undefined) setCourse(filters.course);
  };

  if (loading) return <p>Cargando estadísticas...</p>;
  if (error) return <p>Error: {error}</p>;

  if (!students || students.length === 0) {
    return <p>No hay datos disponibles.</p>;
  }

  const filteredStatistics = calculateStatistics({
    students,
    source,
    school,
    course,
  });

  return (
    <div>
      <h1>Estadísticas</h1>

      <StatisticsFilterControls
        selectedSource={source}
        selectedSchool={school}
        selectedCourse={course}
        onFilterChange={handleFilterChange}
      />

      <Grid className="modulos">
        <GeneralStudentStatsSection
          filteredStatistics={filteredStatistics}
          allFeedbacks={Constants.allFeedbacks}
        />
        <CommunicationPreferenceSection filteredStatistics={filteredStatistics} />
        <EnrollmentSourceSection filteredStatistics={filteredStatistics} />
        <GenderDistributionSection filteredStatistics={filteredStatistics} />
        <CaptatorsTableSection filteredStatistics={filteredStatistics} />
        <StudentsByLevelSection filteredStatistics={filteredStatistics} />
        <FeedbackBySchoolCourseSection filteredStatistics={filteredStatistics} />
      </Grid>
    </div>
  );
};

export default Statistics;