diff --git a/src/App.tsx b/src/App.tsx index 27736ba..791fdfc 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -66,7 +66,9 @@ function App() { }, { - path: "assignments/edit/:id/assignreviewer", + //path to be updated as below once create assignments page is completed + //"assignments/edit/:id/assignreviewer" + path: "assignments/edit/assignreviewer", element: , loader: loadAssignment, }, diff --git a/src/pages/Assignments/AssignReviewer.tsx b/src/pages/Assignments/AssignReviewer.tsx index 925c0e2..10b68f4 100644 --- a/src/pages/Assignments/AssignReviewer.tsx +++ b/src/pages/Assignments/AssignReviewer.tsx @@ -1,96 +1,190 @@ -import React, { useMemo } from 'react'; -import { Button, Container, Row, Col } from 'react-bootstrap'; -// import { useNavigate } from 'react-router-dom'; -import { useLoaderData } from 'react-router-dom'; -import Table from "components/Table/Table"; -import { createColumnHelper } from "@tanstack/react-table"; +import React, { useState } from "react"; +import './AssignReviewerStyle.css'; +import initialData from "./DummyData.json"; -interface IReviewer { - id: number; +interface Reviewer { name: string; + username: string; + status: string; } -const columnHelper = createColumnHelper(); +interface IContributor { + name: string; + username: string; +} + +interface RowData { + topic: string; + contributors: IContributor[]; + reviewers: Reviewer[]; +} + +//Initial data for the table +const data: RowData[] = initialData as RowData[]; const AssignReviewer: React.FC = () => { - const assignment: any = useLoaderData(); - // const navigate = useNavigate(); + // State variables for modal, selected topic, contributors, and inputs + const [modalOpen, setModalOpen] = useState(false); + const [selectedTopic, setSelectedTopic] = useState(""); + const [selectedContributors, setSelectedContributors] = useState([]); + const [reviewerName, setReviewerName] = useState(""); + const [reviewerUsername, setReviewerUsername] = useState(""); + const [tableData, setTableData] = useState(data); - // Dummy data for reviewers - const reviewers = useMemo(() => [ - { id: 1, name: 'Reviewer 1' }, - { id: 2, name: 'Reviewer 2' }, - { id: 3, name: 'Reviewer 3' }, - // ...other reviewers - ], []); + // Opens a pop up window to assign a reviewer, populating topic and contributors + const openModal = (topic: string, contributors: IContributor[]) => { + const contributorDetails = contributors.map( + (contributor) => `${contributor.name} (${contributor.username})` + ); - const columns = useMemo(() => [ - columnHelper.display({ - id: 'select', - header: () => 'Select', - cell: () => ( - // Center the checkbox - ) - }), - columnHelper.accessor('name', { - header: () => 'Reviewer', - cell: info => info.getValue() - }), - columnHelper.display({ - id: 'actions', - header: () => 'Action', - cell: () => ( - - ) - }) - ], []); + setSelectedTopic(topic); + setSelectedContributors(contributorDetails); + setModalOpen(true); + }; + + // Closes the pop up window and clears the reviewer name and username + const closeModal = () => { + setModalOpen(false); + setReviewerName(""); + setReviewerUsername("") + }; - const handleAssignReviewers = () => { - console.log('Assigned reviewers'); - // Logic to assign selected reviewers goes here + // Adds a new reviewer to the selected topic in the table + const handleAddReviewer = () => { + if (reviewerName.trim()) { + setTableData((prevData) => + prevData.map((row) => + row.topic === selectedTopic + ? { + ...row, + reviewers: [ + ...row.reviewers, + { name: reviewerName, username: reviewerUsername, status: "Pending" }, + ], + } + : row + ) + ); + closeModal(); + } }; - // const handleClose = () => { - // navigate(-1); // Go back to the previous page - // }; + // Changes a reviewer’s status to "Pending" when "Unsubmit" is clicked + const handleUnsubmit = (topic: string, reviewerName: string) => { + setTableData((prevData) => + prevData.map((row) => + row.topic === topic + ? { + ...row, + reviewers: row.reviewers.map((reviewer) => + reviewer.name === reviewerName + ? { ...reviewer, status: "Pending" } + : reviewer + ), + } + : row + ) + ); + }; return ( - -
- This is a placeholder page and is still in progress. -
- - -

Assign Reviewer - {assignment.name}

- -
-
- - - +

Assign Reviewer

+

Assignment: Final Project (and design doc)

+
+ + + + + + + + + + {tableData.map((row, index) => ( + + + + + + + ))} + +
Topic selectedContributorsReviewed byAdd reviewer
{row.topic} + {/* Rendering contributors list */} + {row.contributors.map((contributor, idx) => ( +
+ {contributor.name} ({contributor.username}) +
+ ))} +
+ {/* Rendering reviewers and their statuses */} + {row.reviewers.length > 0 ? ( + row.reviewers.map((reviewer, idx) => ( +
+ {reviewer.name} ({reviewer.username}) - Review status: {reviewer.status} + {reviewer.status === "Submitted" && ( + handleUnsubmit(row.topic, reviewer.name)} + > + {" ("}Unsubmit{")"} + + )} +
+ )) + ) : ( + No reviewers assigned + )} +
+ {/* Button to add reviewer, triggers modal */} + +
- }} - /> - -
- - - {/* */} - - - -
+ {/* Modal for adding a reviewer */} + {modalOpen && ( +
+
+

Add reviewer

+

Topic: {selectedTopic}

+

Contributors: {selectedContributors.join(", ")}

+ setReviewerName(e.target.value)} + className="input-field" + /> + setReviewerUsername(e.target.value)} + className="input-field" + /> + + +
+
+ )} + ); }; -export default AssignReviewer; \ No newline at end of file +export default AssignReviewer; diff --git a/src/pages/Assignments/AssignReviewerStyle.css b/src/pages/Assignments/AssignReviewerStyle.css new file mode 100644 index 0000000..7eab281 --- /dev/null +++ b/src/pages/Assignments/AssignReviewerStyle.css @@ -0,0 +1,94 @@ +/* Container for the whole component */ +.assign-reviewer-container { + width: 100%; + padding: 20px; + box-sizing: border-box; + font-family: Arial, sans-serif; + } + + /* Table Styling */ + .assign-reviewer-table { + width: 100%; + border-collapse: collapse; + margin-top: 20px; + } + + .assign-reviewer-table th, + .assign-reviewer-table td { + vertical-align: top; + padding: 10px; + text-align: left; + border: 1px solid #ddd; + } + .assign-reviewer-table td div { + margin-bottom: 5px; /* Adds spacing between lines */ + } + + .assign-reviewer-table th { + background-color: #f4f4f4; + } + + /* Buttons */ + .add-reviewer-button, + .unsubmit-button, + .submit-button, + .cancel-button { + padding: 8px 16px; + border: none; + border-radius: 5px; + color: white; + cursor: pointer; + } + + .add-reviewer-button { + background-color: green; + } + + .unsubmit-link { + color: #007bff; + cursor: pointer; + } + + .unsubmit-link:hover { + color: lightgreen; + } + + .submit-button { + background-color: green; + width: 100%; + } + + .cancel-button { + background-color: gray; + width: 100%; + margin-top: 10px; + } + + /* Modal Styles */ + .modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + } + + .modal-content { + background: white; + padding: 20px; + border-radius: 5px; + width: 300px; + } + + .input-field { + width: 100%; + padding: 8px; + margin: 10px 0; + border: 1px solid #ddd; + border-radius: 5px; + } + \ No newline at end of file diff --git a/src/pages/Assignments/AssignmentEditor.tsx b/src/pages/Assignments/AssignmentEditor.tsx index bde4959..d1d80fe 100644 --- a/src/pages/Assignments/AssignmentEditor.tsx +++ b/src/pages/Assignments/AssignmentEditor.tsx @@ -181,8 +181,10 @@ const AssignmentEditor: React.FC = ({ mode }) => { Create Teams - -
navigate(`/assignments/edit/${assignmentData.id}/assignreviewer`)}> + {/* Line 187 To be updated as below once create assignments page is completed + +
navigate(`/assignments/edit/${assignmentData.id}/assignreviewer`)}> */} +
navigate(`/assignments/edit/assignreviewer`)}> Assign Reviewer
diff --git a/src/pages/Assignments/DummyData.json b/src/pages/Assignments/DummyData.json new file mode 100644 index 0000000..7a18f8c --- /dev/null +++ b/src/pages/Assignments/DummyData.json @@ -0,0 +1,54 @@ +[ + { + "topic": "E2450. Refactor assignments_controller.rb", + "contributors": [ + { "name": "Alice anna", "username": "alice123" }, + { "name": "Bob sam", "username": "bob456" } + ], + "reviewers": [ + { "name": "User1", "username": "username1", "status": "Submitted" } + ] + }, + { + "topic": "E2451. Reimplement feedback_response_map.rb", + "contributors": [ + { "name": "Bob sam", "username": "bob123" }, + { "name": "Eve wesley", "username": "eve123" } + ], + "reviewers": [ + { "name": "user2", "username": "username2", "status": "Pending" }, + { "name": "user3", "username": "username3", "status": "Submitted" } + ] + }, + { + "topic": "E2452. Refactor review_mapping_controller.rb", + "contributors": [ + { "name": "Charlie boo", "username": "charlie123" } + ], + "reviewers": [] + }, + { + "topic": "E2458. User management and users table", + "contributors": [ + { "name": "Harley jad", "username": "harley123" }, + { "name": "Javed son", "username": "javed1234" }, + { "name": "Leo mee", "username": "leo123" } + ], + "reviewers": [ + { "name": "user2", "username": "username2", "status": "Pending" }, + { "name": "user3", "username": "username3", "status": "Submitted" } + ] + }, + { + "topic": "E2467. UI for View Submissions", + "contributors": [ + { "name": "Shadow box", "username": "shadow123" }, + { "name": "Bradon kin", "username": "bradon123" } + ], + "reviewers": [ + { "name": "user2", "username": "username2", "status": "Pending" }, + { "name": "user3", "username": "username3", "status": "Submitted" } + ] + } + ] + \ No newline at end of file