Skip to content

Commit

Permalink
Merge pull request #157 from makeopensource/task-86-update_for_studen…
Browse files Browse the repository at this point in the history
…t's_submissions_page

Task 86 update for student's submissions page
ashwaqaljanahi2021 authored Oct 28, 2024

Verified

This commit was signed with the committer’s verified signature.
drohit-cb Rohit Durvasula
2 parents c4fae27 + 3acedd2 commit a7d265d
Showing 6 changed files with 310 additions and 39 deletions.
9 changes: 7 additions & 2 deletions devU-client/src/components/misc/globalToolbar.scss
Original file line number Diff line number Diff line change
@@ -46,10 +46,15 @@ $font-size: 16px;
}

.bar {
height: 60px;

height: 80px;
background-color: $primary;
font-size: 40px;
color: #FFF;
color: #D9D9D9;
font-weight: 550;



@extend .flex;
justify-content: space-between;
}
5 changes: 4 additions & 1 deletion devU-client/src/components/misc/navbar.scss
Original file line number Diff line number Diff line change
@@ -3,14 +3,17 @@
.breadcrumbContainer {
display: flex;
align-items: center;
margin-left: 3.5rem;
margin-top:10px;

}

.link {
text-decoration: none;
color: $text-color; /* Breadcrumb link color */

}


.link:hover {
text-decoration: underline;
}
43 changes: 43 additions & 0 deletions devU-client/src/components/pages/homePage/homePage.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,37 @@
@import 'variables';



.courses_title {
text-align: left;
margin-left: 20px;
font-size: 30px;
font-weight: 550;
margin-bottom: 30px;
}

.courses_heading{
align-items:left;
margin-left: 20px;
font-size: 30px;
font-weight: 550;
margin-bottom: 30px;

}
// h1 {
// align-items:left;
// margin-left: 20px;
// font-size: 30px;
// font-weight: 550;
// margin-bottom: 30px;
// }

.no_courses {
margin-left: 20px;
}



.coursesContainer {
display: flex;
flex-direction: row;
@@ -36,6 +67,18 @@
align-items: center;
}


.courses_heading::after {
content: '';
display: block;
margin-top: 10px;
width: 100%;
height: 1px;
font-weight: 600;
background-color: $text-color;
}


@media (max-width: 768px) {
.coursesContainer {
flex-direction: column;
14 changes: 7 additions & 7 deletions devU-client/src/components/pages/homePage/homePage.tsx
Original file line number Diff line number Diff line change
@@ -75,7 +75,7 @@ const HomePage = () => {
<PageWrapper>
<div className={styles.header}>
<div className={styles.smallLine}></div>
<h2 className={styles.h2}>Courses</h2>
<h2 className={styles.courses_title}>Courses</h2>
<button className = {styles.create_course} onClick={() => {
history.push(`/addCoursesForm`)
}}>Create Course
@@ -84,7 +84,7 @@ const HomePage = () => {
</div>
<div className={styles.header}>
<div className={styles.smallLine}></div>
<h3>Current</h3>
<h3 className = {styles.courses_heading}>Current</h3>
<div className={styles.largeLine}></div>
</div>
<div className={styles.coursesContainer}>
@@ -101,12 +101,12 @@ const HomePage = () => {
<UserCourseListItem course={course} assignments={assignments.get(course)} key={course.id}/>
</div>
))}
{enrollCourses.length === 0 && <h4>You do not have current enrollment yet</h4>}
{enrollCourses.length === 0 && <h4 className={styles.no_courses}>You do not have current enrollment yet</h4>}
</div>

<div className={styles.header}>
<div className={styles.smallLine}></div>
<h3>Completed</h3>
<h3 className = {styles.courses_heading}>Completed</h3>
<div className={styles.largeLine}></div>
</div>

@@ -122,12 +122,12 @@ const HomePage = () => {
/>
</div>
))}
{pastCourses.length === 0 && <h4>No completed courses</h4>}
{pastCourses.length === 0 && <h4 className={styles.no_courses}>No completed courses</h4>}
</div>

<div className={styles.header}>
<div className={styles.smallLine}></div>
<h3>Upcoming</h3>
<h3 className = {styles.courses_heading}>Upcoming</h3>
<div className={styles.largeLine}></div>
</div>

@@ -137,7 +137,7 @@ const HomePage = () => {
<UserCourseListItem course={course} assignments={assignments.get(course)} key={course.id}/>
</div>
))}
{upcomingCourses.length === 0 && <h4>No upcoming Courses</h4>}
{upcomingCourses.length === 0 && <h4 className={styles.no_courses}>No upcoming Courses</h4>}
</div>


141 changes: 141 additions & 0 deletions devU-client/src/components/pages/submissions/submissionDetailPage.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
@import 'variables';

.heading {
text-align: center;
margin-left:250px;

}
.scores {
padding: 20px;
}

.submissionsLayout {
display: flex;
gap: 50px;
}

.submissionsContainer {
flex: 1;
max-width: 250px;
padding-right: 10px;
overflow-y: auto;
}

.submissionCard {
margin-bottom: 15px;
cursor: pointer;
}

.submissionContent {
flex: 2;
max-height: 800px;
overflow-y: auto;
padding: 0 20px;
background-color: $background;
border: 1px solid #ddd;
color: $text-color;
border-radius: 30px;
padding:30px;
}

pre {
color: $text-color;
white-space: pre-wrap;
word-wrap: break-word;
font-size: 12px;
}

.feedbackContainer{
background-color: $background;

}

.scoreDisplay {

color:$text-color;

}

.content_title{
display: inline-block;
padding: 5px 10px;
background-color: $secondary;
color: $text-color;
border-radius: 5px;
font-size: 1rem;
font-weight: bold;
text-align: left;
margin-bottom: 10px;
margin-top:30px;
}

.scrollableContent {
max-height: 350px;
overflow-y: auto;
border: 1px solid $background;
padding: 10px;
background-color: $background;
border-radius: 5px;
border: 2px solid $text-color;
padding:0px;
}
p{
text-align: left;
margin-left: 10px;
}

.scrollableContent::-webkit-scrollbar {
width: 12px; /* Width of the scrollbar */
}

.scrollableContent::-webkit-scrollbar-thumb {
background-color: $purple;
border-radius: 10px;
}

.scrollableContent::-webkit-scrollbar-track {
background-color: #f0f0f0;
}

.problemAnswerContainer {
margin-top: 10px;
max-height: 400px;
overflow-y: auto;
padding: 10px;
background-color: $background;
border-radius: 5px;
}

.assignmentTable {
width: 100%;
border-collapse: collapse;
}

.assignmentTable th, .assignmentTable td {

padding: 8px;
text-align: left;
}

.assignmentTable th {
background-color: $background;
font-weight: bold;
}

.assignmentTable tr:nth-child(even) {
background-color: $background;
}

.sub_list{
text-align: center;

}
@media (max-width: 768px) {
.submissionsContainer {
display:none;
}
.heading {
margin:10px;
}

}
137 changes: 108 additions & 29 deletions devU-client/src/components/pages/submissions/submissionDetailPage.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import React, {useEffect, useState} from 'react'

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 {Assignment, AssignmentProblem, Submission, SubmissionProblemScore, SubmissionScore} from 'devu-shared-modules'
import {Link, useParams} from 'react-router-dom'
import {Assignment, AssignmentProblem, Submission, SubmissionProblemScore,SubmissionScore} from 'devu-shared-modules'
import { useParams,/*useHistory*/} from 'react-router-dom'
import Button from '../../shared/inputs/button'
import TextField from '../../shared/inputs/textField'
import {useActionless} from 'redux/hooks'
import {SET_ALERT} from 'redux/types/active.types'
import styles from './submissionDetailPage.scss'
import 'react-datepicker/dist/react-datepicker.css'
import Card from '@mui/material/Card'
import CardContent from '@mui/material/CardContent'
import {CardActionArea, Typography} from '@mui/material'
import {prettyPrintDateTime} from "../../../utils/date.utils";


const SubmissionDetailPage = () => {
@@ -21,35 +26,46 @@ const SubmissionDetailPage = () => {
const { submissionId, assignmentId, courseId } = useParams<{submissionId: string, assignmentId: string, courseId: string}>()
const [submissionScore, setSubmissionScore] = useState<SubmissionScore | null>(null)
const [submissionProblemScores, setSubmissionProblemScores] = useState(new Array<SubmissionProblemScore>())
const [submission, setSubmission] = useState<Submission>()
const [selectedSubmission, setSelectedSubmission] = useState<Submission>()
//const [submission, setSubmission] = useState<Submission>()
const [assignmentProblems, setAssignmentProblems] = useState(new Array<AssignmentProblem>())
const [assignment, setAssignment] = useState<Assignment>()

const [submissions, setSubmissions] = useState(new Array<Submission>())
const [showManualGrade, setToggleManualGrade] = useState(false)
const [formData, setFormData] = useState({
submissionId: submissionId,
score: 0,
feedback: '',
releasedAt: "2024-10-05T14:48:00.00Z"
})


const fetchData = async () => {
try {
const submission = await RequestService.get<Submission>(`/api/course/${courseId}/assignment/${assignmentId}/submissions/${submissionId}`)
setSubmission(submission)

//const submission = await RequestService.get<Submission>(`/api/course/${courseId}/assignment/${assignmentId}/submissions/${submissionId}`)
//setSubmission(submission)

const submissionScore = (await RequestService.get<SubmissionScore[]>(`/api/course/${courseId}/assignment/${assignmentId}/submission-scores?submission=${submissionId}`)).pop() ?? null
setSubmissionScore(submissionScore)


const selectedSubmission = await RequestService.get<Submission>(`/api/course/${courseId}/assignment/${assignmentId}/submissions/${submissionId}`);
setSelectedSubmission(selectedSubmission);

const submissionProblemScores = await RequestService.get<SubmissionProblemScore[]>(`/api/course/${courseId}/assignment/${assignmentId}/submission-problem-scores/submission/${submissionId}`)
setSubmissionProblemScores(submissionProblemScores)
setSubmissionProblemScores(submissionProblemScores)

const assignment = await RequestService.get<Assignment>(`/api/course/${courseId}/assignments/${submission.assignmentId}`)
const assignment = await RequestService.get<Assignment>(`/api/course/${courseId}/assignments/${selectedSubmission.assignmentId}`)
setAssignment(assignment)

const assignmentProblems = await RequestService.get<AssignmentProblem[]>(`/api/course/${courseId}/assignment/${assignment.id}/assignment-problems`)
setAssignmentProblems(assignmentProblems)

const submissionsReq = await RequestService.get<Submission[]>(`/api/course/${courseId}/assignment/${assignmentId}/submissions/`)
submissionsReq.sort((a, b) => (Date.parse(b.createdAt ?? '') - Date.parse(a.createdAt ?? '')))
setSubmissions(submissionsReq)


} catch (error: any) {
setError(error)
} finally {
@@ -79,6 +95,7 @@ const SubmissionDetailPage = () => {
setAlert({ autoDelete: true, type: 'success', message: 'Submission Score Updated' })

})

}
else {
// Create a new submission score
@@ -90,9 +107,13 @@ const SubmissionDetailPage = () => {
}
}




if (loading) return <LoadingOverlay delay={250} />
if (error) return <ErrorPage error={error} />

//const history = useHistory()
//var submission_form = JSON.parse(submission?.content);
return(
<PageWrapper>
<Button onClick={handleClick}>Manually Grade</Button>
@@ -104,27 +125,85 @@ const SubmissionDetailPage = () => {
<Button onClick={handleManualGrade}>Submit</Button>
</div>
)}
<div className={styles.scores}>
<h1 className = {styles.heading}>Submissions For Assignment {assignment?.name}</h1>


<div className={styles.submissionsLayout}>

<div className={styles.submissionsContainer}>
<h2 className={styles.sub_list}>Submission List:</h2>
{submissions.map((submission, index) => (
<Card className={styles.submissionCard} key={index}>
<CardActionArea onClick={() =>
setSelectedSubmission(submission)}>
<CardContent>
<Typography className={styles.submissionHeading}>{`Submission ${submissions.length - index}`}</Typography>
<Typography className={styles.submissionTime}>{`Submitted at: ${submission.createdAt && prettyPrintDateTime(submission.createdAt)}`}</Typography>
</CardContent>
</CardActionArea>
</Card>
))}
</div>
<div className={styles.submissionContent}>


{selectedSubmission ? (
<>

<div className={styles.scoreDisplay}>
<h2 className = {styles.content_title}>{submissionScore ? `Score: ${submissionScore.score}` : "Score: N/A"}</h2>
</div>

<h1>Submission Detail for {assignment?.name}</h1>
<h2>Submission Grades:</h2>
<table>
{assignmentProblems.map(ap => (
<th>{ap.problemName} ({ap.maxScore})</th>
))}
<th>Total Score</th>
<tr>
{assignmentProblems.map(ap => (
<td>{submissionProblemScores.find(sps => sps.assignmentProblemId === ap.id)?.score ?? "N/A"}</td>
))}
<td>{submissionScore?.score ?? "N/A"}</td>
</tr>
<div className={styles.feedbackContainer}>
<h3 className={styles.content_title}>Feedback:</h3>
<div className={styles.problemAnswerContainer}>
<table className={styles.assignmentTable}>
<thead>
<tr>
{assignmentProblems.map(ap => (
<th key={ap.id}>{ap.problemName}</th>
))}
<th>Total Score</th>
</tr>
</thead>
<tbody>
<tr>

{assignmentProblems.map(ap => (
<td key={ap.id}>
{submissionProblemScores.find(sps => sps.assignmentProblemId === ap.id)?.score ?? "N/A"}
</td>
))}
<td>{submissionScore?.score ?? "N/A"}</td>
</tr>
</tbody>
</table>
<Link to={`/course/${courseId}/assignment/${assignmentId}/submission/${submissionId}/feedback`}>View
Feedback</Link>
<br/>
</div>
{submissionScore?.feedback ? (
<p>{submissionScore.feedback}</p>
) : (
<p>No feedback provided for this submission.</p>
)}
{submissionProblemScores.map(sps => (
<div>
<h2>Feedback for {assignmentProblems.find(ap => ap.id === sps.assignmentProblemId)?.problemName}:</h2>
<pre>{sps.feedback}</pre>
</div>
))}

<h2>Submission Content:</h2>
<pre>{submission?.content}</pre>
</div>
<h2 className={styles.content_title}>Content</h2>
<div className={styles.scrollableContent}>
<pre>{selectedSubmission.content}</pre>
</div>
</>
) : (
<p>Select a submission to view its content.</p>
)}
</div>
</div>
</div>
</PageWrapper>
)
}

0 comments on commit a7d265d

Please sign in to comment.