diff --git a/frontend/src/components/EditProjectModal.jsx b/frontend/src/components/EditProjectModal.jsx
new file mode 100644
index 0000000..12e5f03
--- /dev/null
+++ b/frontend/src/components/EditProjectModal.jsx
@@ -0,0 +1,86 @@
+import React, { useState, useEffect } from 'react';
+import * as projectService from '../services/projectService';
+
+const EditProjectModal = ({
+ isOpen,
+ onClose,
+ project,
+ onProjectUpdated
+}) => {
+ const [title, setTitle] = useState('');
+ const [description, setDescription] = useState('');
+
+ // Pre-fill fields when modal opens or project changes
+ useEffect(() => {
+ if (project) {
+ setTitle(project.title || '');
+ setDescription(project.description || '');
+ }
+ }, [project]);
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ try {
+ const updatedProject = await projectService.updateProject(project._id, {
+ title,
+ description,
+ });
+ onProjectUpdated(updatedProject);
+ onClose();
+ } catch (error) {
+ console.error('Failed to update project:', error);
+ }
+ };
+
+ if (!isOpen) return null;
+
+ return (
+
+ );
+};
+
+export default EditProjectModal;
diff --git a/frontend/src/pages/ProjectPage.jsx b/frontend/src/pages/ProjectPage.jsx
index fdac960..69b86aa 100644
--- a/frontend/src/pages/ProjectPage.jsx
+++ b/frontend/src/pages/ProjectPage.jsx
@@ -6,8 +6,11 @@ import * as taskService from '../services/taskService';
import TaskColumn from '../components/TaskColumn';
import TaskModal from '../components/TaskModal';
import socket from '../services/socketService';
-
+import EditProjectModal from '../components/EditProjectModal';
const ProjectPage = () => {
+ // State for Edit modal
+ const [isEditModalOpen, setIsEditModalOpen] = useState(false);
+
const { projectId } = useParams();
const navigate = useNavigate(); // Get the navigate function
const { user } = useAuth();
@@ -34,13 +37,13 @@ const ProjectPage = () => {
socket.emit('joinProject', projectId);
const handleTaskUpdate = (updatedTask) => {
- setTasks(currentTasks =>
- currentTasks.map(task =>
+ setTasks(currentTasks =>
+ currentTasks.map(task =>
task._id === updatedTask._id ? updatedTask : task
)
);
};
-
+
socket.on('taskUpdated', handleTaskUpdate);
return () => {
@@ -48,6 +51,10 @@ const ProjectPage = () => {
};
}, [projectId], fetchProjectData);
+ const handleProjectUpdated = (updated) => {
+ setProject(updated); // instantly refresh UI
+ };
+
const handleInviteMember = async (e) => {
e.preventDefault();
if (!inviteEmail) return;
@@ -110,27 +117,35 @@ const ProjectPage = () => {
}
};
-return (
+ return (
← Back to Dashboard
-
-
{project.title}
-
{project.description}
-
-
- {/* Conditionally rendered Delete Project button */}
- {project.isOwner && (
-
- )}
- {/* Single Add Task button */}
-
@@ -151,8 +166,8 @@ return (
{user && project.owner && user._id === project.owner._id && (
- setIsModalOpen(false)}
onTaskSaved={fetchProjectData}
projectId={projectId}
taskToEdit={taskToEdit}
/>
+ setIsEditModalOpen(false)}
+ project={project}
+ onProjectUpdated={handleProjectUpdated}
+ />
);
};
diff --git a/frontend/src/services/projectService.js b/frontend/src/services/projectService.js
index 0b4a8e0..c26f3a1 100644
--- a/frontend/src/services/projectService.js
+++ b/frontend/src/services/projectService.js
@@ -28,4 +28,9 @@ export const addMemberToProject = async (projectId, email) => {
export const deleteProject = async (projectId) => {
const response = await api.delete(`/projects/${projectId}`);
return response.data;
+};
+
+export const updateProject = async (projectId, projectData) => {
+ const response = await api.put(`/projects/${projectId}`, projectData);
+ return response.data;
};
\ No newline at end of file