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

E2446 Implement Front End for Student Task List #52

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5a07b9f
created a new page StudentTasks under student role and added a basic …
prathyu99 Apr 17, 2024
e01eee6
Added link to navigate to new Student Task Detail page
prathyu99 Apr 19, 2024
111ba6a
added checkbox for publishing rights
prathyu99 Apr 19, 2024
2ad4e8d
added css for links
prathyu99 Apr 19, 2024
15c58c6
Adding Student Tasks Box
soubhi Apr 23, 2024
5c3de2c
Merge pull request #1 from prathyu99/apiAndLayout
soubhi Apr 23, 2024
544b071
Modifying code to fetch data from dummy data
soubhi Apr 23, 2024
8a628a4
Merge pull request #2 from prathyu99/apiAndLayout
soubhi Apr 23, 2024
80b463c
added icon i which displays text on hover
prathyu99 Apr 24, 2024
ab936ac
added css to adjust the layout
prathyu99 Apr 24, 2024
5e372f0
Modifying Revisions component and adding remaining days functionality
soubhi Apr 24, 2024
5c40ef2
Merge branch 'main' into apiAndLayout
soubhi Apr 24, 2024
ca8ac62
Merge pull request #3 from prathyu99/apiAndLayout
soubhi Apr 24, 2024
1257334
added comments to the code and resolved merge conflicts
prathyu99 Apr 24, 2024
25f8ad2
added comments to the code studenttasks
prathyu99 Apr 24, 2024
19f3409
Merge branch 'main' into main
soubhi Apr 24, 2024
7c1a434
added space in student task box, changed the hover text for publishin…
prathyu99 Apr 29, 2024
a779945
Merge remote-tracking branch 'origin/main'
prathyu99 Apr 29, 2024
e6cccb7
added space in student task box, changed the hover text for publishin…
prathyu99 Apr 29, 2024
8bf0c02
removed an unnecessary change
prathyu99 Apr 29, 2024
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
Binary file added public/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.
7 changes: 6 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import Questionnaire from "pages/EditQuestionnaire/Questionnaire";
import Courses from "pages/Courses/Course";
import CourseEditor from "pages/Courses/CourseEditor";
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 @@ -47,6 +48,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: "assignments/edit/:id/createteams",
element: <CreateTeams />,
Expand Down Expand Up @@ -274,4 +279,4 @@ function App() {
return <RouterProvider router={router} />;
}

export default App;
export default App;
15 changes: 15 additions & 0 deletions src/pages/StudentTasks/StudentTaskDetail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { useParams } from 'react-router-dom';

const StudentTaskDetail: React.FC = () => {
const { id } = useParams(); // To grab the ID from the URL

return (
<div>
<h2>Assignment Title: {id}</h2>
{/* Details about the assignment could be fetched and displayed here */}
</div>
);
};

export default StudentTaskDetail;
210 changes: 210 additions & 0 deletions src/pages/StudentTasks/StudentTasks.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/* Base container styling */
.container {
font-family: Arial, sans-serif;
margin: 20px;
}

/* Header 1 styling */
h1 {
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 base styling */
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}

/* Table, th, and td shared border styling */
table,
th,
td {
border: 1px solid #ddd;
}

/* Table header styling */
th {
background-color: #f8f8f8;
color: #333;
text-align: left;
padding: 8px;
}

/* Table data cell styling */
td {
padding: 8px;
text-align: left;
}

/* First child of th and td border styling */
th:first-child,
td:first-child {
border-left: none;
}

/* Last child of th and td border styling */
th:last-child,
td:last-child {
border-right: none;
}

/* Table row striping for even rows */
tr:nth-child(even) {
background-color: #f2f2f2;
}

/* Badge info icon and publishing rights checkbox styling */
.badge-info-icon,
.publishing-rights-checkbox {
cursor: pointer;
margin-left: 5px;
}

/* Checked state styling for publishing rights checkbox */
.publishing-rights-checkbox:checked {
accent-color: #009688;
}

/* Table header row font styling */
thead tr {
font-weight: bold;
}

/* Status indicator icons styling */
.status-indicator {
color: #009688;
margin-left: 5px;
}

/* Disabled state styling for checkboxes */
input[type="checkbox"][disabled] {
opacity: 0.6;
cursor: not-allowed;
}

/* Information icon styling in table */
.info-icon {
font-style: normal;
color: #017bff;
cursor: help;
}

/* Side information section styling */
.side-info {
color: #333;
padding: 10px 0;
}

/* Number styling in side information section */
.side-info .number {
font-weight: bold;
color: #d9534f; /* Red color for the number badge */
}

/* 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 data cell link styling */
table td a {
color: #986633;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
padding: 0px 1px 2px;
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;
}

/* Table data cell link hover and focus styling */
table td a:hover, table td a:focus {
color: #337ab7;
text-decoration: underline;
}

/* Page layout styling */
.pageLayout {
display: flex;
margin: 16px;
}

/* Sidebar styling */
.sidebar {
width: 250px;
margin-right: 20px;
padding-top: 20px;
}

/* Main content area styling */
.mainContent {
flex-grow: 1;
overflow: hidden;
}

/* Header below pageLayout styling */
.header {
margin-bottom: 20px;
}

/* Tasks table styling */
.tasksTable {
width: 100%;
}

/* Page assignments styling */
.assignments-page {
font-family: 'Arial', sans-serif;
}

/* Title in assignments page styling */
.assignments-title {
color: #333;
text-align: left;
padding: 20px;
font-size: 24px;
}

/* Footer section styling */
.footer {
display: flex;
justify-content: center;
padding: 20px 0;
}

/* Footer link styling */
.footerLink {
margin: 0 10px;
color: #986633;
text-decoration: none;
}

/* Footer link hover styling */
.footerLink:hover {
color: #000000;
text-decoration: underline;
}

/* Center checkbox in table data cell styling */
.centerCheckbox {
text-align: center;
vertical-align: middle;
}
142 changes: 142 additions & 0 deletions src/pages/StudentTasks/StudentTasks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
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 StudentTasksBox from './StudentTasksBox';
import testData from './testData.json';

// 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 | { comment: string };
badges: string | boolean;
stageDeadline: string;
publishingRights: boolean;
};

// Empty props for FC as no props are needed currently
type Props = {};

// Main functional component for Student Tasks
const StudentTasks: React.FC = () => {
// State and hooks initialization
const participantTasks = testData.participantTasks;
const currentUserId = testData.current_user_id;
const auth = useSelector((state: RootState) => state.authentication);
const dispatch = useDispatch();
const navigate = useNavigate();

// State to hold tasks
const [tasks, setTasks] = useState<Task[]>([]);
const exampleDuties = testData.dueTasks;
const taskRevisions = testData.revisions;
const studentsTeamedWith = testData.studentsTeamedWith;

// Effect to process tasks on component mount or update
useEffect(() => {
if (participantTasks) {
const filteredParticipantTasks = participantTasks.filter(task => task.participant_id === currentUserId);

const mergedTasks = filteredParticipantTasks.map(task => {
return {
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);
}
}, [participantTasks]);

// Callback to toggle publishing rights
const togglePublishingRights = useCallback((id: number) => {
setTasks(prevTasks => prevTasks.map(task =>
task.id === id ? {...task, publishingRights: !task.publishingRights} : task
));
}, []);

const showBadges = tasks.some(task => task.badges);

// Component render method
return (
<div className="assignments-page">
<h1 className="assignments-title">Assignments</h1>
<div className={styles.pageLayout}>
<aside className={styles.sidebar}>
<StudentTasksBox
dueTasks={exampleDuties}
revisions={taskRevisions}
studentsTeamedWith={studentsTeamedWith}
/>
</aside>
<div className={styles.mainContent}>
<table className={styles.tasksTable}>
<thead>
<tr>
<th>Assignment</th>
<th>Course</th>
<th>Topic</th>
<th>Current Stage</th>
<th>Review Grade</th>
{showBadges && <th>Badges</th>}
<th>
Stage Deadline
<img src="assets/icons/info.png" alt="Info" title="You can change 'Preferred Time Zone' in 'Profile' in the banner." />
</th>
<th>
Publishing Rights
<img src="assets/icons/info.png" alt="Info" title="Grant publishing rights to make my work available to others over the Web" />
</th>
</tr>
</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 === "N/A" ? "NA" :
<img src="assets/icons/info.png" alt="Review Grade" title={(task.reviewGrade as any).comment || ''} />
}
</td>
{showBadges && <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>

{/* 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 the component for use in other parts of the application
export default StudentTasks;
Loading