diff --git a/backend/routers/projects.router.js b/backend/routers/projects.router.js
index 8991000cb..f0762b834 100644
--- a/backend/routers/projects.router.js
+++ b/backend/routers/projects.router.js
@@ -10,6 +10,8 @@ router.post('/', ProjectController.create);
router.get('/:ProjectId', ProjectController.project_by_id);
+router.put('/:ProjectId', ProjectController.update);
+
router.patch('/:ProjectId', ProjectController.update);
diff --git a/backend/routers/projects.router.test.js b/backend/routers/projects.router.test.js
index 5233247b9..b4abbc6ee 100644
--- a/backend/routers/projects.router.test.js
+++ b/backend/routers/projects.router.test.js
@@ -73,7 +73,7 @@ describe('UPDATE', () => {
// Update project
const res2 = await request
- .patch(`/api/projects/${res.body._id}`)
+ .put(`/api/projects/${res.body._id}`)
.set(headers)
.send(updatedDataPayload);
expect(res2.status).toBe(200);
diff --git a/client/src/App.js b/client/src/App.js
index 7a2d51b7f..d610b188b 100644
--- a/client/src/App.js
+++ b/client/src/App.js
@@ -21,6 +21,7 @@ import ProjectLeaderDashboard from './pages/ProjectLeaderDashboard';
import UserAdmin from './pages/UserAdmin';
import ProjectList from './pages/ProjectList';
import ManageProjects from './pages/ManageProjects';
+import addProject from './components/manageProjects/addProject';
import HealthCheck from './pages/HealthCheck';
import SecretPassword from './pages/SecretPassword';
import UserWelcome from './pages/UserWelcome';
@@ -49,7 +50,7 @@ const routes = [
{ path: '/events', name: 'events', Component: Events },
{ path: '/useradmin', name: 'useradmin', Component: UserAdmin },
{ path: '/projects', name: 'projects', Component: ProjectList },
- { path: '/projects/create', name: 'projectform', Component: ProjectForm },
+ { path: '/projects/create', name: 'projectform', Component: addProject},
{
path: '/projects/:projectId',
name: 'project',
diff --git a/client/src/api/ProjectApiService.js b/client/src/api/ProjectApiService.js
index 12f4e0763..949bd5ee0 100644
--- a/client/src/api/ProjectApiService.js
+++ b/client/src/api/ProjectApiService.js
@@ -22,6 +22,7 @@ class ProjectApiService {
}
}
+ // Handles the POST request and returns the projects ID.
async create(projectData) {
const {
name,
@@ -58,26 +59,13 @@ class ProjectApiService {
}
}
- async updateProject(projectId, fieldName, fieldValue) {
- let updateValue = fieldValue;
- // These field are arrays, but the form makes them comma separated strings,
- // so this adds it back to db as an arrray.
- if (
- fieldValue &&
- (fieldName === 'partners' || fieldName === 'recruitingCategories')
- ) {
- updateValue = fieldValue
- .split(',')
- .filter((x) => x !== '')
- .map((y) => y.trim());
- }
-
+ async updateProject(projectId, projectData) {
// Update database
const url = `${this.baseProjectUrl}${projectId}`;
const requestOptions = {
- method: 'PATCH',
+ method: 'PUT',
headers: this.headers,
- body: JSON.stringify({ [fieldName]: updateValue }),
+ body: JSON.stringify({ ...projectData }),
};
try {
diff --git a/client/src/components/ProjectForm.js b/client/src/components/ProjectForm.js
index e455fb57e..dc0c5491f 100644
--- a/client/src/components/ProjectForm.js
+++ b/client/src/components/ProjectForm.js
@@ -1,9 +1,11 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState } from 'react';
import { Link, useHistory } from 'react-router-dom';
import { useForm } from 'react-hook-form';
import ProjectApiService from '../api/ProjectApiService';
+
+import { ReactComponent as EditIcon } from '../svg/Icon_Edit.svg';
import { ReactComponent as PlusIcon } from '../svg/PlusIcon.svg';
-import { Redirect } from 'react-router-dom'
+import { Redirect } from 'react-router-dom';
import {
Typography,
Box,
@@ -18,70 +20,7 @@ import {
RadioGroup,
} from '@mui/material';
import { styled } from '@mui/material/styles';
-import useAuth from "../hooks/useAuth"
-
-/** Project Form Component
- *
- * To be used for creating and updating a project
- * */
-
-const simpleInputs = [
- {
- label: 'Project Name',
- name: 'name',
- type: 'text',
- placeholder: 'Enter project name',
- },
- {
- label: 'Project Description',
- name: 'description',
- type: 'textarea',
- placeholder: 'Enter project description',
- },
- {
- label: 'Location',
- name: 'location',
- type: 'text',
- placeholder: 'Enter location for meeting',
- value: /https:\/\/[\w-]*\.?zoom.us\/(j|my)\/[\d\w?=-]+/,
- errorMessage: 'Please enter a valid Zoom URL',
- addressValue: '',
- addressError: 'Invalid address'
-
- },
- // Leaving incase we want to add this back in for updating projects
- // {
- // label: 'GitHub Identifier',
- // name: 'githubIdentifier',
- // type: 'text',
- // placeholder: 'Enter GitHub identifier',
- // },
- {
- label: 'GitHub URL',
- name: 'githubUrl',
- type: 'text',
- placeholder: 'htttps://github.com/'
- },
- {
- label: 'Slack Channel Link',
- name: 'slackUrl',
- type: 'text',
- placeholder: 'htttps://slack.com/',
- },
- {
- label: 'Google Drive URL',
- name: 'googleDriveUrl',
- type: 'text',
- placeholder: 'htttps://drive.google.com/',
- },
- // Leaving incase we want to add this back in for updating projects
- // {
- // label: 'HFLA Website URL',
- // name: 'hflaWebsiteUrl',
- // type: 'text',
- // placeholder: 'htttps://hackforla.org/projects/',
- // },
-];
+import useAuth from '../hooks/useAuth';
/** STYLES
* -most TextField and InputLabel styles are controlled by the theme
@@ -107,54 +46,144 @@ const StyledRadio = styled(Radio)(({ theme }) => ({
/**Project Form Component
* -renders a form for creating and updating a project
- */
-export default function ProjectForm() {
- //seperate state for the location radio buttons
- const [locationType, setLocationType] = React.useState('remote');
- const [activeButton, setActiveButton] = React.useState('close');
- const [newlyCreatedID, setNewlyCreatedID] = useState(null);
+
+/**
+
+/**
+ * Takes Array, formData, projectToEdit, handleChage, isEdit
+ * submitForm, handleChange, and isEdit are for the edit forms.
+ * - arr - simpleInputs arr from the edit page that holds the input's properties.
+ * - formData - passes the current project information to the form.
+ * - projectToEdit - used to grab the of the project we are editing.
+ * - isEdit - Whether its creating a new project or editing one - True or False.
+ * - setFormData - allows us to updated the form data.
+ * */
+export default function ProjectForm({
+ arr,
+ formData,
+ projectToEdit,
+ isEdit,
+ setFormData
+}) {
const history = useHistory();
+
+ // ----------------- States -----------------
+ const [locationType, setLocationType] = useState('remote');
+ // State to track the toggling from Project view to Edit Project View via edit icon.
+ const [editMode, setEditMode] = useState(false);
const { auth } = useAuth();
- const { register, handleSubmit, formState: { errors } } = useForm({
+
+ /**
+ * React Hook Forms
+ * - register
+ * - handleSubmit
+ * - formState
+ * - reset
+ * - defaultValues - holds edit project data
+ *
+ */
+
+ const {
+ register,
+ handleSubmit,
+ reset,
+ formState: { errors },
+ } = useForm({
mode: 'all',
+ // Holds the current project data in state.
defaultValues: {
- name: '',
- description: '',
- location: '',
- githubUrl: '',
- slackUrl: '',
- googleDriveUrl: ''
- }
+ ...formData,
+ },
});
- const routeToNewProjectPage = () => {
- if(newlyCreatedID !== null) {
- history.push(`/projects/${newlyCreatedID}`)
- }
- }
-
- useEffect(() => {
- routeToNewProjectPage()
- },[newlyCreatedID])
+ // ----------------- Submit requests -----------------
- // only handles radio button change
- const handleRadioChange = (event) => {
- setLocationType(event.target.value);
+ // Handles POST request found in api/ProjectApiService.
+ const submitNewProject = async (data) => {
+ const projectApi = new ProjectApiService();
+ try {
+ const id = await projectApi.create(data);
+ history.push(`/projects/${id}`);
+ } catch (errors) {
+ console.error(errors);
+ return;
+ }
};
- const submitForm = async (data) => {
+ // Fires PUT request to update the project,
+ const submitEditProject = async (data) => {
const projectApi = new ProjectApiService();
try {
- const id = await projectApi.create(data);
- setNewlyCreatedID(id);
+ await projectApi.updateProject(projectToEdit._id, data);
} catch (errors) {
console.error(errors);
return;
}
- setActiveButton('close');
+ // setOriginalProjectData(data);
+ setFormData(data);
+ setEditMode(false);
+ };
+
+ // ----------------- Handles and Toggles -----------------
+
+ // Handles the location radio button change.
+ const handleRadioChange = (event) => {
+ setLocationType(event.target.value);
+ };
+
+ // Toggles the project view to edit mode change.
+ const handleEditMode = (event) => {
+ setEditMode(!editMode);
+ // React hook form method to reset data back to original values. Triggered when Edit Mode is cancelled.
+ reset({
+ ...formData,
+ });
+ };
+
+ // ----------------- Icons -----------------
+
+ // Holds the Add New Project Icon and styling.
+ const addIcon = () => {
+ return (
+