Skip to content

Commit

Permalink
Adding Student Tasks Box
Browse files Browse the repository at this point in the history
  • Loading branch information
soubhi committed Apr 23, 2024
1 parent 2ad4e8d commit 15c58c6
Show file tree
Hide file tree
Showing 6 changed files with 472 additions and 70 deletions.
11 changes: 6 additions & 5 deletions src/App.tsx
Expand Up @@ -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";
Expand All @@ -44,8 +43,10 @@ function App() {
{ path: "login", element: <Login /> },
{ path: "logout", element: <ProtectedRoute element={<Logout />} /> },
{ path: "edit-questionnaire", element: <ProtectedRoute element={<Questionnaire />} /> },
{ path: "student_tasks", element: <ProtectedRoute element={<StudentTasks />} leastPrivilegeRole={ROLE.STUDENT} /> },
{ path: "student_task_detail/:id", element: <ProtectedRoute element={<StudentTaskDetail />} leastPrivilegeRole={ROLE.STUDENT} /> },
{
path: "student_tasks",
element: <ProtectedRoute element={<StudentTasks />} leastPrivilegeRole={ROLE.STUDENT} />,
},
{
path: "assignments",
element: <ProtectedRoute element={<Assignment />} leastPrivilegeRole={ROLE.TA} />,
Expand Down Expand Up @@ -210,4 +211,4 @@ function App() {
return <RouterProvider router={router} />;
}

export default App;
export default App;
52 changes: 52 additions & 0 deletions src/pages/StudentTasks/StudentTasks.module.css
Expand Up @@ -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;
}

184 changes: 119 additions & 65 deletions 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 = {
Expand All @@ -17,80 +24,127 @@ type Task = {

type Props = {};

const StudentTasks: React.FC<Props> = () => {
const [tasks, setTasks] = useState<Task[]>([
{
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<Task[]>([]);
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 (
<div className={styles.container}>
<h1>Assignments</h1>
<table>
<div className="assignments-page">

<h1 className="assignments-title">Student Task List</h1>
<div className={styles.pageLayout}>


<aside className={styles.sidebar}>
<StudentTasksBox duties={exampleDuties}
revisions={taskRevisions}
studentsTeamedWith={studentsTeamedWith}
/>
</aside>
<div className={styles.mainContent}>

{isLoading ? (
<p>Loading tasks...</p>
) : (
<table className={styles.tasksTable}>
<thead>
<tr>
<th>Assignment</th>
<th>Course</th>
<th>Topic</th>
<th>Current Stage</th>
<th>Review Grade</th>
<th>Badges</th>
<th>Stage Deadline</th>
<th>Publishing Rights</th>
</tr>
</thead>
<tbody>
{tasks.map((task) => (
<tr key={task.id}>
<td><Link to={`/student_task_detail/${task.assignment}`}>{task.assignment}</Link></td>
<td>{task.course}</td>
<td>{task.topic}</td>
<td>{task.currentStage}</td>
<td>{task.reviewGrade}</td>
<td>{task.badges}</td>
<td>{task.stageDeadline}</td>
<td>
<input
type="checkbox"
checked={task.publishingRights}
onChange={() => togglePublishingRights(task.id)}
/>
</td>
<tr>
<th>Assignment</th>
<th>Course</th>
<th>Topic</th>
<th>Current Stage</th>
<th>Review Grade</th>
<th>Badges</th>
<th>Stage Deadline</th>
<th>Publishing Rights</th>
</tr>
))}
</tbody>
</table>
</thead>
<tbody>
{tasks.map((task) => (
<tr key={task.id}>
<td><Link to={`/student_task_detail/${task.id}`}>{task.assignment}</Link></td>
<td>{task.course}</td>
<td>{task.topic}</td>
<td>{task.currentStage}</td>
<td>{task.reviewGrade}</td>
<td>{task.badges}</td>
<td>{task.stageDeadline}</td>
<td>
<input
type="checkbox"
checked={task.publishingRights}
onChange={() => togglePublishingRights(task.id)}
/>
</td>
</tr>
))}
</tbody>
</table>
)}
</div>
</div>
</div>
);
};

export default StudentTasks;
export default StudentTasks;
103 changes: 103 additions & 0 deletions 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;
}

0 comments on commit 15c58c6

Please sign in to comment.