From fadb986f6d63d2fc26933da33ced92808cbc244f Mon Sep 17 00:00:00 2001 From: SameepK Date: Sun, 23 Feb 2025 08:55:40 -0500 Subject: [PATCH 1/3] updated the student gradebook to match the figma layout --- .../pages/courses/courseDetailPage.scss | 132 ++++++++++--- .../pages/courses/courseDetailPage.tsx | 11 +- .../pages/gradebook/gradebookPage.scss | 180 +++++++++++++++--- .../pages/gradebook/gradebookStudentPage.tsx | 141 ++++++++++---- 4 files changed, 373 insertions(+), 91 deletions(-) diff --git a/devU-client/src/components/pages/courses/courseDetailPage.scss b/devU-client/src/components/pages/courses/courseDetailPage.scss index 86e70196..8f392bc7 100644 --- a/devU-client/src/components/pages/courses/courseDetailPage.scss +++ b/devU-client/src/components/pages/courses/courseDetailPage.scss @@ -70,15 +70,17 @@ .courseDetailPage { padding: 40px; + position: relative; // Ensures absolute positioning works within this container .header { display: flex; - flex-direction: column; - align-items: flex-start; - background-color: $secondary; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; padding: 20px; color: $text-color; - width: 70%; + width: 100%; + position: relative; } h1 { @@ -88,13 +90,6 @@ font-weight: bold; } - h2 { - padding-top: 20px; - margin: 0 0 20px 0; - font-size: 1.0rem; - padding-bottom: 10px; - } - h3 { font-size: 1.5rem; border-bottom: 1px solid; @@ -105,9 +100,11 @@ /* Updated Button Layout */ .buttonContainer { display: flex; - justify-content: flex-end; // Align buttons slightly to the right - gap: 15px; // Space between buttons - margin-top: 10px; + justify-content: flex-start; // Align buttons to left under Course Links + flex-wrap: wrap; + gap: 15px; + margin-top: 20px; + } /* Button Styling to Match the New UI */ @@ -128,9 +125,39 @@ } } -/* Remove old button styles */ -.actual_button { - display: none; +.edit_actual_button { + display: flex; + flex-direction: row; + 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; + color: white !important; + min-width: 160px; + position: relative; + bottom: 66px; + right: 100px; +} +.assignment_actual_button { + display: flex; + flex-direction: row; + 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; + color: white !important; + min-width: 160px; + position: relative; + bottom: -57px; + left: 89px; } /* Assignments Formatting */ @@ -146,27 +173,74 @@ /* Instructor Buttons */ .instructorActions { display: flex; - justify-content: flex-end; - gap: 10px; + justify-content: flex-start; + gap: 15px; margin-top: 20px; } -.editCourse, -.addAssignment { +/* Course Links - Move to the Right */ +.courseLinks { + display: flex; + justify-content: flex-end; + gap: 15px; + margin-top: 10px; +} + +/* Style for each link button */ +.linkButton { + background: white; + color: #4b0082; + border: 2px solid #4b0082; + padding: 8px 16px; + border-radius: 20px; + font-size: 16px; + font-weight: bold; + cursor: pointer; + transition: all 0.3s ease; + + &:hover { + background: #4b0082; + color: white; + } +} + +/* Move "Edit Course" to the top-right just below account info */ +.editCourse { + position: absolute; + top: -60px; // Moves it higher to match the layout + right: 0; background-color: $primary; color: white; border: none; - padding: 8px 15px; - border-radius: 5px; + padding: 8px 16px; + border-radius: 20px; cursor: pointer; - font-size: 14px; -} + font-size: 16px; + font-weight: bold; + transition: all 0.3s ease; -.editCourse:hover, -.addAssignment:hover { - background-color: $purple-darker; + &:hover { + background-color: $purple-darker; + } } +/* Move "Add Assignment" to the bottom right */ +.addAssignment { + position: absolute; + bottom: -60px; // Pushes it downward + right: 0; + background-color: $primary; + color: white; + border: none; + padding: 8px 16px; + border-radius: 20px; + cursor: pointer; + font-size: 16px; + font-weight: bold; + transition: all 0.3s ease; - + &:hover { + background-color: $purple-darker; + } +} diff --git a/devU-client/src/components/pages/courses/courseDetailPage.tsx b/devU-client/src/components/pages/courses/courseDetailPage.tsx index 3dffb474..f9ddf565 100644 --- a/devU-client/src/components/pages/courses/courseDetailPage.tsx +++ b/devU-client/src/components/pages/courses/courseDetailPage.tsx @@ -43,8 +43,13 @@ const CourseDetailPage = () => { useEffect(() => { fetchCourseInfo(); + console.log("User Role:", role); + console.log("Is Instructor?", role.isInstructor ? role.isInstructor() : "role.isInstructor() is undefined"); }, []); + + + return (
@@ -69,16 +74,16 @@ const CourseDetailPage = () => { {role.isInstructor() &&( - )} {role.isInstructor() &&( - )}
diff --git a/devU-client/src/components/pages/gradebook/gradebookPage.scss b/devU-client/src/components/pages/gradebook/gradebookPage.scss index 7297b2d5..d4bd9e4a 100644 --- a/devU-client/src/components/pages/gradebook/gradebookPage.scss +++ b/devU-client/src/components/pages/gradebook/gradebookPage.scss @@ -1,11 +1,12 @@ @import 'variables'; - +// Category Styling .categoryName { color: $text-color; font-size: 1.25rem; } +// Table Wrapper for layout consistency .tableWrapper { padding: 0 100px; } @@ -16,12 +17,11 @@ } table { - border-radius: 20px; - // margin: 15px auto; - border-collapse: collapse; width: 100%; + border-collapse: collapse; } +// Alternating Row Colors tr.evenRow { background-color: $table-row-even; } @@ -30,18 +30,19 @@ tr.oddRow { background-color: $table-row-odd; } +// Table Header & Cell Styling th { - background-color: $primary; - color: #FFF; - font-weight: 600; + background-color: #5a3d8a; + color: white; } -td, -th { +th, td { padding: 10px; - text-align: center; + border-bottom: 1px solid #ccc; + text-align: left; } +// Table Borders & Rounded Corners th:first-of-type { border-top-left-radius: 10px; } @@ -58,12 +59,20 @@ tr:last-of-type td:last-of-type { border-bottom-right-radius: 10px; } +// Table Options Section .tableOptions { display: flex; justify-content: space-between; align-items: center; } +.topSection { + display: flex; + justify-content: space-between; + align-items: center; +} + +// Text Colors for Status Indicators .tableOptions span:first-child, span.yellow { color: $yellowText; @@ -74,37 +83,153 @@ span.red { color: $redText; } -// STUDENT GRADEBOOK STYLING - -// .header { -// color: $text-color; -// display: flex; -// align-items: center; -// justify-content: center; -// // margin-bottom: 20px; -// } - +// Student Gradebook Styling .assignmentName { text-align: left; } -.gradebook-container { +.gradebookContainer { display: flex; + flex-direction: column; gap: 20px; - flex-wrap: wrap; } -.category { - width: calc(100%/3 - 14px); +// Section Styling +.section { + background-color: white; + padding: -3px; + border-radius: 10px; + border: 2px solid #5a3d8a; +} + +.categoryRow { + font-weight: bold; } +.categoryValue { + text-align: right; + padding-right: 10px; // 🟒 Fix: Align value to the left +} + +.categoryText { + text-align: left; + padding-left: 10px; // 🟒 Fix: Align "Category Average" text to the right +} + +// Assignment Link Styling +.assignmentLink { + color: blue; + text-decoration: underline; +} + +// Category Average Styling (Adjusted for spacing) +.categoryAverage { + font-size: 14px; + text-align: right; + padding: 10px; + font-weight: bold; + margin-top: 10px; // 🟒 FIX: Added spacing so it doesn’t overlap +} + +// Page Wrapper & Title +.pageWrapper { + padding: 20px; +} + +.gradebookTitle { + text-align: center; + font-size: 2rem; + font-weight: bold; +} + +// 🟒 FIX: "Back to Course" Button Alignment +.backToCourseButton { + background-color: #5a3d8a; + color: white; + padding: 8px 15px; + border-radius: 30px; + border: none; + cursor: pointer; + position: absolute; + top: 137px; + right: 30px; +} + +// Section Headers (Purple Background) +.sectionHeader { + background-color: #5a3d8a; + color: white; + padding: 12px 20px; + border-radius: 8px 8px 0 0; + font-weight: bold; + display: flex; + justify-content: space-between; // 🟒 FIX: Ensures Late Days & Score are in the same row + align-items: center; +} + +.headerRight { + display: flex; + gap: 20px; // 🟒 FIX: Adds spacing between Late Days and Score +} + +// Gradebook Layout (Using Grid) +.gradebookGrid { + display: grid; + grid-template-columns: 1fr 1fr; + grid-gap: 20px; + width: 100%; // 🟒 FIX: Ensures the grid container spans full width +} + +// 🟒 FIX: Project Section Width Adjusted +.sectionLeft { + grid-column: 1; +} + +.sectionRight { + grid-column: 2; +} + +.sectionFull { + grid-column: 1 / span 1; // 🟒 FIX: Project is same width as Homeworks +} + +// Empty Assignments Text +.noAssignments { + text-align: center; + padding: 10px; + font-style: italic; +} + +// Course Average Box Styling +.courseAverage { + border: 2px solid #5a3d8a; + padding: 14px; + display: flex; + justify-content: space-between; // 🟒 FIX: Pushes the value to the rightmost side + font-weight: bold; + width: 99.01%; + grid-column: span 2; + margin-top: 20px; + border-radius: 13px; +} + +// 🟒 FIX: Mobile Responsive Adjustments @media (max-width: 650px) { .pageWrapper { padding: 0 20px; } .category { - width: calc(100%/2 - 14px); + width: calc(100% / 2 - 14px); + } + + .gradebookGrid { + display: flex; + flex-direction: column; + } + + .section { + width: 100%; } } @@ -112,4 +237,9 @@ span.red { .category { width: 100%; } + + .backToCourseButton { + position: relative; // 🟒 FIX: Prevents it from overlapping content on small screens + margin-top: 10px; + } } \ No newline at end of file diff --git a/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx b/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx index c7c4c2e6..c88d8cad 100644 --- a/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx +++ b/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx @@ -22,7 +22,6 @@ const GradebookStudentPage = () => { const userId = useAppSelector((store) => store.user.id); const history = useHistory(); - useEffect(() => { fetchData(); }, []); @@ -34,7 +33,6 @@ const GradebookStudentPage = () => { const assignmentScores = await RequestService.get(`/api/course/${courseId}/assignment-scores/user/${userId}`); setAssignmentScores(assignmentScores); - } catch (error: any) { setError(error); } finally { @@ -45,53 +43,128 @@ const GradebookStudentPage = () => { if (loading) return ; if (error) return ; - const categories = [...new Set(assignments.map(a => a.categoryName))]; + // Categorize assignments + const homeworks = assignments.filter(a => a.categoryName === "Homework"); + const lectureQuestions = assignments.filter(a => a.categoryName === "Lecture Questions"); + const projects = assignments.filter(a => a.categoryName === "Project"); + + const calculateAverage = () => { + if (assignmentScores.length === 0) return 0.0; + const total = assignmentScores.reduce((sum, a) => sum + (a.score || 0), 0); + return (total / assignmentScores.length).toFixed(1); + }; + + const calculateHomeworkAverage = () => { + if (homeworks.length === 0) return "N/A"; + const totalScore = homeworks.reduce((sum, assignment) => sum + (assignmentScores.find(a => a.assignmentId === assignment.id)?.score || 0), 0); + return (totalScore / homeworks.length).toFixed(1); + }; return ( -
-

Student Gradebook

+ {/* Top Section with Back to Course Button */} +
+

CSE 312 Gradebook

{role.isInstructor() && ( - )}
-
- {categories.map(category => ( -
-

{category}

- {/* Add table class */} -
- - {/* Add class for purple header */} - - - {/* */} - + +
+ {/* Homework - Left Column */} +
+
+ Homeworks + + Late Days + Score + +
+
AssignmentScore
+ + {homeworks.length > 0 ? ( + homeworks.map((assignment) => ( + + + + + + )) + ) : ( + + + + )} + + + + + +
{assignment.name}0{assignmentScores.find(a => a.assignmentId === assignment.id)?.score ?? 'N/A'}
No assignments yet
Category Average{calculateHomeworkAverage()}
+
+ + {/* Lecture Questions Section */} +
+
+ Lecture Questions + + Late Days + Score + +
+ {lectureQuestions.length > 0 ? ( + - {assignments.filter(a => a.categoryName === category).map((assignment, index) => ( - - - + {lectureQuestions.map((assignment) => ( + + + + ))}
-
- {assignment.name} -
-
- {/*
*/} - {assignmentScores.find(aScore => aScore.assignmentId === assignment.id)?.score ?? 'N/A'} - {/*
*/} -
{assignment.name}0{assignmentScores.find(a => a.assignmentId === assignment.id)?.score ?? 'N/A'}
+ ) : ( +
No assignments yet
+ )} +
+ + {/* Project Section */} +
+
+ Project + + Late Days + Score +
- ))} + {projects.length > 0 ? ( + + + {projects.map((assignment) => ( + + + + + + ))} + +
{assignment.name}0{assignmentScores.find(a => a.assignmentId === assignment.id)?.score ?? 'N/A'}
+ ) : ( +
No assignments yet
+ )} +
+ + {/* Course Average Section */} +
+ Course Average + {calculateAverage()} +
); }; -export default GradebookStudentPage; \ No newline at end of file +export default GradebookStudentPage; From d0133abec2bec858c8abd5406990157cc88c0ab4 Mon Sep 17 00:00:00 2001 From: SameepK Date: Mon, 24 Feb 2025 14:35:40 -0500 Subject: [PATCH 2/3] fixed the error for the Course-Title --- .../pages/gradebook/gradebookStudentPage.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx b/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx index c88d8cad..75f090c0 100644 --- a/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx +++ b/devU-client/src/components/pages/gradebook/gradebookStudentPage.tsx @@ -2,7 +2,7 @@ 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, Course } from 'devu-shared-modules'; import PageWrapper from 'components/shared/layouts/pageWrapper'; import LoadingOverlay from 'components/shared/loaders/loadingOverlay'; @@ -21,6 +21,7 @@ const GradebookStudentPage = () => { const { courseId } = useParams<{ courseId: string }>(); const userId = useAppSelector((store) => store.user.id); const history = useHistory(); + const [courseName, setCourseName] = useState(""); useEffect(() => { fetchData(); @@ -33,6 +34,10 @@ const GradebookStudentPage = () => { const assignmentScores = await RequestService.get(`/api/course/${courseId}/assignment-scores/user/${userId}`); setAssignmentScores(assignmentScores); + + const courseData = await RequestService.get(`/api/courses/${courseId}`); + setCourseName(courseData.name); + } catch (error: any) { setError(error); } finally { @@ -64,9 +69,9 @@ const GradebookStudentPage = () => { {/* Top Section with Back to Course Button */}
-

CSE 312 Gradebook

+

{courseName} Gradebook

{role.isInstructor() && ( - )} @@ -167,4 +172,4 @@ const GradebookStudentPage = () => { ); }; -export default GradebookStudentPage; +export default GradebookStudentPage; \ No newline at end of file From 8baa16bafe647485843f1aac10a15777fc64f73b Mon Sep 17 00:00:00 2001 From: Diego Cabiya Date: Fri, 7 Mar 2025 10:54:02 -0500 Subject: [PATCH 3/3] reverted coursepage styling --- .../pages/courses/courseDetailPage.scss | 174 +++++------------- .../pages/courses/courseDetailPage.tsx | 56 ++++-- 2 files changed, 81 insertions(+), 149 deletions(-) diff --git a/devU-client/src/components/pages/courses/courseDetailPage.scss b/devU-client/src/components/pages/courses/courseDetailPage.scss index 49d36daf..d00d73f0 100644 --- a/devU-client/src/components/pages/courses/courseDetailPage.scss +++ b/devU-client/src/components/pages/courses/courseDetailPage.scss @@ -62,45 +62,20 @@ color: $text-color; background:none; } -} - -.courseDetailPage { - padding: 40px; - position: relative; // Ensures absolute positioning works within this container - .header { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - padding: 20px; - color: $text-color; - width: 100%; - position: relative; - } - - h1 { - margin: 0 0 10px 0; - font-size: 1.5rem; - text-align: left; - font-weight: bold; - } - - h3 { - font-size: 1.5rem; - border-bottom: 1px solid; - color: $text-color; - } +.header { + color: $text-color; + display: grid; + grid-template-columns: 1fr 2fr 1fr; + justify-items: center; + align-items: center; } - -/* Updated Button Layout */ -.buttonContainer { - display: flex; - justify-content: flex-start; // Align buttons to left under Course Links - flex-wrap: wrap; - gap: 15px; - margin-top: 20px; - +.subheader{ + color: $text-color; + display: grid; + grid-template-columns: 1fr 1fr; + align-items: center; + margin-bottom: 20px; } h3 { @@ -108,39 +83,10 @@ h3 { margin: 10px 0 0 0; } -.edit_actual_button { - display: flex; - flex-direction: row; - 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; - color: white !important; - min-width: 160px; - position: relative; - bottom: 66px; - right: 100px; -} -.assignment_actual_button { - display: flex; - flex-direction: row; - 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; - color: white !important; - min-width: 160px; - position: relative; - bottom: -57px; - left: 89px; +h4 { + font-size: 1.0rem; + margin: 0; + display: inline; } .class_title{ grid-column-start: 2; @@ -149,75 +95,41 @@ h3 { .meta_container{ display: flex; - justify-content: flex-start; - gap: 15px; - margin-top: 20px; + flex-direction: column; + align-items: flex-start; } -/* Course Links - Move to the Right */ -.courseLinks { - display: flex; - justify-content: flex-end; - gap: 15px; +.buttons_container { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + gap: 10px; margin-top: 10px; } - -/* Style for each link button */ -.linkButton { - background: white; - color: #4b0082; - border: 2px solid #4b0082; - padding: 8px 16px; - border-radius: 20px; - font-size: 16px; - font-weight: bold; - cursor: pointer; - transition: all 0.3s ease; - - &:hover { - background: #4b0082; - color: white; - } +#parallel_button{ + margin-left: auto; } -/* Move "Edit Course" to the top-right just below account info */ -.editCourse { - position: absolute; - top: -60px; // Moves it higher to match the layout - right: 0; - background-color: $primary; - color: white; - border: none; - padding: 8px 16px; - border-radius: 20px; - cursor: pointer; - font-size: 16px; - font-weight: bold; - transition: all 0.3s ease; - - &:hover { - background-color: $purple-darker; - } +.assignmentName { + padding: 10px; + color: $text-color; + display: block; + width: 100%; + margin: 5px auto; + border-bottom: 1px solid #ddd; + } -/* Move "Add Assignment" to the bottom right */ -.addAssignment { - position: absolute; - bottom: -60px; // Pushes it downward - right: 0; - background-color: $primary; - color: white; - border: none; - padding: 8px 16px; - border-radius: 20px; - cursor: pointer; - font-size: 16px; - font-weight: bold; - transition: all 0.3s ease; - - &:hover { - background-color: $purple-darker; - } +.due_end{ + text-decoration: none; + display: flex; + flex-direction: row; + font-size:11px; + flex-wrap: wrap; + color: $text-color-secondary; + font-family: monospace; + font-weight: 500; + } @media (max-width: $medium) { diff --git a/devU-client/src/components/pages/courses/courseDetailPage.tsx b/devU-client/src/components/pages/courses/courseDetailPage.tsx index 30cc3fc9..8e4cdcc4 100644 --- a/devU-client/src/components/pages/courses/courseDetailPage.tsx +++ b/devU-client/src/components/pages/courses/courseDetailPage.tsx @@ -65,30 +65,50 @@ const CourseDetailPage = () => { useEffect(() => { - fetchCourseInfo(); - console.log("User Role:", role); - console.log("Is Instructor?", role.isInstructor ? role.isInstructor() : "role.isInstructor() is undefined"); - }, []); + fetchCourseInfo() - - - - return ( + }, []) + return( {courseInfo ? (
-1. - {role.isInstructor() &&( - - )} - - {role.isInstructor() &&( -
+
+
+
+

Instructor:

+
+
+

Section:

+
+
+

Semester:

{prettyPrintSemester(courseInfo.semester)} +
+
+
+

Course Links

+
+ +
+
+
+

Assignments

+ {role.isInstructor() &&( + )}