From 5a07b9f78bf5f25b2f78c686ca2818fc545e5abd Mon Sep 17 00:00:00 2001 From: prathyu99 Date: Tue, 16 Apr 2024 20:55:33 -0400 Subject: [PATCH 01/14] created a new page StudentTasks under student role and added a basic table displaying the projects. --- src/App.tsx | 2 + .../StudentTasks/StudentTasks.module.css | 97 +++++++++++++++++++ src/pages/StudentTasks/StudentTasks.tsx | 85 ++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 src/pages/StudentTasks/StudentTasks.module.css create mode 100644 src/pages/StudentTasks/StudentTasks.tsx diff --git a/src/App.tsx b/src/App.tsx index e3e7ab6..6ee648e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -26,6 +26,7 @@ import Home from "pages/Home"; import Questionnaire from "pages/EditQuestionnaire/Questionnaire"; import Courses from "pages/Courses/Course"; import CourseEditor from "pages/Courses/CourseEditor"; +import StudentTasks from "pages/StudentTasks/StudentTasks"; import { loadCourseInstructorDataAndInstitutions } from "pages/Courses/CourseUtil"; import TA from "pages/TA/TA"; import TAEditor from "pages/TA/TAEditor"; @@ -42,6 +43,7 @@ function App() { { path: "login", element: }, { path: "logout", element: } /> }, { path: "edit-questionnaire", element: } /> }, + { path: "student_tasks", element: } leastPrivilegeRole={ROLE.STUDENT} /> }, { path: "assignments", element: } leastPrivilegeRole={ROLE.TA} />, diff --git a/src/pages/StudentTasks/StudentTasks.module.css b/src/pages/StudentTasks/StudentTasks.module.css new file mode 100644 index 0000000..33b9226 --- /dev/null +++ b/src/pages/StudentTasks/StudentTasks.module.css @@ -0,0 +1,97 @@ +.container { + font-family: Arial, sans-serif; /* Change to the font of your choice */ + margin: 20px; +} + +h1 { + color: #333; /* Dark text for the header */ + text-align: left; +} + +table { + width: 100%; + border-collapse: collapse; + margin-top: 20px; /* Add space above the table */ +} + +table, +th, +td { + border: 1px solid #ddd; /* Light grey border */ +} + +th { + background-color: #f8f8f8; /* Light grey background */ + color: #333; /* Dark text for headers */ + text-align: left; + padding: 8px; /* Padding inside the header cells */ +} + +td { + padding: 8px; /* Padding inside cells */ + text-align: left; +} + +th:first-child, +td:first-child { + border-left: none; +} + +th:last-child, +td:last-child { + border-right: none; +} + +tr:nth-child(even) { + background-color: #f2f2f2; /* Zebra striping for rows */ +} + +/* Styling for the badge info icon and checkboxes */ +.badge-info-icon, +.publishing-rights-checkbox { + cursor: pointer; + margin-left: 5px; +} + +/* Styling for the checkbox when it's checked */ +.publishing-rights-checkbox:checked { + accent-color: #009688; /* Teal-like color */ +} + +/* Additional styles */ +/* Align the table header and data to match the design */ +thead tr { + font-weight: bold; +} + +/* This class is for the status indicator icons */ +.status-indicator { + color: #009688; /* Teal-like color for icons */ + margin-left: 5px; +} + +/* Disable the checkboxes visually */ +input[type="checkbox"][disabled] { + opacity: 0.6; /* Transparency to show it's disabled */ + cursor: not-allowed; +} + +/* Info icons in the table */ +.info-icon { + font-style: normal; + color: #017bff; /* Blue color for info icon */ + cursor: help; +} + +/* This can be used to style the surrounding sections like task counts and team member lists */ +.side-info { + color: #333; + padding: 10px 0; +} + +.side-info .number { + font-weight: bold; + color: #d9534f; /* Red color for the number badge */ +} + +/* You may need to add responsiveness or additional styles as required */ diff --git a/src/pages/StudentTasks/StudentTasks.tsx b/src/pages/StudentTasks/StudentTasks.tsx new file mode 100644 index 0000000..4cfb17e --- /dev/null +++ b/src/pages/StudentTasks/StudentTasks.tsx @@ -0,0 +1,85 @@ +import React, { useState } from 'react'; +import styles from './StudentTasks.module.css'; + +// Define the types for a single task and the associated course +type Task = { + id: number; + assignment: string; + course: string; + topic: string; + currentStage: string; + reviewGrade: string; + badges: string; + stageDeadline: string; + publishingRights: boolean; +}; + +type Props = {}; + +const StudentTasks: React.FC = () => { + // Initial tasks state + const [tasks, setTasks] = useState([ + { + id: 1, + assignment: 'Program 1', + course: 'CSC/ECE 517, Spring 2024', + topic: '-', + currentStage: 'Finished', + reviewGrade: 'N/A', + badges: '', + stageDeadline: '2024-01-31 00:00:00 -0500', + publishingRights: false, + }, + { + id: 2, + assignment: 'Program 1', + course: 'CSC/ECE 517, Spring 2024', + topic: '-', + currentStage: 'Finished', + reviewGrade: 'N/A', + badges: '', + stageDeadline: '2024-01-31 00:00:00 -0500', + publishingRights: false, + }, + // ... add additional tasks as needed + ]); + + // Render the list of tasks within a container + return ( +
+

Assignments

+ + + + + + + + + + + + + + + {tasks.map((task) => ( + + + + + + + + + + + ))} + +
AssignmentCourseTopicCurrent StageReview GradeBadgesStage DeadlinePublishing Rights
{task.assignment}{task.course}{task.topic}{task.currentStage}{task.reviewGrade}{task.badges}{task.stageDeadline} + +
+
+ ); +}; + +export default StudentTasks; From e01eee6e1ec35cf5b7e87818985b6a2b0d436aa9 Mon Sep 17 00:00:00 2001 From: prathyu99 Date: Thu, 18 Apr 2024 21:46:58 -0400 Subject: [PATCH 02/14] Added link to navigate to new Student Task Detail page --- src/App.tsx | 2 + src/pages/StudentTasks/StudentTaskDetail.tsx | 15 ++++ src/pages/StudentTasks/StudentTasks.tsx | 92 ++++++++++---------- 3 files changed, 63 insertions(+), 46 deletions(-) create mode 100644 src/pages/StudentTasks/StudentTaskDetail.tsx diff --git a/src/App.tsx b/src/App.tsx index 6ee648e..0e757ed 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -27,6 +27,7 @@ import Questionnaire from "pages/EditQuestionnaire/Questionnaire"; import Courses from "pages/Courses/Course"; import CourseEditor from "pages/Courses/CourseEditor"; import StudentTasks from "pages/StudentTasks/StudentTasks"; +import StudentTaskDetail from "pages/StudentTasks/StudentTaskDetail"; import { loadCourseInstructorDataAndInstitutions } from "pages/Courses/CourseUtil"; import TA from "pages/TA/TA"; import TAEditor from "pages/TA/TAEditor"; @@ -44,6 +45,7 @@ function App() { { path: "logout", element: } /> }, { path: "edit-questionnaire", element: } /> }, { path: "student_tasks", element: } leastPrivilegeRole={ROLE.STUDENT} /> }, + { path: "student_task_detail/:id", element: } leastPrivilegeRole={ROLE.STUDENT} /> }, { path: "assignments", element: } leastPrivilegeRole={ROLE.TA} />, diff --git a/src/pages/StudentTasks/StudentTaskDetail.tsx b/src/pages/StudentTasks/StudentTaskDetail.tsx new file mode 100644 index 0000000..35cf31c --- /dev/null +++ b/src/pages/StudentTasks/StudentTaskDetail.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { useParams } from 'react-router-dom'; + +const StudentTaskDetail: React.FC = () => { + const { id } = useParams(); // This hook allows you to grab the ID from the URL + + return ( +
+

Assignment Title: {id}

+ {/* Additional details about the assignment could be fetched and displayed here */} +
+ ); +}; + +export default StudentTaskDetail; \ No newline at end of file diff --git a/src/pages/StudentTasks/StudentTasks.tsx b/src/pages/StudentTasks/StudentTasks.tsx index 4cfb17e..156fbae 100644 --- a/src/pages/StudentTasks/StudentTasks.tsx +++ b/src/pages/StudentTasks/StudentTasks.tsx @@ -1,5 +1,6 @@ import React, { useState } from 'react'; import styles from './StudentTasks.module.css'; +import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; // Define the types for a single task and the associated course type Task = { @@ -17,7 +18,6 @@ type Task = { type Props = {}; const StudentTasks: React.FC = () => { - // Initial tasks state const [tasks, setTasks] = useState([ { id: 1, @@ -31,55 +31,55 @@ const StudentTasks: React.FC = () => { publishingRights: false, }, { - id: 2, - assignment: 'Program 1', - course: 'CSC/ECE 517, Spring 2024', - topic: '-', - currentStage: 'Finished', - reviewGrade: 'N/A', - badges: '', - stageDeadline: '2024-01-31 00:00:00 -0500', - publishingRights: false, - }, + id: 2, + assignment: 'Program 2', + course: 'CSC/ECE 517, Spring 2024', + topic: '-', + currentStage: 'Finished', + reviewGrade: 'N/A', + badges: '', + stageDeadline: '2024-01-31 00:00:00 -0500', + publishingRights: false, + }, // ... add additional tasks as needed ]); // Render the list of tasks within a container return ( -
-

Assignments

- - - - - - - - - - - - - - - {tasks.map((task) => ( - - - - - - - - - +
+

Assignments

+
AssignmentCourseTopicCurrent StageReview GradeBadgesStage DeadlinePublishing Rights
{task.assignment}{task.course}{task.topic}{task.currentStage}{task.reviewGrade}{task.badges}{task.stageDeadline} - -
+ + + + + + + + + + - ))} - -
AssignmentCourseTopicCurrent StageReview GradeBadgesStage DeadlinePublishing Rights
-
- ); -}; + + + {tasks.map((task) => ( + + {task.assignment} + {task.course} + {task.topic} + {task.currentStage} + {task.reviewGrade} + {task.badges} + {task.stageDeadline} + + + + + ))} + + + + ); + }; -export default StudentTasks; + export default StudentTasks; \ No newline at end of file From 111ba6a5f5552f351dbd02c1e1b07b64eac2e30b Mon Sep 17 00:00:00 2001 From: prathyu99 Date: Thu, 18 Apr 2024 21:50:56 -0400 Subject: [PATCH 03/14] added checkbox for publishing rights --- src/pages/StudentTasks/StudentTasks.tsx | 81 ++++++++++++++----------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/src/pages/StudentTasks/StudentTasks.tsx b/src/pages/StudentTasks/StudentTasks.tsx index 156fbae..83f2c55 100644 --- a/src/pages/StudentTasks/StudentTasks.tsx +++ b/src/pages/StudentTasks/StudentTasks.tsx @@ -44,42 +44,53 @@ const StudentTasks: React.FC = () => { // ... add additional tasks as needed ]); + // Function to toggle publishing rights + const togglePublishingRights = (id: number) => { + setTasks(prevTasks => prevTasks.map(task => + task.id === id ? {...task, publishingRights: !task.publishingRights} : task + )); + }; + // Render the list of tasks within a container return ( -
-

Assignments

- - - - - - - - - - - +
+

Assignments

+
AssignmentCourseTopicCurrent StageReview GradeBadgesStage DeadlinePublishing Rights
+ + + + + + + + + + + + + + {tasks.map((task) => ( + + + + + + + + + - - - {tasks.map((task) => ( - - - - - - - - - - - ))} - -
AssignmentCourseTopicCurrent StageReview GradeBadgesStage DeadlinePublishing Rights
{task.assignment}{task.course}{task.topic}{task.currentStage}{task.reviewGrade}{task.badges}{task.stageDeadline} + togglePublishingRights(task.id)} + /> +
{task.assignment}{task.course}{task.topic}{task.currentStage}{task.reviewGrade}{task.badges}{task.stageDeadline} - -
-
- ); - }; + ))} + + + + ); +}; - export default StudentTasks; \ No newline at end of file +export default StudentTasks; From 2ad4e8d56d1584e94bb3b98a85753bd30274775a Mon Sep 17 00:00:00 2001 From: prathyu99 Date: Thu, 18 Apr 2024 22:20:22 -0400 Subject: [PATCH 04/14] added css for links --- .../StudentTasks/StudentTasks.module.css | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/pages/StudentTasks/StudentTasks.module.css b/src/pages/StudentTasks/StudentTasks.module.css index 33b9226..99895b5 100644 --- a/src/pages/StudentTasks/StudentTasks.module.css +++ b/src/pages/StudentTasks/StudentTasks.module.css @@ -1,5 +1,5 @@ .container { - font-family: Arial, sans-serif; /* Change to the font of your choice */ + font-family: Arial, sans-serif; /* Add "Helvetica Neue" if you have it available */ margin: 20px; } @@ -94,4 +94,26 @@ input[type="checkbox"][disabled] { color: #d9534f; /* Red color for the number badge */ } -/* You may need to add responsiveness or additional styles as required */ +/* New styles for the links based on the uploaded image */ +table td { + padding: 8px; /* Padding specified in your screenshot */ +} + +table td a { + color: #986633; /* The color specified in your screenshot */ + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; /* The font stack specified */ + font-size: 14px; /* The font size specified */ + padding: 0px 1px 2px; /* The padding specified */ + display: block; + margin: 10px 0; + text-decoration: none; + font-weight: bold; + border-radius: 4px; + transition: box-shadow 0.2s ease-in-out, background-color 0.3s; + /* No specific font-weight is given, so you might keep it normal or bold */ +} + +table td a:hover, table td a:focus { + color: #337ab7; /* Change color to #337ab7 on hover */ + text-decoration: underline; /* Underline the link on hover */ +} From 15c58c643f474dabab0d336c16b5ca50464f9b4c Mon Sep 17 00:00:00 2001 From: soubhi Date: Tue, 23 Apr 2024 08:19:51 -0400 Subject: [PATCH 05/14] Adding Student Tasks Box --- src/App.tsx | 11 +- .../StudentTasks/StudentTasks.module.css | 52 +++++ src/pages/StudentTasks/StudentTasks.tsx | 184 +++++++++++------- .../StudentTasks/StudentTasksBox.module.css | 103 ++++++++++ src/pages/StudentTasks/StudentTasksBox.tsx | 81 ++++++++ src/pages/StudentTasks/testData.json | 111 +++++++++++ 6 files changed, 472 insertions(+), 70 deletions(-) create mode 100644 src/pages/StudentTasks/StudentTasksBox.module.css create mode 100644 src/pages/StudentTasks/StudentTasksBox.tsx create mode 100644 src/pages/StudentTasks/testData.json diff --git a/src/App.tsx b/src/App.tsx index 0e757ed..4ba3b32 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -26,9 +26,8 @@ import Home from "pages/Home"; import Questionnaire from "pages/EditQuestionnaire/Questionnaire"; import Courses from "pages/Courses/Course"; import CourseEditor from "pages/Courses/CourseEditor"; -import StudentTasks from "pages/StudentTasks/StudentTasks"; -import StudentTaskDetail from "pages/StudentTasks/StudentTaskDetail"; import { loadCourseInstructorDataAndInstitutions } from "pages/Courses/CourseUtil"; +import StudentTasks from "./pages/StudentTasks/StudentTasks"; import TA from "pages/TA/TA"; import TAEditor from "pages/TA/TAEditor"; import { loadTAs } from "pages/TA/TAUtil"; @@ -44,8 +43,10 @@ function App() { { path: "login", element: }, { path: "logout", element: } /> }, { path: "edit-questionnaire", element: } /> }, - { path: "student_tasks", element: } leastPrivilegeRole={ROLE.STUDENT} /> }, - { path: "student_task_detail/:id", element: } leastPrivilegeRole={ROLE.STUDENT} /> }, + { + path: "student_tasks", + element: } leastPrivilegeRole={ROLE.STUDENT} />, + }, { path: "assignments", element: } leastPrivilegeRole={ROLE.TA} />, @@ -210,4 +211,4 @@ function App() { return ; } -export default App; +export default App; \ No newline at end of file diff --git a/src/pages/StudentTasks/StudentTasks.module.css b/src/pages/StudentTasks/StudentTasks.module.css index 99895b5..801a271 100644 --- a/src/pages/StudentTasks/StudentTasks.module.css +++ b/src/pages/StudentTasks/StudentTasks.module.css @@ -117,3 +117,55 @@ table td a:hover, table td a:focus { color: #337ab7; /* Change color to #337ab7 on hover */ text-decoration: underline; /* Underline the link on hover */ } + +/* StudentTasks.module.css */ +.studentTasksLayout { + display: flex; + flex-direction: row; /* aligns children (StudentTasksBox and the tasks list) in a row */ + gap: 20px; /* adds space between the children */ +} + +.studentTasksList { + flex-grow: 1; /* allows the tasks list to take up the remaining space */ +} + + +/* StudentTasks.module.css */ + +.pageLayout { + display: flex; + margin: 16px; +} + +.sidebar { + width: 250px; /* Width of the sidebar */ + margin-right: 20px; /* Spacing between sidebar and main content */ +} + +.mainContent { + flex-grow: 1; + overflow: hidden; /* In case the content is too wide */ +} + +.header { + margin-bottom: 20px; /* Space below the header */ +} + +.tasksTable { + width: 100%; /* Full width of the main content area */ + /* Add more styling for your table */ +} + +/* Add additional styling as needed */ + +.assignments-page { + font-family: 'Arial', sans-serif; +} + +.assignments-title { + color: #333; + text-align: left; + padding: 20px; + font-size: 24px; +} + diff --git a/src/pages/StudentTasks/StudentTasks.tsx b/src/pages/StudentTasks/StudentTasks.tsx index 83f2c55..422c9b0 100644 --- a/src/pages/StudentTasks/StudentTasks.tsx +++ b/src/pages/StudentTasks/StudentTasks.tsx @@ -1,6 +1,13 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { useNavigate, Link } from 'react-router-dom'; +import { RootState } from '../../store/store'; +import useAPI from 'hooks/useAPI'; import styles from './StudentTasks.module.css'; -import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; +import StudentTasksBox from './StudentTasksBox'; +import testData from './testData.json'; + + // Define the types for a single task and the associated course type Task = { @@ -17,80 +24,127 @@ type Task = { type Props = {}; -const StudentTasks: React.FC = () => { - const [tasks, setTasks] = useState([ - { - id: 1, - assignment: 'Program 1', - course: 'CSC/ECE 517, Spring 2024', - topic: '-', - currentStage: 'Finished', - reviewGrade: 'N/A', - badges: '', - stageDeadline: '2024-01-31 00:00:00 -0500', - publishingRights: false, - }, - { - id: 2, - assignment: 'Program 2', - course: 'CSC/ECE 517, Spring 2024', - topic: '-', - currentStage: 'Finished', - reviewGrade: 'N/A', - badges: '', - stageDeadline: '2024-01-31 00:00:00 -0500', - publishingRights: false, - }, - // ... add additional tasks as needed - ]); + +const StudentTasks: React.FC = () => { + const { error, isLoading, data: assignmentResponse, sendRequest: fetchAssignments } = useAPI(); + const { data: coursesResponse, sendRequest: fetchCourses } = useAPI(); + const auth = useSelector((state: RootState) => state.authentication); + const dispatch = useDispatch(); + const navigate = useNavigate(); + + const [tasks, setTasks] = useState([]); + const exampleDuties = testData.duties; + const taskRevisions = testData.revisions; + const studentsTeamedWith = testData.studentsTeamedWith; + + // Fetch assignments and courses data on component mount + useEffect(() => { + const fetchData = async () => { + try { + await Promise.all([ + fetchAssignments({ url: '/assignments' }), + fetchCourses({ url: '/courses' }) + ]); + } catch (error) { + console.error("Error fetching tasks data:", error); + } + }; + fetchData(); + }, [fetchAssignments, fetchCourses]); + + // Merge assignments and courses data + useEffect(() => { + if (assignmentResponse && coursesResponse) { + const mergedTasks = assignmentResponse.data.map((assignment: any) => { + const course = coursesResponse.data.find((c: any) => c.id === assignment.course_id); + return { + id: assignment.id, + assignment: assignment.name, + course: course ? course.name : 'Unknown', + topic: assignment.topic || '-', + currentStage: assignment.currentStage || 'Pending', + reviewGrade: assignment.reviewGrade || 'N/A', + badges: assignment.badges || '', + stageDeadline: assignment.stageDeadline || 'No deadline', + publishingRights: assignment.publishingRights || false + }; + }); + setTasks(mergedTasks); + } + }, [assignmentResponse, coursesResponse]); + + // Error handling for API requests + useEffect(() => { + if (error) { + dispatch({ type: 'SHOW_ALERT', payload: { message: error, variant: 'danger' }}); + } + }, [error, dispatch]); // Function to toggle publishing rights - const togglePublishingRights = (id: number) => { + const togglePublishingRights = useCallback((id: number) => { setTasks(prevTasks => prevTasks.map(task => task.id === id ? {...task, publishingRights: !task.publishingRights} : task )); - }; + }, []); // Render the list of tasks within a container return ( -
-

Assignments

- +
+ +

Student Task List

+
+ + + +
+ + {isLoading ? ( +

Loading tasks...

+ ) : ( +
- - - - - - - - - - - - - {tasks.map((task) => ( - - - - - - - - - + + + + + + + + + - ))} - -
AssignmentCourseTopicCurrent StageReview GradeBadgesStage DeadlinePublishing Rights
{task.assignment}{task.course}{task.topic}{task.currentStage}{task.reviewGrade}{task.badges}{task.stageDeadline} - togglePublishingRights(task.id)} - /> -
AssignmentCourseTopicCurrent StageReview GradeBadgesStage DeadlinePublishing Rights
+ + + {tasks.map((task) => ( + + {task.assignment} + {task.course} + {task.topic} + {task.currentStage} + {task.reviewGrade} + {task.badges} + {task.stageDeadline} + + togglePublishingRights(task.id)} + /> + + + ))} + + + )} +
+ ); }; -export default StudentTasks; +export default StudentTasks; \ No newline at end of file diff --git a/src/pages/StudentTasks/StudentTasksBox.module.css b/src/pages/StudentTasks/StudentTasksBox.module.css new file mode 100644 index 0000000..7e3fed5 --- /dev/null +++ b/src/pages/StudentTasks/StudentTasksBox.module.css @@ -0,0 +1,103 @@ +.student-tasks .table-striped>tbody>tr:nth-of-type(odd)>td, +.student-tasks .table-striped>tbody>tr:nth-of-type(odd)>th { + background-color: #ffffff; + --bs-table-bg-type: none +} + +.student-tasks .table-striped>tbody>tr:nth-of-type(even)>td, +.student-tasks .table-striped>tbody>tr:nth-of-type(even)>th { + background-color: #f2f2f2; + --bs-table-bg-type: none; +} +.taskbox { + padding: 5px; + margin-bottom: 39px; + border: 1px dashed #999999; + float: left; + font-size: 12px; + background: none repeat scroll 0pt 0pt #fafaea; + width: 100%; +} +.tasknum { + color: #FFFFFF; + background-color: #B73204; +} + +.revnum { + color: #FFFFFF; + background-color: #999999; +} + +.notification a { + color:#0066CC +} + +/* StudentTasks.module.css */ + +.pageLayout { + display: flex; + margin: 16px; + } + + .sidebar { + width: 200px; /* Width of the sidebar */ + margin-right: 20px; /* Spacing between sidebar and main content */ + } + + .mainContent { + flex-grow: 1; + overflow: hidden; /* In case the content is too wide */ + } + + .header { + margin-bottom: 20px; /* Space below the header */ + } + + .tasksTable { + width: 100%; /* Full width of the main content area */ + /* Add more styling for your table */ + } + + .section { + margin-bottom: 20px; /* Space between sections */ + } + + .section-header { + font-size: 18px; /* Larger font size for visibility */ + font-weight: bold; /* Bold text for section headers */ + color: #333; /* Darker text for better readability */ + margin-bottom: 10px; /* Space below section header */ + } + + .section-item { + margin-left: 20px; /* Indent for items in the list */ + margin-bottom: 5px; /* Space between items */ + color: #555; /* Slightly lighter text for items */ + } + + .badge { + display: inline-block; + padding: 0.25em 0.4em; + font-size: 75%; + font-weight: 700; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0; + background-color: #a52a2a; + color: white; + } + + .greyBadge{ + padding: 0.25em 0.4em; + font-size: 75%; + font-weight: 700; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0; + background-color: rgb(159, 156, 156); + color: white; + } \ No newline at end of file diff --git a/src/pages/StudentTasks/StudentTasksBox.tsx b/src/pages/StudentTasks/StudentTasksBox.tsx new file mode 100644 index 0000000..b60e695 --- /dev/null +++ b/src/pages/StudentTasks/StudentTasksBox.tsx @@ -0,0 +1,81 @@ +import React from 'react'; +import styles from './StudentTasksBox.module.css'; // Make sure the path to your CSS module is correct + +// Define the types for each prop + type Duty = { + name: string; + dueDate: string; + }; + + type Revision = { + // Your Revision type properties + }; + + type StudentsTeamedWith = { + [semester: string]: string[]; + }; + + interface StudentTasksBoxProps { + duties: Duty[]; + revisions: Revision[]; + studentsTeamedWith: StudentsTeamedWith; + } + + const StudentTasksBox: React.FC = ({ duties, revisions, studentsTeamedWith }) => { + + + // Function to calculate the number of days left until the due date + const calculateDaysLeft = (dueDate: string) => { + const today = new Date(); + const due = new Date(dueDate); + const timeDiff = due.getTime() - today.getTime(); + const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24)); + return daysDiff > 0 ? daysDiff : 0; + }; + + // Find the duties that have not started yet based on the due date + const tasksNotStarted = duties.filter(duty => calculateDaysLeft(duty.dueDate) > 0); + + return ( +
+
+ + Tasks not yet started +
+ + {/* Revisions section (remains empty since revisions array is empty) */} +
+ {revisions.length} + Revisions +
+ + {tasksNotStarted.map((task, index) => { + const daysLeft = calculateDaysLeft(task.dueDate); + return ( +
+ » {task.name} ({daysLeft} day{daysLeft !== 1 ? 's' : ''} left) +
+ ); + })} + + + {/* Students who have teamed with you section */} +
+ Students who have teamed with you +
+ {Object.entries(studentsTeamedWith).map(([semester, students], index) => ( +
+ {semester} + {students.length} + {students.map((student, studentIndex) => ( +
+ » {student} +
+ ))} +
+ ))} +
+ ); +}; + +export default StudentTasksBox; diff --git a/src/pages/StudentTasks/testData.json b/src/pages/StudentTasks/testData.json new file mode 100644 index 0000000..df656a3 --- /dev/null +++ b/src/pages/StudentTasks/testData.json @@ -0,0 +1,111 @@ + +{ + "assignments": [ + { + "name": "Assignment 1", + "course_name": "Course3", + "topic": "Ruby", + "current_stage": "in progress", + "review_grade": { + "comment": "3/5" + }, + "has_badge": false, + "stage_deadline": "3/18", + "publishing_rights": true + }, + { + "name": "Assignment 2", + "course_name": "Course3", + "topic": "Rails", + "current_stage": "in progress", + "review_grade": "N/A", + "has_badge": true, + "stage_deadline": "3/18", + "publishing_rights": true + }, + { + "name": "Assignment 3", + "course_name": "Course3", + "topic": "Git", + "current_stage": "in progress", + "review_grade": "N/A", + "has_badge": true, + "stage_deadline": "3/18", + "publishing_rights": false + }, + { + "name": "Assignment 1", + "course_name": "Course32", + "topic": "AI", + "current_stage": "in progress", + "review_grade": "N/A", + "has_badge": false, + "stage_deadline": "3/25", + "publishing_rights": true + }, + { + "name": "Assignment 2", + "course_name": "Course4", + "topic": "Random Forest", + "current_stage": "finished", + "review_grade": "N/A", + "has_badge": false, + "stage_deadline": "3/28", + "publishing_rights": true + } + ], + "courses": [ + { + "id": 1, + "name": "Course3", + "directory_path": "/path/to/course_files", + "info": null, + "private": false, + "created_at": "2024-04-21T23:46:38.633Z", + "updated_at": "2024-04-21T23:46:38.633Z", + "instructor_id": 2, + "institution_id": 1 + }, + { + "id": 4, + "name": "Course4", + "directory_path": "/path/to/course_files", + "info": null, + "private": false, + "created_at": "2024-04-21T23:46:38.633Z", + "updated_at": "2024-04-21T23:46:38.633Z", + "instructor_id": 2, + "institution_id": 1 + } + + ], + + "duties": [ + { + "name": "Program 1", + "dueDate": "2024-03-18" + }, + { + "name": "Program 2", + "dueDate": "2024-03-18" + }, + { + "name": "OSS project", + "dueDate": "2024-03-18" + }, + { + "name": "OSS project 2", + "dueDate": "2024-03-25" + }, + { + "name": "OSS project 3", + "dueDate": "2024-04-28" + } + ], + "revisions": [ + + ], + "studentsTeamedWith": { + "CSC/ECE 517, Fall 2023": ["teammate one", "teammate two", "teammate three", "teammate four","teammate five", "teammate six", "teammate seven"] + } +} \ No newline at end of file From 544b0715ae89137e4144ac7133930c5ab0ce8ca9 Mon Sep 17 00:00:00 2001 From: soubhi Date: Tue, 23 Apr 2024 19:29:00 -0400 Subject: [PATCH 06/14] Modifying code to fetch data from dummy data --- .../StudentTasks/StudentTasks.module.css | 18 ++ src/pages/StudentTasks/StudentTasks.tsx | 75 ++++---- src/pages/StudentTasks/StudentTasksBox.tsx | 26 +-- src/pages/StudentTasks/testData.json | 161 ++++++++++++++---- 4 files changed, 188 insertions(+), 92 deletions(-) diff --git a/src/pages/StudentTasks/StudentTasks.module.css b/src/pages/StudentTasks/StudentTasks.module.css index 801a271..3bc41e6 100644 --- a/src/pages/StudentTasks/StudentTasks.module.css +++ b/src/pages/StudentTasks/StudentTasks.module.css @@ -169,3 +169,21 @@ table td a:hover, table td a:focus { font-size: 24px; } +/* ... Existing styles ... */ + +.footer { + display: flex; + justify-content: center; + padding: 20px 0; +} + +.footerLink { + margin: 0 10px; + color: #CCAC00; /* Example link color */ + text-decoration: none; +} + +.footerLink:hover { + color: #000000; + text-decoration: underline; +} diff --git a/src/pages/StudentTasks/StudentTasks.tsx b/src/pages/StudentTasks/StudentTasks.tsx index 422c9b0..5f5e58b 100644 --- a/src/pages/StudentTasks/StudentTasks.tsx +++ b/src/pages/StudentTasks/StudentTasks.tsx @@ -16,18 +16,19 @@ type Task = { course: string; topic: string; currentStage: string; - reviewGrade: string; - badges: string; + reviewGrade: string | { comment: string }; + badges: string | boolean; // Assuming badges can be either a string or a boolean stageDeadline: string; publishingRights: boolean; }; + type Props = {}; const StudentTasks: React.FC = () => { - const { error, isLoading, data: assignmentResponse, sendRequest: fetchAssignments } = useAPI(); - const { data: coursesResponse, sendRequest: fetchCourses } = useAPI(); + const participantTasks = testData.participantTasks; + const auth = useSelector((state: RootState) => state.authentication); const dispatch = useDispatch(); const navigate = useNavigate(); @@ -37,48 +38,28 @@ const StudentTasks: React.FC = () => { const taskRevisions = testData.revisions; const studentsTeamedWith = testData.studentsTeamedWith; - // Fetch assignments and courses data on component mount - useEffect(() => { - const fetchData = async () => { - try { - await Promise.all([ - fetchAssignments({ url: '/assignments' }), - fetchCourses({ url: '/courses' }) - ]); - } catch (error) { - console.error("Error fetching tasks data:", error); - } - }; - fetchData(); - }, [fetchAssignments, fetchCourses]); - - // Merge assignments and courses data + useEffect(() => { - if (assignmentResponse && coursesResponse) { - const mergedTasks = assignmentResponse.data.map((assignment: any) => { - const course = coursesResponse.data.find((c: any) => c.id === assignment.course_id); + + if (participantTasks) { + const filteredParticipantTasks = participantTasks.filter(task => task.participant_id === 1); + + const mergedTasks = filteredParticipantTasks.map(task => { return { - id: assignment.id, - assignment: assignment.name, - course: course ? course.name : 'Unknown', - topic: assignment.topic || '-', - currentStage: assignment.currentStage || 'Pending', - reviewGrade: assignment.reviewGrade || 'N/A', - badges: assignment.badges || '', - stageDeadline: assignment.stageDeadline || 'No deadline', - publishingRights: assignment.publishingRights || false + id: task.id, + assignment: task.assignment, + course: task.course, + topic: task.topic || '-', + currentStage: task.current_stage || 'Pending', + reviewGrade: task.review_grade || 'N/A', + badges: task.badges || '', + stageDeadline: task.stage_deadline || 'No deadline', + publishingRights: task.publishing_rights || false }; }); setTasks(mergedTasks); } - }, [assignmentResponse, coursesResponse]); - - // Error handling for API requests - useEffect(() => { - if (error) { - dispatch({ type: 'SHOW_ALERT', payload: { message: error, variant: 'danger' }}); - } - }, [error, dispatch]); +}, [participantTasks]); // Function to toggle publishing rights const togglePublishingRights = useCallback((id: number) => { @@ -102,10 +83,7 @@ const StudentTasks: React.FC = () => { />
- - {isLoading ? ( -

Loading tasks...

- ) : ( + @@ -126,7 +104,7 @@ const StudentTasks: React.FC = () => { - +
{task.course} {task.topic} {task.currentStage}{task.reviewGrade}{typeof task.reviewGrade === 'string' ? task.reviewGrade : task.reviewGrade.comment} {task.badges} {task.stageDeadline} @@ -140,9 +118,14 @@ const StudentTasks: React.FC = () => { ))}
- )}
+ + {/* Footer Section Added */} +
+ Help + Papers on Expertiza +
); }; diff --git a/src/pages/StudentTasks/StudentTasksBox.tsx b/src/pages/StudentTasks/StudentTasksBox.tsx index b60e695..cf84565 100644 --- a/src/pages/StudentTasks/StudentTasksBox.tsx +++ b/src/pages/StudentTasks/StudentTasksBox.tsx @@ -23,6 +23,10 @@ import styles from './StudentTasksBox.module.css'; // Make sure the path to your const StudentTasksBox: React.FC = ({ duties, revisions, studentsTeamedWith }) => { + let totalStudents = 0; + for (const semester in studentsTeamedWith) { + totalStudents += studentsTeamedWith[semester].length; + } // Function to calculate the number of days left until the due date const calculateDaysLeft = (dueDate: string) => { @@ -39,28 +43,28 @@ import styles from './StudentTasksBox.module.css'; // Make sure the path to your return (
- + 0 Tasks not yet started
{/* Revisions section (remains empty since revisions array is empty) */}
- {revisions.length} + {tasksNotStarted.length} Revisions + {tasksNotStarted.map((task, index) => { + const daysLeft = calculateDaysLeft(task.dueDate); + return ( +
+ » {task.name} ({daysLeft} day{daysLeft !== 1 ? 's' : ''} left) +
+ ); + })}
- {tasksNotStarted.map((task, index) => { - const daysLeft = calculateDaysLeft(task.dueDate); - return ( -
- » {task.name} ({daysLeft} day{daysLeft !== 1 ? 's' : ''} left) -
- ); - })} - {/* Students who have teamed with you section */}
+ {totalStudents} Students who have teamed with you
{Object.entries(studentsTeamedWith).map(([semester, students], index) => ( diff --git a/src/pages/StudentTasks/testData.json b/src/pages/StudentTasks/testData.json index df656a3..ca5587e 100644 --- a/src/pages/StudentTasks/testData.json +++ b/src/pages/StudentTasks/testData.json @@ -1,57 +1,148 @@ { - "assignments": [ + "participantTasks": [ { - "name": "Assignment 1", - "course_name": "Course3", + "id": 1, + "assignment": "Program 1", + "course": "CSC 517", "topic": "Ruby", - "current_stage": "in progress", + "current_stage": "In progress", "review_grade": { - "comment": "3/5" + "comment": "40/40" }, - "has_badge": false, - "stage_deadline": "3/18", - "publishing_rights": true + "badges": false, + "stage_deadline": "2024-02-26 12:00:00 -0500", + "publishing_rights": true, + "participant_id": 1 }, { - "name": "Assignment 2", - "course_name": "Course3", + "id": 2, + "assignment": "Program 2", + "course": "CSC 517", "topic": "Rails", - "current_stage": "in progress", + "current_stage": "In progress", "review_grade": "N/A", - "has_badge": true, - "stage_deadline": "3/18", - "publishing_rights": true + "badges": true, + "stage_deadline": "2024-02-26 12:00:00 -0500", + "publishing_rights": false, + "participant_id": 2 }, { - "name": "Assignment 3", - "course_name": "Course3", + "id": 3, + "assignment": "Program 3", + "course": "CSC 517", "topic": "Git", - "current_stage": "in progress", + "current_stage": "In progress", "review_grade": "N/A", - "has_badge": true, - "stage_deadline": "3/18", - "publishing_rights": false + "badges": true, + "stage_deadline": "2024-02-26 12:00:00 -0500", + "publishing_rights": false, + "participant_id": 1 }, { - "name": "Assignment 1", - "course_name": "Course32", - "topic": "AI", - "current_stage": "in progress", + "id": 4, + "assignment": "Program 4", + "course": "CSC 517", + "topic": "Reimplementation Backend", + "current_stage": "In progress", + "review_grade": "120/120", + "badges": false, + "stage_deadline": "2024-02-26 12:00:00 -0500", + "publishing_rights": true, + "participant_id": 1 + }, + { + "id": 5, + "assignment": "Program 5", + "course": "CSC 517", + "topic": "Reimplementation Frontend", + "current_stage": "Finished", "review_grade": "N/A", - "has_badge": false, - "stage_deadline": "3/25", - "publishing_rights": true + "badges": false, + "stage_deadline": "2024-02-26 12:00:00 -0500", + "publishing_rights": false, + "participant_id": 1 }, { - "name": "Assignment 2", - "course_name": "Course4", - "topic": "Random Forest", - "current_stage": "finished", + "id": 6, + "assignment": "OSS Program 1", + "course": "CSC 517", + "topic": "Reimplementation Frontend", + "current_stage": "Finished", "review_grade": "N/A", - "has_badge": false, - "stage_deadline": "3/28", - "publishing_rights": true + "badges": false, + "stage_deadline": "2024-02-26 12:00:00 -0500", + "publishing_rights": false, + "participant_id": 1 + }, + { + "id": 7, + "assignment": "OSS Program 2", + "course": "CSC 517", + "topic": "Reimplementation Frontend", + "current_stage": "Finished", + "review_grade": "N/A", + "badges": false, + "stage_deadline": "2024-02-26 12:00:00 -0500", + "publishing_rights": false, + "participant_id": 1 + }, + { + "id": 8, + "assignment": "Program 5", + "course": "CSC 517", + "topic": "Reimplementation Frontend", + "current_stage": "Finished", + "review_grade": "N/A", + "badges": false, + "stage_deadline": "2024-02-26 12:00:00 -0500", + "publishing_rights": true, + "participant_id": 1 + }, + { + "id": 9, + "assignment": "Program 5", + "course": "CSC 517", + "topic": "Reimplementation Frontend", + "current_stage": "Finished", + "review_grade": "N/A", + "badges": false, + "stage_deadline": "2024-02-26 12:00:00 -0500", + "publishing_rights": true, + "participant_id": 1 + } + ], + + "participants": [ + { + "id": 1, + "assignment_id": 1, + "course_id": 1 + + }, + { + "id": 1, + "assignment_id": 2, + "course_id": 1 + + }, + { + "id": 2, + "assignment_id": 3, + "course_id": 1 + + }, + { + "id": 1, + "assignment_id": 4, + "course_id": 1 + + }, + { + "id": 1, + "assignment_id": 5, + "course_id": 1 + } ], "courses": [ @@ -106,6 +197,6 @@ ], "studentsTeamedWith": { - "CSC/ECE 517, Fall 2023": ["teammate one", "teammate two", "teammate three", "teammate four","teammate five", "teammate six", "teammate seven"] + "CSC/ECE 517, Fall 2024": ["teammate one", "teammate two", "teammate three", "teammate four","teammate five", "teammate six", "teammate seven"] } } \ No newline at end of file From 80b463cecf2da9c0317064c7730728c9afc9aed3 Mon Sep 17 00:00:00 2001 From: prathyu99 Date: Tue, 23 Apr 2024 20:09:53 -0400 Subject: [PATCH 07/14] added icon i which displays text on hover --- public/assets/icons/info.png | Bin 0 -> 1007 bytes src/pages/StudentTasks/StudentTasks.tsx | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 public/assets/icons/info.png diff --git a/public/assets/icons/info.png b/public/assets/icons/info.png new file mode 100644 index 0000000000000000000000000000000000000000..e0626bec0f5a1dd6ae62a0fe578131a85b9ce181 GIT binary patch literal 1007 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z8pn}NEkcg59UmvUF{9L`nl>DSry^7odplSvNn+hu+GdHy)QK2F?C$HG5 z!d3~a!V1U+3F|8Y3;nDA{o-C@9zzrKDK}xwt{K19`Se z86_nJR{Hwo<>h+i#(Mch>H3D2mX`VkM*2oZx=P7{9O-#x!EwNQn0$BtH5O0c3d|4@L;p!@;Rg)$-uy*@9E+gVj(y+ z*fu{XQN-?f+!EF(J(FV=4^on>n+gMje>10COL()!^RmSc<}YUFT!kmAec+yDb$#nG z$8fRsEUES~Rz_CCZ}%R5-gDrs?5-beEuX*6Isd$C$^4mZ4-?gLy-uHNpRq+Z@X&=l z23KaBdtNJ3H*7dw`}N#88@>)*YaklR^id3M1k{w-bO9>1{UCtq@>;$P#I-d6X@@vvIktSe9NoNKdi%iznL#(y zS`%9LZtGC|mZZd6&#~^h`-5#wf*QYt-sn8 iob=}>^Y;JWi~q5&?3A|>>z*YC%7vb;elF{r5}E)4W19T{ literal 0 HcmV?d00001 diff --git a/src/pages/StudentTasks/StudentTasks.tsx b/src/pages/StudentTasks/StudentTasks.tsx index 5f5e58b..c355669 100644 --- a/src/pages/StudentTasks/StudentTasks.tsx +++ b/src/pages/StudentTasks/StudentTasks.tsx @@ -93,8 +93,14 @@ const StudentTasks: React.FC = () => { Current Stage Review Grade Badges - Stage Deadline - Publishing Rights + + Stage Deadline + Info + + + Publishing Rights + Info + @@ -104,7 +110,11 @@ const StudentTasks: React.FC = () => { {task.course} {task.topic} {task.currentStage} - {typeof task.reviewGrade === 'string' ? task.reviewGrade : task.reviewGrade.comment} + + {task.reviewGrade === "N/A" ? "NA" : + Review Grade + } + {task.badges} {task.stageDeadline} From ab936ac1e7afd1ae95c53b68ca649750524da960 Mon Sep 17 00:00:00 2001 From: prathyu99 Date: Tue, 23 Apr 2024 21:02:23 -0400 Subject: [PATCH 08/14] added css to adjust the layout --- .../StudentTasks/StudentTasks.module.css | 22 +++++++++++++++++-- src/pages/StudentTasks/StudentTasks.tsx | 6 ++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/pages/StudentTasks/StudentTasks.module.css b/src/pages/StudentTasks/StudentTasks.module.css index 3bc41e6..99c45cc 100644 --- a/src/pages/StudentTasks/StudentTasks.module.css +++ b/src/pages/StudentTasks/StudentTasks.module.css @@ -4,8 +4,15 @@ } h1 { - color: #333; /* Dark text for the header */ text-align: left; + padding-top: 5px; + padding-left: 15px; + margin-bottom: 0px; + padding-bottom: 0px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.428571429; + color: #333333; } table { @@ -97,6 +104,12 @@ input[type="checkbox"][disabled] { /* New styles for the links based on the uploaded image */ table td { padding: 8px; /* Padding specified in your screenshot */ + max-width: 100px; /* Adjust the width as needed for your design */ + white-space: normal; + padding: 8px; + line-height: 1.428571429; + vertical-align: top; + border-top: 1px solid #ddd; } table td a { @@ -139,7 +152,8 @@ table td a:hover, table td a:focus { .sidebar { width: 250px; /* Width of the sidebar */ - margin-right: 20px; /* Spacing between sidebar and main content */ + margin-right: 20px; + padding-top: 20px;/* Spacing between sidebar and main content */ } .mainContent { @@ -187,3 +201,7 @@ table td a:hover, table td a:focus { color: #000000; text-decoration: underline; } +.centerCheckbox { + text-align: center; + vertical-align: middle; /* This will vertically center it if your table rows are taller than the checkbox */ +} \ No newline at end of file diff --git a/src/pages/StudentTasks/StudentTasks.tsx b/src/pages/StudentTasks/StudentTasks.tsx index c355669..df6d4b3 100644 --- a/src/pages/StudentTasks/StudentTasks.tsx +++ b/src/pages/StudentTasks/StudentTasks.tsx @@ -72,9 +72,9 @@ const StudentTasks: React.FC = () => { return (
-

Student Task List

+

Assignments

+
-