Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

E2463 Implement Front End for Student Task List #66

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
226 changes: 127 additions & 99 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ import ViewSubmissions from "pages/Assignments/ViewSubmissions";
import ViewScores from "pages/Assignments/ViewScores";
import ViewReports from "pages/Assignments/ViewReports";
import ViewDelayedJobs from "pages/Assignments/ViewDelayedJobs";

import StudentTaskHome from "./pages/StudentTasks/StudentTaskHome";

function App() {
const router = createBrowserRouter([
{
Expand All @@ -50,6 +53,10 @@ function App() {
{ index: true, element: <ProtectedRoute element={<Home />} /> },
{ path: "login", element: <Login /> },
{ path: "logout", element: <ProtectedRoute element={<Logout />} /> },
{
path: "taskhome",
element: <ProtectedRoute element={<StudentTaskHome />} />,
},
// Add the ViewTeamGrades route
{
path: "view-team-grades",
Expand Down Expand Up @@ -192,11 +199,11 @@ function App() {
},
{
path: "reviews",
element: <Reviews/>,
element: <Reviews />,
},
{
path: "email_the_author",
element: <Email_the_author/>,
element: <Email_the_author />,
},
// Fixed the missing comma and added an opening curly brace
{
Expand Down
Binary file added src/assets/icons/info.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ const Header: React.FC = () => {
</NavDropdown.Item>
</NavDropdown>
)}
<Nav.Link as={Link} to="/student_tasks">
Assignments
<Nav.Link as={Link} to="/taskhome">
Assignments (StudentTaskHome)
</Nav.Link>
<Nav.Link as={Link} to="/profile">
Profile
Expand Down
30 changes: 22 additions & 8 deletions src/pages/Assignments/Assignment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Table from "components/Table/Table";
import { alertActions } from "store/slices/alertSlice";
import useAPI from "hooks/useAPI";

import dummyData from "./dummyData/data.json";

const Assignments = () => {
const { error, isLoading, data: assignmentResponse, sendRequest: fetchAssignments } = useAPI();
Expand All @@ -32,18 +33,31 @@ const Assignments = () => {
}>({ visible: false });


const fetchData = useCallback(async () => {
// const fetchData = useCallback(async () => {
// try {
// const [assignments, courses] = await Promise.all([
// fetchAssignments({ url: `/assignments` }),
// fetchCourses({ url: '/courses' }),
// ]);
// // Handle the responses as needed
// } catch (err) {
// // Handle any errors that occur during the fetch
// console.error("Error fetching data:", err);
// }
// }, [fetchAssignments, fetchCourses]);

// Fetch data from the dummy JSON file
const fetchData = useCallback(() => {
try {
const [assignments, courses] = await Promise.all([
fetchAssignments({ url: `/assignments` }),
fetchCourses({ url: '/courses' }),
]);
// Handle the responses as needed
// Extract assignments and courses directly from imported dummyData
const assignments = dummyData.assignments;
const courses = dummyData.courses;

// Process data if needed
} catch (err) {
// Handle any errors that occur during the fetch
console.error("Error fetching data:", err);
}
}, [fetchAssignments, fetchCourses]);
}, []);

useEffect(() => {
if (!showDeleteConfirmation.visible) {
Expand Down
11 changes: 11 additions & 0 deletions src/pages/Assignments/dummyData/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"assignments": [
{ "id": 1, "name": "Assignment 1", "course_id": 1 },
{ "id": 2, "name": "Assignment 2", "course_id": 2 }
],
"courses": [
{ "id": 1, "name": "Course 1" },
{ "id": 2, "name": "Course 2" }
]
}

207 changes: 207 additions & 0 deletions src/pages/StudentTasks/StudentTaskHome.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import React, { useState, useEffect, useCallback } from 'react';
import testData from './testData.json';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate, Link } from 'react-router-dom';
import { RootState } from 'store/store';
import StudentTasksBox from './StudentTasksBox';

import styles from './StudentTasks.module.css';

type Task = {
id: number;
assignment: string;
course: string;
topic: string;
currentStage: string;
reviewGrade: string | { comment: string };
badges: string | boolean;
stageDeadline: string;
publishingRights: boolean;
};

const StudentTasksHome: React.FC = () => {
// init state and hooks
const currUserId = testData.current_user_id;
const dispatch = useDispatch();
const navigate = useNavigate();
const auth = useSelector((state: RootState) => state.authentication)

type StudentsTeamedWith = {
[semester: string]: string[];
};

// states to hold tasks
const taskRevisions = testData.revisions;
const participantTasks = testData.participantTasks;
console.log("participantTasks", participantTasks)

const [tasks, setTasks] = useState<Task[]>([]);
const dueTasks = testData.dueTasks;
const studentsTeamedWith: StudentsTeamedWith = testData.studentsTeamedWith;
const [filteredTasks, setFilteredTasks] = useState<Task[]>([]);

const [assignmentFilter, setAssignmentFilter] = useState('');
const [courseFilter, setCourseFilter] = useState('');
const [topicFilter, setTopicFilter] = useState('');
const [currentstageFilter, setCurrentStageFilter] = useState('');

function togglePublishingRights(id: number): void {
throw new Error('Function not implemented.');
}

let totalStudents = 0;
let allStudents: string[] = [];
for (const semester in studentsTeamedWith) {
// Add the number of students in each semester to the total count
totalStudents += studentsTeamedWith[semester].length;
allStudents = allStudents.concat(studentsTeamedWith[semester]);
}

useEffect(() => {
// Map the data from participationTasks to the tasks state
const mappedTasks = participantTasks.map(task => ({
id: task.id,
assignment: task.assignment,
course: task.course,
topic: task.topic,
currentStage: task.current_stage, // Adjust to match your data's structure
reviewGrade: task.review_grade, // Can be a string or an object
badges: task.badges, // Keep as is since it can be string or boolean
stageDeadline: task.stage_deadline, // Adjust to match your data's structure
publishingRights: task.publishing_rights, // Boolean type
}));

setTasks(mappedTasks);
setFilteredTasks(mappedTasks);
}, [participantTasks]);

console.log("after use effect:", participantTasks)

useEffect(() => {
const filtered = tasks.filter((task) =>
(assignmentFilter ? task.assignment === assignmentFilter : true) &&
(courseFilter ? task.course === courseFilter : true) &&
(topicFilter ? task.topic === topicFilter : true) &&
(currentstageFilter ? task.topic == currentstageFilter : true)
);
setFilteredTasks(filtered);
}, [assignmentFilter, courseFilter, topicFilter, currentstageFilter, tasks]);

return (
<div className="assignments-page">
{/* <h1 className="assignments-title">Assignments</h1> */}
<div className={styles.pageLayout}>
<div className={styles.leftSidebar}>
<h1 className="assignments-title">Assignments</h1>
<StudentTasksBox
participantTasks={tasks}
revisions={taskRevisions}
studentsTeamedWith={studentsTeamedWith}
/>
</div>
<div className={styles.mainContent}>
<table className={styles.tasksTable}>
<thead>
<tr>
<th>
Assignment
<select onChange={(e) => setAssignmentFilter(e.target.value)}>
<option value="">All</option>
{Array.from(new Set(tasks.map(task => task.assignment))).map(assignment => (
<option key={assignment} value={assignment}>{assignment}</option>
))}
</select>
</th>
<th>
Course
<select onChange={(e) => setCourseFilter(e.target.value)}>
<option value="">All</option>
{Array.from(new Set(tasks.map(task => task.course))).map(course => (
<option key={course} value={course}>{course}</option>
))}
</select>
</th>
<th>
Topic
<select onChange={(e) => setTopicFilter(e.target.value)}>
<option value="">All</option>
{Array.from(new Set(tasks.map(task => task.topic))).map(topic => (
<option key={topic} value={topic}>{topic}</option>
))}
</select>
</th>
<th>
Current Stage
<select onChange={(e) => setCurrentStageFilter(e.target.value)}>
<option value="">All</option>
{Array.from(new Set(tasks.map(task => task.currentStage))).map(currentStage => (
<option key={currentStage} value={currentStage}>{currentStage}</option>
))}
</select>
</th>
<th>Review Grade</th>
<th>Badges</th>
<th>
Stage Deadline
</th>
<th>
Publishing Rights
</th>
</tr>
</thead>
<tbody>
{filteredTasks.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 === "N/A" ? "NA" :
(task.reviewGrade as any).comment || ''
}
</td>
{<td>{task.badges}</td>}
<td>{task.stageDeadline}</td>
<td className={styles.centerCheckbox}>
<input
type="checkbox"
checked={task.publishingRights}
onChange={() => togglePublishingRights(task.id)}
/>
</td>
</tr>
))}
</tbody>
</table>

</div>
<div className={styles.rightSidebar}>
<br></br><br></br>
<h3> Legend </h3>
<b>Stage Deadline:</b> You can change 'Preferred Time Zone' in 'Profile' in the banner.
<br></br><br></br>
<b>Publishing Rights:</b> Grant publishing rights to make my work available to others over the Web"
Review Grade
</div>
</div>

{/* <div className={styles.teamedStudents}>
<p>Total Students Teamed With: {totalStudents}</p>
<ul>
{allStudents.map((student, index) => (
<li key={index}>{student}</li>
))}
</ul>
</div> */}

{/* Footer section */}
<div className={styles.footer}>
<Link to="https://wiki.expertiza.ncsu.edu/index.php/Expertiza_documentation" className={styles.footerLink}>Help</Link>
<Link to="https://research.csc.ncsu.edu/efg/expertiza/papers" className={styles.footerLink}>Papers on Expertiza</Link>
</div>
</div>
);
};

export default StudentTasksHome;
Loading