/**
* @module Pages
* @category Routes
*/
import React, { useEffect } from "react";
import bee from "../assets/bee.png";
import beeDark from "../assets/beedark.png";
import EditMenuProject from "../components/EditMenuProject";
import TeamMenu from "../components/TeamMenu";
import { useProjectStore } from "../config/projectStore";
import { NavLink, useNavigate, useParams } from "react-router-dom";
import useAxiosStore from "../hooks/useAxios";
import BoardTask from "../components/BoardTask";
import { useTheme } from "../context/ThemeContext";
import { useUsersStore } from "../config/usersStore";
import { useAddCollaboratorStore } from "../config/addCollaboratorStore";
/**
* @page
* Componente ProyectInfo
*
* Este componente muestra la información detallada de un proyecto específico,
* incluyendo su descripción, fechas, administrador, y tableros de tareas.
*
* @returns {JSX.Element} Página de información detallada del proyecto
*/
const ProyectInfo = () => {
const { id } = useParams(); // Recuperar ID desde la URL
const {
project,
setProject,
loading,
setLoading,
setTodoTasks,
setInProgressTasks,
setToReviewTasks,
setDoneTasks,
todoTasks,
inProgressTasks,
toReviewTasks,
doneTasks,
} = useProjectStore();
const { fetch: newFetch } = useAxiosStore();
const { users, setUsers } = useUsersStore();
const { setError, setCollaboratorAdded } = useAddCollaboratorStore();
const token = localStorage.getItem("token");
const { isDarkMode } = useTheme();
const { clearProject } = useProjectStore();
const navigate = useNavigate();
// Efecto para cargar los datos del proyecto y sus tareas
useEffect(() => {
// Función para obtener los datos del proyecto
async function fetchProjectData() {
try {
const projectResponse = await newFetch(
`${import.meta.env.VITE_BASE_API}tableros/${id}`,
"GET",
null,
{ Authorization: `Bearer ${token}` }
);
if (projectResponse.error) throw new Error(projectResponse.error);
return projectResponse.data;
} catch (error) {
console.error("Error al obtener el proyecto:", error);
throw error;
}
}
// Función para obtener los datos de un usuario
async function fetchUserData(userId) {
try {
const userResponse = await newFetch(
`${import.meta.env.VITE_BASE_API}usuarios/${userId}`,
"GET",
null,
{ Authorization: `Bearer ${token}` }
);
if (userResponse.error) throw new Error(userResponse.error);
return userResponse.data;
} catch (error) {
console.error(`Error al obtener datos del usuario ${userId}:`, error);
throw error;
}
}
//Función para obtener las tareas según su estado
async function fetchTaskData(estado) {
try {
const response = await newFetch(
`${import.meta.env.VITE_BASE_API}tareas/estado`,
"POST",
{ tablero: id, estado },
{ Authorization: `Bearer ${token}` }
);
if (response.error) throw new Error(response.error);
return response.data;
} catch (error) {
console.error(`Error al obtener tareas de estado ${estado}:`, error);
return [];
}
}
//Función principal para obtener todos los datos del proyecto y sus tareas
async function getProjectAndTasks() {
setLoading(true);
try {
const projectData = await fetchProjectData();
// Obtener administrador
const adminData = await fetchUserData(projectData.administrador);
// Obtener colaboradores
const collaborators = await Promise.all(
projectData.colaboradores.map((colaboradorId) =>
fetchUserData(colaboradorId)
)
);
// Actualizar proyecto con datos completos
setProject({
...projectData,
administrador: adminData,
colaboradores: collaborators.filter(Boolean),
});
// Obtener y establecer tareas según estado
const [todo, inProgress, toReview, done] = await Promise.all([
fetchTaskData("pendiente"),
fetchTaskData("en_proceso"),
fetchTaskData("en_revision"),
fetchTaskData("completada"),
]);
setTodoTasks(todo);
setInProgressTasks(inProgress);
setToReviewTasks(toReview);
setDoneTasks(done);
} catch (error) {
console.error(
"Error al cargar los datos del proyecto y tareas:",
error
);
}
}
async function fetchUsers() {
try {
const response = await newFetch(
`${import.meta.env.VITE_BASE_API}usuarios`,
"GET",
null,
{ Authorization: `Bearer ${token}` }
);
if (response.error) throw new Error(response.error);
return response.data;
} catch (error) {
console.error("Error al obtener los usuarios:", error);
}
}
async function getUsers() {
try {
const usersData = await fetchUsers();
setUsers(usersData);
} catch (error) {
console.error("Error al obtener los usuarios:", error);
} finally {
setLoading(false);
}
}
if (id && token) {
getProjectAndTasks();
getUsers();
}
}, [
id,
token,
newFetch,
setProject,
setLoading,
setTodoTasks,
setInProgressTasks,
setToReviewTasks,
setDoneTasks,
]);
if (loading) {
return <h1>Cargando...</h1>;
}
return (
project && (
<div className="contenedor__info">
<header className="info__header">
<div className="contenedor__image">
<img
className="header__image"
src={isDarkMode ? beeDark : bee}
alt="Logo de WorkHive"
/>
<h1 className="header__titulo">{project.nombre}</h1>
</div>
<TeamMenu
teamMembers={[project.administrador, ...project.colaboradores]}
/>
</header>
<section className="info__proyecto">
<div className="proyecto__descripcion">
<h1 className="descripcion__titulo">Descripción de proyecto</h1>
<p className="descripcion__parrafo">{project.descripcion}</p>
</div>
<div className="proyecto__fechas">
<div className="fechas__descripcion">
<p className="fechas__parrafo">
<span>Fecha de inicio: </span>
{new Date(project.fechaInicio).toLocaleDateString()}
</p>
</div>
<div className="fechas__descripcion">
<p className="fechas__parrafo">
<span>Fecha de fin: </span>
{new Date(project.fechaFin).toLocaleDateString()}
</p>
</div>
</div>
<div className="proyecto__administrador">
<h1 className="administrador__titulo">Administrador</h1>
<p className="administrador__nombre">
{project.administrador.nombre}
</p>
</div>
</section>
<section className="contenedor__tareas">
<BoardTask
name="TO DO"
type="todo"
panels={todoTasks}
idTablero={id}
/>
<BoardTask
name="IN PROGRESS"
type="inprogress"
panels={inProgressTasks}
idTablero={id}
/>
<BoardTask
name="TO REVIEW"
type="toreview"
panels={toReviewTasks}
idTablero={id}
/>
<BoardTask
name="DONE"
type="done"
panels={doneTasks}
idTablero={id}
/>
</section>
<EditMenuProject
id={id}
onAddPerson={async (email) => {
try {
const user = users.find((u) => u.email === email);
if (user) {
if (project.administrador._id === user._id) {
setError("El usuario ya está en el proyecto");
throw "El usuario ya está en el proyecto";
} else {
const colaborador = project.colaboradores.find(
(u) => u._id === user._id
);
if (colaborador) {
setError("El usuario ya está en el proyecto");
throw "El usuario ya está en el proyecto";
} else {
const newCollaborators = [...project.colaboradores, user];
setProject({ ...project, colaboradores: newCollaborators });
const colaboradorResponse = await newFetch(
import.meta.env.VITE_BASE_API +
`tableros/${id}/colaboradores`,
"POST",
{ userId: user._id },
{ Authorization: `Bearer ${token}` }
);
if (colaboradorResponse.error) {
setError(colaboradorResponse.error);
throw colaboradorResponse.error;
}
setCollaboratorAdded(true);
}
}
} else {
setError("El usuario no está registrado");
throw "El usuario no está registrado";
}
} catch (error) {
console.error("Error al agregar persona al proyecto:", error);
}
}}
onDeleteProject={async () => {
try {
const response = await newFetch(
import.meta.env.VITE_BASE_API + `tableros/${id}`,
"DELETE",
null,
{ Authorization: `Bearer ${token}` }
);
if (response.error) throw new Error(response.error);
clearProject();
navigate("/usuario");
} catch (error) {
console.error("Error al eliminar proyecto:", error);
}
}}
/>
</div>
)
);
};
export default ProyectInfo;