+
{courseInfo ? (
-
-
-
{courseInfo.name}
-
-
-
-
-
- {role.isInstructor() &&
-
- ) : (
-
Error fetching Course Information
- )}
-
- )
-}
-
-export default CourseDetailPage
\ No newline at end of file
+
+
+
+
+ ) : (
+
Error fetching Course Information
+ )}
+
+
+ )
+ }
+
+
+ export default CourseDetailPage
\ No newline at end of file
diff --git a/devU-client/src/components/pages/gradebook/gradebookPage.scss b/devU-client/src/components/pages/gradebook/gradebookPage.scss
index a252e74..9af830c 100644
--- a/devU-client/src/components/pages/gradebook/gradebookPage.scss
+++ b/devU-client/src/components/pages/gradebook/gradebookPage.scss
@@ -1,10 +1,7 @@
@import 'variables';
-.header {
- color: $text-color;
- display: flex;
- align-items: center;
-}
+
+
.categoryName {
color: $text-color;
@@ -12,7 +9,7 @@
}
.assignmentName {
- color: $text-color
+ color: $blue-darker
}
.smallLine {
@@ -26,4 +23,85 @@
border-top: 3px solid $text-color; /* adjust this value to set the color and thickness of the line */
margin-left: 10px; /* adjust this value to set the space between the line and the text */
margin-right: 10px; /* add this line to create some space between the line and the button */
-}
\ No newline at end of file
+}
+
+
+.header {
+ color: $text-color;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 20px;
+}
+
+.gradebook-container {
+ /* Add a container for the gradebook tables */
+ display: flex;
+ flex: 1 0 300px;
+ gap: 20px; /* Space between the tables */
+ overflow: hidden;
+}
+.gradebook-container .table {
+ border-radius: 20px !important;
+ transform: translateZ(0);
+}
+.table {
+ color: $blue-darker;
+ width: 100%;
+ overflow: hidden;
+ border-collapse: collapse;
+ border-radius: 20px;
+ background-color: $secondary-lighter;
+ table-layout: fixed; /* Key for even distribution */
+
+
+ th, td {
+
+ border: none;
+ border-radius: 0;
+ padding: 15px;
+ text-align: left;
+ width: 50%; /* Distribute columns evenly */
+ overflow: hidden; /* Prevent content from overflowing */
+ text-overflow: ellipsis; /* Add ellipsis for long names */
+ }
+
+
+ th {
+ background-color: #f2f2f2;
+ font-weight: bold;
+ }
+
+ .evenRow {
+ background-color: if(type-of($secondary-lighter) == 'color', lighten($secondary-lighter, 5%), #e0e0e0); // Fallback to #e0e0e0
+ }
+
+ .oddRow {
+ background-color: if(type-of($secondary-lighter) == 'color', darken($secondary-lighter, 5%), #d0d0d0); // Fallback to #d0d0d0
+ }
+
+}
+.headerRow th { /* Style for the purple header row */
+ background-color: $primary; /* Purple background */
+ color: white;
+}
+.content{
+ padding: 15px;
+ text-align: left;
+}
+
+.actual_button {
+ color: white;
+ display: flex;
+ align-items: flex-end;
+ border: 0; /* Primary button color */
+ /* Button text color */
+ padding: 10px 20px; /* Padding for button */
+ border-radius: 5px;
+ font-weight: 600;
+ transition: background-color 0.3s ease;
+ margin : 0 10px;
+ background-color: $purple !important;
+
+}
+
diff --git a/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx b/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx
index 2a9d9f8..9414f0c 100644
--- a/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx
+++ b/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx
@@ -1,127 +1,100 @@
-import React, {useEffect, useState} from 'react'
-import {Link, useHistory, useParams} from 'react-router-dom'
-import {useAppSelector} from 'redux/hooks'
+import React, { useEffect, useState } from 'react';
+import { useHistory, useParams } from 'react-router-dom';
+import { useAppSelector } from 'redux/hooks';
-import {Assignment, AssignmentScore} from 'devu-shared-modules'
+import { Assignment, AssignmentScore } from 'devu-shared-modules';
-import PageWrapper from 'components/shared/layouts/pageWrapper'
-import LoadingOverlay from 'components/shared/loaders/loadingOverlay'
-import ErrorPage from '../errorPage/errorPage'
+import PageWrapper from 'components/shared/layouts/pageWrapper';
+import LoadingOverlay from 'components/shared/loaders/loadingOverlay';
+import ErrorPage from '../errorPage/errorPage';
-import RequestService from 'services/request.service'
-import Button from '@mui/material/Button'
+import RequestService from 'services/request.service';
+//import Button from '@mui/material/Button';
-import styles from './gradebookPage.scss'
+import styles from './gradebookPage.scss';
-type CategoryProps = {
- categoryName: string
- assignments: Assignment[]
- assignmentScores: AssignmentScore[]
-}
-type AssignmentProps = {
- assignment: Assignment
- assignmentScore?: AssignmentScore
-}
-
-
-const CategoryAssignment = ({assignment, assignmentScore}: AssignmentProps) => {
- const { courseId } = useParams<{courseId: string}>()
+const GradebookStudentPage = () => {
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+ const [assignments, setAssignments] = useState
([]);
+ const [assignmentScores, setAssignmentScores] = useState([]);
+ const role = useAppSelector((store) => store.roleMode);
+ const { courseId } = useParams<{ courseId: string }>();
+ const userId = useAppSelector((store) => store.user.id);
+ const history = useHistory();
- return (
-
- {assignment.name} -
- Score: {assignmentScore?.score ?? 'N/A'}
-
- )
-}
-
-const GradebookCategory = ({categoryName, assignments, assignmentScores}: CategoryProps) => {
- return (
-
-
- {categoryName}
-
-
- {assignments.filter((a) => a.categoryName === categoryName)
- .map((a) => (
- aScore.assignmentId === a.id)}
- />
- ))}
-
-
- )
-
-}
-
-const GradebookStudentPage = () => {
-
- const [loading, setLoading] = useState(true)
- const [error, setError] = useState(null)
- const [categories, setCategories] = useState(new Array())
- const [assignments, setAssignments] = useState(new Array())
- const [assignmentScores, setAssignmentScores] = useState(new Array())
- const role = useAppSelector((store) => store.roleMode)
- const { courseId } = useParams<{courseId: string}>()
- const userId = useAppSelector((store) => store.user.id)
- const history = useHistory()
-
useEffect(() => {
- fetchData()
- }, [])
-
+ fetchData();
+ }, []);
+
const fetchData = async () => {
try {
- const assignments = await RequestService.get(`/api/course/${courseId}/assignments/released`)
- setAssignments(assignments)
+ const assignments = await RequestService.get(`/api/course/${courseId}/assignments/released`);
+ setAssignments(assignments);
- const assignmentScores = await RequestService.get(`/api/course/${courseId}/assignment-scores/user/${userId}`)
- setAssignmentScores(assignmentScores)
-
- //As I'm unsure as to how category creation will be handled, this is done for now instead of an api call to /categories/course/{courseId}
- const categories = [... new Set(assignments.map(a => a.categoryName))] //Get all unique categories from assignments
- setCategories(categories)
+ const assignmentScores = await RequestService.get(`/api/course/${courseId}/assignment-scores/user/${userId}`);
+ setAssignmentScores(assignmentScores);
} catch (error: any) {
- setError(error)
+ setError(error);
} finally {
- setLoading(false)
+ setLoading(false);
}
- }
+ };
+
+ if (loading) return ;
+ if (error) return ;
- if (loading) return
- if (error) return
+ const categories = [...new Set(assignments.map(a => a.categoryName))];
return (
-
Student Gradebook
-
-
- {role.isInstructor() &&
- {
- history.push(`/course/${courseId}/gradebook/instructor`)
- }
- }>Instructor View}
-
+ {role.isInstructor() &&(
+
{
+ history.push(`/course/${courseId}/gradebook/instructor`)
+ }}>Instructor View
+
+ )}
+
-
- {categories.map((c) => (
-
- ))}
+
+
+ {categories.map(category => (
+
+
{category}
+
{/* Add table class */}
+
+ {/* Add class for purple header */}
+ Assignment |
+ Score |
+
+
+
+ {assignments.filter(a => a.categoryName === category).map((assignment, index) => (
+
+
+
+ {assignment.name}
+
+ |
+
+
+
+ {assignmentScores.find(aScore => aScore.assignmentId === assignment.id)?.score ?? 'N/A'}
+
+ |
+
+ ))}
+
+
+
+ ))}
- )
-}
+ );
+};
-export default GradebookStudentPage
+export default GradebookStudentPage;
\ No newline at end of file