Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deyvicz #33

Merged
merged 8 commits into from
Sep 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions FrontEnd/react-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions FrontEnd/react-app/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,14 @@ const App = () => {
<Routes>
{/* Ruta para la página de inicio */}
<Route path="/" element={<LoginPage />} />

<Route path="/admin" element={<AdminDashboard />} />

<Route path="/reset_password" element={<ResetPassword />} />


{/* Ruta protegida para los dashboards */}
<Route element={<ProtectedRoute />}>
<Route path="/teacher-dashboard" element={<TeacherDashboard />} />
<Route path="/student-dashboard" element={<StudentDashboard />} />
<Route path="/parent-dashboard" element={<ParentDashboard />} />
<Route path="/admin" element={<AdminDashboard />} />
</Route>
</Routes>
</Router>
Expand Down
87 changes: 41 additions & 46 deletions FrontEnd/react-app/src/components/Login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,82 +10,75 @@ import {
useToast,
} from "@chakra-ui/react";
import { jwtDecode } from "jwt-decode";
import { useEffect, useState } from "react";
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import logo from "../assets/logoSchoolManager.png";
import { loginUser } from "../services/authService";
import { forgotPassword } from "../services/resetService"; // Cambia de resetService a authService
import { forgotPassword } from "../services/resetService"; // Asegúrate de que la ruta del import sea correcta

const Login = () => {
const [loginData, setLoginData] = useState({ email: "", password: "" });
const [name, setName] = useState("");
const [isResetting, setIsResetting] = useState(false);
const [resetEmail, setResetEmail] = useState("");
const navigate = useNavigate();
const toast = useToast();
const [isLoading, setIsLoading] = useState(false);

useEffect(() => {
const token = sessionStorage.getItem("token");
if (token) {
try {
const decodedToken = jwtDecode(token);
const authorities = decodedToken.authorities || "";

if (authorities.includes("ROLE_TEACHER")) {
navigate("/teacher-dashboard");
} else if (authorities.includes("ROLE_STUDENT")) {
navigate("/student-dashboard");
} else if (authorities.includes("ROLE_PARENT")) {
navigate("/parent-dashboard");
} else if (authorities.includes("ROLE_ADMIN")) {
navigate("/admin");
} else {
navigate("/");
}
} catch (error) {
console.error("Error decoding token:", error);
}
}
}, [navigate]);

const handleChange = (e) => {
setLoginData({ ...loginData, [e.target.name]: e.target.value });
};

const handleSubmit = async (e) => {
e.preventDefault();
setIsLoading(true);

try {
const response = await loginUser(loginData);
console.log(response);
const name = response.name;
const token = response.token;
const decodedToken = jwtDecode(token);
const authorities = decodedToken.authorities || "";
sessionStorage.setItem("name", name);

let redirectPath = "/";
if (response.status === false) {
toast({
title: "Cambio de Contraseña Requerido",
description:
"Parece que tu contraseña ha caducado o necesita ser actualizada. Por favor, restablece tu contraseña para continuar.",
status: "info",
duration: 6000,
isClosable: true,
});
setIsResetting(true);
} else if (response.status === true) {
const { name, token } = response;
const decodedToken = jwtDecode(token);
const authorities = decodedToken.authorities || "";

if (authorities.includes("ROLE_TEACHER")) {
redirectPath = "/teacher-dashboard";
} else if (authorities.includes("ROLE_STUDENT")) {
redirectPath = "/student-dashboard";
} else if (authorities.includes("ROLE_PARENT")) {
redirectPath = "/parent-dashboard";
} else if (authorities.includes("ROLE_ADMIN")) {
redirectPath = "/admin";
}
sessionStorage.setItem("name", name);
sessionStorage.setItem("token", token);

// Redirige a la ruta basada en el rol del usuario
let redirectPath = "/";
if (authorities.includes("ROLE_TEACHER")) {
redirectPath = "/teacher-dashboard";
} else if (authorities.includes("ROLE_STUDENT")) {
redirectPath = "/student-dashboard";
} else if (authorities.includes("ROLE_PARENT")) {
redirectPath = "/parent-dashboard";
} else if (authorities.includes("ROLE_ADMIN")) {
redirectPath = "/admin";
}

navigate(redirectPath);
navigate(redirectPath);
}
} catch (error) {
console.error("Error logging in:", error);
toast({
title: "Error al iniciar sesión",
description: "Las credenciales son incorrectas.",
description:
"Las credenciales son incorrectas o hubo un problema con el servidor.",
status: "error",
duration: 5000,
isClosable: true,
});
} finally {
setIsLoading(false);
}
};

Expand All @@ -103,7 +96,7 @@ const Login = () => {
setIsResetting(false);
setResetEmail(""); // Limpiar campo de email
} catch (error) {
console.error(error);
console.error("Error sending reset email:", error);
toast({
title: "Error",
description: "No se pudo enviar el correo de restablecimiento.",
Expand Down Expand Up @@ -160,6 +153,7 @@ const Login = () => {
borderColor: "#34495E",
boxShadow: "0 0 15px rgba(52, 73, 94, 0.5)",
}}
autoComplete="email"
/>
</FormControl>
<Button
Expand Down Expand Up @@ -199,6 +193,7 @@ const Login = () => {
borderColor: "#34495E",
boxShadow: "0 0 15px rgba(52, 73, 94, 0.5)",
}}
autoComplete="email"
/>
</FormControl>
<FormControl id="password" isRequired>
Expand Down
48 changes: 22 additions & 26 deletions FrontEnd/react-app/src/components/ProtectedRoute.jsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,40 @@
// src/components/ProtectedRoute.jsx
import { Navigate, Outlet, useLocation } from "react-router-dom";
import { jwtDecode } from "jwt-decode"; // Importa jwt-decode
import { jwtDecode } from "jwt-decode";

const ProtectedRoute = () => {
const token = sessionStorage.getItem("token"); // Obtén el token del almacenamiento local
const location = useLocation(); // Obtén la ubicación actual
const token = sessionStorage.getItem("token");
const location = useLocation();

if (!token) {
// Si no hay token, redirige a la página de inicio de sesión
// Redirige a la página de inicio de sesión si no hay token
return <Navigate to="/" state={{ from: location }} />;
}

// Si hay token, decodifícalo para obtener el rol
try {
const decodedToken = jwtDecode(token);
const authorities = decodedToken.authorities || "";
const isPasswordResetRequired =
decodedToken.isPasswordResetRequired || false;

if (
location.pathname === "/teacher-dashboard" &&
!authorities.includes("ROLE_TEACHER")
) {
return <Navigate to="/" />;
} else if (
location.pathname === "/student-dashboard" &&
!authorities.includes("ROLE_STUDENT")
) {
return <Navigate to="/" />;
} else if (
location.pathname === "/parent-dashboard" &&
!authorities.includes("ROLE_PARENT")
) {
return <Navigate to="/" />;
} else if (
location.pathname === "/admin" &&
!authorities.includes("ROLE_ADMIN")
) {
// Redirige a la página de restablecimiento de contraseña si es necesario
if (isPasswordResetRequired && location.pathname !== "/reset-password") {
return <Navigate to="/reset-password" />;
}

// Redirige a la página de inicio si el rol no coincide con la ruta
const pathRoleMap = {
"/teacher-dashboard": "ROLE_TEACHER",
"/student-dashboard": "ROLE_STUDENT",
"/parent-dashboard": "ROLE_PARENT",
"/admin": "ROLE_ADMIN",
};

const requiredRole = pathRoleMap[location.pathname];
if (requiredRole && !authorities.includes(requiredRole)) {
return <Navigate to="/" />;
}

// Si el rol es correcto o la ruta es pública, renderiza el contenido
// Permite el acceso si todas las validaciones pasan
return <Outlet />;
} catch (error) {
console.error("Error decoding token:", error);
Expand Down
3 changes: 1 addition & 2 deletions FrontEnd/react-app/src/components/ResetPassword.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const ResetPassword = () => {
duration: 5000,
isClosable: true,
});
navigate("/login");
navigate("/");
}
}, [searchParams, navigate, toast]);

Expand Down Expand Up @@ -345,7 +345,6 @@ const ResetPassword = () => {
mt="4"
type="submit"
colorScheme="orange"
isFullWidth
isLoading={loading}
>
Restablecer Contraseña
Expand Down
1 change: 0 additions & 1 deletion FrontEnd/react-app/src/pages/AdminDashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ const AdminDashboard = () => {
display="flex"
flexDirection="column"
>
<ModalHeader>Registrar Padre/Tutor</ModalHeader>
<ModalCloseButton />
<ModalBody overflowY="auto">
<RegisterParent />
Expand Down
Loading