Skip to content

Commit f4ad8ae

Browse files
authored
Merge pull request #244 from makeopensource/95-bug-fixes
95 bug fixes
2 parents 24f4008 + 835d258 commit f4ad8ae

10 files changed

Lines changed: 170 additions & 139 deletions

File tree

devU-client/src/components/pages/assignments/assignmentDetailPage.scss

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@
5555
.problems_section{
5656
width: 100%;
5757
display: flex;
58+
// justify-content: space-between;
5859
justify-content: center;
60+
gap: 20px;
5961
}
6062

6163
.options_section{
@@ -67,6 +69,10 @@
6769
justify-content: flex-end;
6870
}
6971

72+
.file_upload {
73+
width: 30%;
74+
}
75+
7076
.problems_list{
7177
width: 50%;
7278
gap: 10px;
@@ -90,10 +96,17 @@
9096
margin-top: 10px;
9197
align-self: flex-start;
9298
gap: 10px;
99+
margin: auto;
93100
}
94101

95102
.affirmText{
96103
color: $text-color;
104+
cursor: pointer;
105+
}
106+
107+
.handinHistory{
108+
text-decoration: underline;
109+
cursor: pointer;
97110
}
98111

99112
.handinHistory{

devU-client/src/components/pages/assignments/assignmentDetailPage.tsx

Lines changed: 77 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import React, {useEffect, useState} from 'react'
2-
import {useHistory, useParams} from 'react-router-dom'
1+
import React, { useEffect, useState } from 'react'
2+
import { useHistory, useParams } from 'react-router-dom'
33
import PageWrapper from 'components/shared/layouts/pageWrapper'
44
import AssignmentProblemListItem from 'components/listItems/assignmentProblemListItem'
5-
import {Assignment, AssignmentProblem, Course, Submission, NonContainerAutoGrader /*SubmissionScore, /*ContainerAutoGrader*/} from 'devu-shared-modules'
5+
import { Assignment, AssignmentProblem, Course, Submission, NonContainerAutoGrader /*SubmissionScore, /*ContainerAutoGrader*/ } from 'devu-shared-modules'
66
import RequestService from 'services/request.service'
77
import ErrorPage from '../errorPage/errorPage'
88
import LoadingOverlay from 'components/shared/loaders/loadingOverlay'
9-
import {useActionless, useAppSelector} from 'redux/hooks'
10-
import {SET_ALERT} from 'redux/types/active.types'
9+
import { useActionless, useAppSelector } from 'redux/hooks'
10+
import { SET_ALERT } from 'redux/types/active.types'
1111
//import Card from '@mui/material/Card'
1212
//import CardContent from '@mui/material/CardContent'
1313
//import {Accordion, AccordionDetails, TextField, Typography} from '@mui/material'
@@ -16,15 +16,16 @@ import {SET_ALERT} from 'redux/types/active.types'
1616
//import Grid from '@mui/material/Unstable_Grid2'
1717

1818
import styles from './assignmentDetailPage.scss'
19-
import {prettyPrintDateTime, fullWordPrintDate} from "../../../utils/date.utils";
19+
import { prettyPrintDateTime, fullWordPrintDate } from "../../../utils/date.utils";
2020

2121
import { useLocation } from 'react-router-dom';
2222
import Scoreboard from '../assignments/scoreboard';
23+
// import DragDropFile from 'components/utils/dragDropFile'
2324

2425
const AssignmentDetailPage = () => {
2526
const [setAlert] = useActionless(SET_ALERT)
2627
const history = useHistory()
27-
const { assignmentId, courseId } = useParams<{assignmentId: string, courseId: string}>()
28+
const { assignmentId, courseId } = useParams<{ assignmentId: string, courseId: string }>()
2829
const userId = useAppSelector((store) => store.user.id)
2930
const role = useAppSelector((store) => store.roleMode)
3031

@@ -42,7 +43,7 @@ const AssignmentDetailPage = () => {
4243

4344
// const [containerAutograder, setContainerAutograder] = useState<ContainerAutoGrader | null>()
4445
// const contaierAutograder = false; //TODO: Use the above commented out code to get the container autograder
45-
const [nonContainerAutograders, setNonContainerAutograders] = useState(new Array <NonContainerAutoGrader>())
46+
const [nonContainerAutograders, setNonContainerAutograders] = useState(new Array<NonContainerAutoGrader>())
4647
const [showScoreboard, setShowScoreboard] = useState(false);
4748
setShowScoreboard;
4849
const location = useLocation();
@@ -86,28 +87,29 @@ const AssignmentDetailPage = () => {
8687
setNonContainerAutograders(nonContainers)
8788
nonContainerAutograders
8889

89-
} catch (err:any) {
90+
91+
} catch (err: any) {
9092
setError(err)
91-
const message = "Submission past due date"//Array.isArray(err) ? err.map((e) => `${e.param} ${e.msg}`).join(', ') : err.message
92-
setAlert({autoDelete: false, type: 'error', message})
93+
const message = "Submission past due date"//Array.isArray(err) ? err.map((e) => `${e.param} ${e.msg}`).join(', ') : err.message
94+
setAlert({ autoDelete: false, type: 'error', message })
9395
} finally {
9496
setLoading(false)
9597
}
9698
}
9799

98100
if (loading) return <LoadingOverlay delay={250} />
99101
if (error) return <ErrorPage error={error} />
100-
102+
101103
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
102104
const type = e.target.type;
103105
const value = e.target.value;
104106
const key = e.target.id;
105-
107+
106108
if (type === 'checkbox') { // behavior for multiple choic questions
107109
const newState = e.target.checked;
108-
110+
109111
setFormData(prevState => {
110-
const currentValue = prevState[key] || "";
112+
const currentValue = prevState[key] || "";
111113
let res = '';
112114
if (newState) {
113115
res = currentValue + value
@@ -130,7 +132,7 @@ const AssignmentDetailPage = () => {
130132
};
131133

132134

133-
const handleFileChange = (e : React.ChangeEvent<HTMLInputElement>) => {
135+
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
134136
setFile(e.target.files?.item(0))
135137
}
136138

@@ -141,14 +143,14 @@ const AssignmentDetailPage = () => {
141143
const handleSubmit = async () => {
142144
let response;
143145
const contentField = {
144-
filepaths : [],
145-
form : formData
146+
filepaths: [],
147+
form: formData
146148
}
147149
const submission = {
148-
userId : userId,
149-
assignmentId : assignmentId,
150-
courseId : courseId,
151-
content : JSON.stringify(contentField),
150+
userId: userId,
151+
assignmentId: assignmentId,
152+
courseId: courseId,
153+
content: JSON.stringify(contentField),
152154
}
153155

154156
console.log(contentField)
@@ -172,7 +174,7 @@ const AssignmentDetailPage = () => {
172174
setAlert({ autoDelete: true, type: 'success', message: 'Submission Sent' })
173175

174176
// Now you can use submissionResponse.id here
175-
await RequestService.post(`/api/course/${courseId}/grade/${response.id}`, {} )
177+
await RequestService.post(`/api/course/${courseId}/grade/${response.id}`, {})
176178
setAlert({ autoDelete: true, type: 'success', message: 'Submission Graded' })
177179

178180
await fetchData()
@@ -189,23 +191,23 @@ const AssignmentDetailPage = () => {
189191
const endDate = new Date(assignment.endDate);
190192
const now = new Date();
191193
return now > endDate;
192-
}
194+
}
193195
return false;
194196
};
195197

196198
handleFileChange;
197199

198200

199-
return(
201+
return (
200202
<PageWrapper>
201203
<div className={styles.header}>
202-
<h1 style={{gridColumnStart:2}}>Submit Assignment</h1>
203-
<button style={{marginLeft:'auto'}} className='btnPrimary' onClick={() => {history.goBack()}}>Back to Course</button>
204+
<h1 style={{ gridColumnStart: 2 }}>Submit Assignment</h1>
205+
<button style={{ marginLeft: 'auto' }} className='btnPrimary' onClick={() => { history.goBack() }}>Back to Course</button>
204206
</div>
205207

206208
<div className={styles.details}>
207209
<div className={styles.assignmentDetails}>
208-
<h2 style={{textAlign:'left'}}>{course?.number} - {assignment?.name}</h2>
210+
<h2 style={{ textAlign: 'left' }}>{course?.number} - {assignment?.name}</h2>
209211
<div>{assignment?.description}</div>
210212
</div>
211213
<div className={styles.submissionDetails}>
@@ -216,15 +218,15 @@ const AssignmentDetailPage = () => {
216218
<strong>Available Until:&nbsp;</strong>{assignment?.endDate ? fullWordPrintDate(assignment?.endDate) : "N/A"}
217219
</span>
218220
<span className={styles.metaText}>
219-
<strong>Submissions Made:&nbsp;</strong>{submissions.length +"/"+ assignment?.maxSubmissions}
221+
<strong>Submissions Made:&nbsp;</strong>{submissions.length + "/" + assignment?.maxSubmissions}
220222
</span>
221223
<span>
222224
<a onClick={() => history.push(`/course/${courseId}/assignment/${assignmentId}/submissions`)}
223-
className={styles.handinHistory}>View Handin History</a>
225+
className={styles.handinHistory}>View Handin History</a>
224226
</span>
225227
</div>
226228
</div>
227-
<div className={styles.details} style={{marginTop: '20px'}}>
229+
<div className={styles.details} style={{ marginTop: '20px' }}>
228230
<div className={styles.assignmentDetails}>
229231
<span className={styles.metaText}>
230232
<strong>Assignment Category:&nbsp;</strong>{assignment?.categoryName}
@@ -234,62 +236,69 @@ const AssignmentDetailPage = () => {
234236
</span>
235237
</div>
236238
{role.isInstructor() && <div className={styles.options_section}>
237-
<button className={`btnPrimary ${styles.parallel_button}`} onClick={() => {
238-
history.push(`/course/${courseId}/assignment/${assignmentId}/update`)
239-
}}>Edit Assignment</button>
240-
<button className={`btnPrimary ${styles.parallel_button}`}>Grade Submissions</button>
241-
<button className={`btnPrimary ${styles.parallel_button}`}>Scoreboard</button>
239+
<button className={`btnPrimary ${styles.parallel_button}`} onClick={() => {
240+
history.push(`/course/${courseId}/assignment/${assignmentId}/update`)
241+
}}>Edit Assignment</button>
242+
<button className={`btnPrimary ${styles.parallel_button}`}>Grade Submissions</button>
243+
<button className={`btnPrimary ${styles.parallel_button}`}>Scoreboard</button>
242244
</div>}
243245
</div>
244-
246+
247+
<h3 style={{ textAlign: 'center' }}>Problems</h3>
245248
<div className={styles.problems_section}>
249+
250+
{/* <div className={styles.file_upload}>
251+
<h4 className={styles.problem_header}>File Upload:</h4>
252+
<DragDropFile handleFile={(e) => {console.log(e)}} />
253+
</div> */}
254+
246255
<div className={styles.problems_list}>
247256
<h2>Problems</h2>
248257
{assignmentProblems.length != 0 ? (assignmentProblems.map((problem) => (
249258
<>
250-
<AssignmentProblemListItem problem={problem} handleChange={handleChange}/>
251-
<hr/>
259+
<AssignmentProblemListItem problem={problem} handleChange={handleChange} />
260+
<hr />
252261
</>
253-
))) : <div style={{fontStyle:'italic', textAlign: 'center', marginTop: '10px'}}> No problems yet...</div>}
262+
))) : <div style={{ fontStyle: 'italic', textAlign: 'center', marginTop: '10px' }}> No problems yet...</div>}
254263
{!(isSubmissionDisabled()) && assignmentProblems && assignmentProblems.length > 0 ? (
255-
<div className = {styles.submit_container}>
264+
<div className={styles.submit_container}>
256265
<div className={styles.affirmation}>
257-
<input type='checkbox' onClick={handleCheckboxChange}/>
258-
<span className={styles.affirmText}>I affirm that I have complied with this course's academic integrity policy as defined in the syllabus.</span>
266+
<input type='checkbox' id='ai-check' onClick={handleCheckboxChange} />
267+
<label htmlFor='ai-check' className={styles.affirmText}>I affirm that I have complied with this courses academic integrity policy as defined in the syllabus.</label>
259268
</div>
260269
<button className='btnPrimary'
261-
style={{marginTop:'40px'}}
262-
onClick={handleSubmit}
263-
disabled={notClickable}
264-
>Submit Assignment</button>
270+
style={{ marginTop: '40px' }}
271+
onClick={handleSubmit}
272+
disabled={notClickable}
273+
>Submit Assignment</button>
265274
</div>
266-
) : null}
267-
</div>
275+
) : null}
276+
</div>
268277
</div>
269278

270279

271280
<div>
272-
<div className={styles.submissionsContainer}>
273-
{submissions.map((submission, index) => (
274-
<div className={styles.submissionCard} key={index}>
275-
<div onClick={() => {
276-
history.push(`/course/${courseId}/assignment/${assignmentId}/submission/${submission.id}`)
277-
}}>
278-
<div>
279-
<div className={styles.submissionHeading}>{`Submission ${submissions.length - index}`}</div>
280-
<div className={styles.submissionTime}>{`Submitted at: ${submission.createdAt && prettyPrintDateTime(submission.createdAt)}`}</div>
281-
</div>
282-
</div>
283-
</div>
284-
))}
281+
<div className={styles.submissionsContainer}>
282+
{submissions.map((submission, index) => (
283+
<div className={styles.submissionCard} key={index}>
284+
<div onClick={() => {
285+
history.push(`/course/${courseId}/assignment/${assignmentId}/submission/${submission.id}`)
286+
}}>
287+
<div>
288+
<div className={styles.submissionHeading}>{`Submission ${submissions.length - index}`}</div>
289+
<div className={styles.submissionTime}>{`Submitted at: ${submission.createdAt && prettyPrintDateTime(submission.createdAt)}`}</div>
290+
</div>
291+
</div>
292+
</div>
293+
))}
285294

286-
{showScoreboard && (
287-
<div className={styles.scoreboardContainer}>
288-
<Scoreboard courseId={courseId} assignmentId={assignmentId} />
295+
{showScoreboard && (
296+
<div className={styles.scoreboardContainer}>
297+
<Scoreboard courseId={courseId} assignmentId={assignmentId} />
289298

290-
</div>
291-
)}
292-
</div>
299+
</div>
300+
)}
301+
</div>
293302
</div>
294303

295304
</PageWrapper>

devU-client/src/components/pages/forms/assignments/assignmentFormPage.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import React, { useState, useEffect } from 'react'
2-
// import { useHistory } from 'react-router-dom'
2+
import { useHistory } from 'react-router-dom'
33
import { ExpressValidationError, Assignment } from 'devu-shared-modules'
44
import 'react-datepicker/dist/react-datepicker.css'
5-
// import PageWrapper from 'components/shared/layouts/pageWrapper'
65

76
import RequestService from 'services/request.service'
87
import { useActionless } from 'redux/hooks'
9-
// import TextField from 'components/shared/inputs/textField'
10-
// import Button from '../../../shared/inputs/button'
11-
// import DragDropFile from 'components/utils/dragDropFile'
128
import { Option } from 'components/shared/inputs/dropdown'
139

1410

@@ -35,6 +31,7 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
3531
const [categoryOptions, setAllCategoryOptions] = useState<Option<String>[]>([])
3632
const [currentCategory, setCurrentCategory] = useState<Option<String>>()
3733
const [assignments, setAssignments] = useState<Assignment[]>([])
34+
const history = useHistory()
3835

3936
const [formData, setFormData] = useState({
4037
courseId: courseId,
@@ -66,7 +63,14 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
6663

6764
const handleStartDateChange = (e: React.ChangeEvent<HTMLInputElement>) => { setStartDate(e.target.value) }
6865
const handleEndDateChange = (e: React.ChangeEvent<HTMLInputElement>) => { setEndDate(e.target.value) }
69-
const handleDueDateChange = (e: React.ChangeEvent<HTMLInputElement>) => { setDueDate(e.target.value) }
66+
const handleDueDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
67+
setDueDate(e.target.value)
68+
69+
// automatically set end date
70+
if (!endDate) {
71+
setEndDate(e.target.value)
72+
}
73+
}
7074

7175
const handleSubmit = () => {
7276
const finalFormData = {
@@ -101,12 +105,10 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
101105

102106

103107
RequestService.postMultipart(`/api/course/${courseId}/assignments/`, multipart)
104-
.then(() => {
105-
setAlert({ autoDelete: true, type: 'success', message: 'Assignment Added' })
106-
// Navigate to the update page for the new assignment
107-
// navigate(`/course/${courseId}/assignment/${response.id}/update`);
108-
// history.goBack()
108+
.then((response) => {
109+
// setAlert({ autoDelete: true, type: 'success', message: 'Assignment Added' })
109110
onClose();
111+
history.push(`/course/${courseId}/assignment/${response.id}/update`);
110112
})
111113
.catch((err: ExpressValidationError[] | Error) => {
112114
const message = Array.isArray(err) ? err.map((e) => `${e.param} ${e.msg}`).join(', ') : err.message
@@ -115,9 +117,6 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
115117

116118
setAlert({ autoDelete: false, type: 'error', message })
117119
})
118-
.finally(() => {
119-
120-
})
121120
}
122121

123122
useEffect(() => {RequestService.get(`/api/course/${courseId}/assignments`).then((res) => { setAssignments(res) })}, [formData])
@@ -183,7 +182,7 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
183182
<div>
184183
<label htmlFor="end_date">End Date:</label>
185184
<br />
186-
<input type='date' id="end_date" onChange={handleEndDateChange} />
185+
<input type='date' id="end_date" value={endDate} onChange={handleEndDateChange} />
187186
</div>
188187
</div>
189188
<label htmlFor="disableHandins">Disable Submissions?<input type="checkbox" id="disableHandins" /></label>

0 commit comments

Comments
 (0)