Skip to content

Commit 37dfdfe

Browse files
authored
Merge pull request #262 from makeopensource/125-timezone-fix
125 timezone rendering
2 parents 2700bca + c797495 commit 37dfdfe

File tree

13 files changed

+84
-80
lines changed

13 files changed

+84
-80
lines changed

devU-client/src/components/listItems/assignmentProblemListItem.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const AssignmentProblemListItem = ({problem, handleChange, disabled}: Props) =>
1717

1818

1919
const getMeta = () => {
20-
setMeta(JSON.parse(problem.metadata))
20+
setMeta(problem.metadata)
2121
}
2222

2323
useEffect(() => {
@@ -57,7 +57,6 @@ const AssignmentProblemListItem = ({problem, handleChange, disabled}: Props) =>
5757
return (
5858
<div key={problem.id} className={styles.problem}>
5959
<h4 className={styles.problem_header}>{problem.problemName}</h4>
60-
{console.log(options)}
6160
{Object.keys(options).map((key : string) => (
6261
<label key={key} className={styles.mcqLabel} style={disabled ? {cursor: 'default'} : undefined}>
6362
<input id={problem.problemName}
@@ -96,7 +95,7 @@ const AssignmentProblemListItem = ({problem, handleChange, disabled}: Props) =>
9695

9796
else {
9897
return(
99-
<div>{console.log(meta)}Unknown type, something is wrong on the backend!</div>)
98+
<div>Unknown type, something is wrong on the backend!</div>)
10099
}
101100
}
102101

devU-client/src/components/pages/Attendence/InstructorAttendancePage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const InstructorAttendancePage: React.FC<Props> = () => {
7676
};
7777

7878
if (!courseInfo) {
79-
return <PageWrapper><p style={{ padding: '2rem' }}>Loading course info...</p></PageWrapper>;
79+
return <PageWrapper><p className='info'>Loading course info...</p></PageWrapper>;
8080
}
8181

8282
return (
@@ -130,7 +130,7 @@ const InstructorAttendancePage: React.FC<Props> = () => {
130130

131131
<div style={{ marginTop: '2rem' }}>
132132
{attendanceRecords.length === 0 ? (
133-
<p className="empty-message">No attendance records yet.</p>
133+
<p className="empty-message info">No attendance records yet.</p>
134134
) : (
135135
<table className="attendance-table">
136136
<thead>

devU-client/src/components/pages/Attendence/attendancePage.scss

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,11 @@
22

33

44

5-
65
h2 {
76
text-align: center;
87
}
98

10-
p {
11-
text-align: center;
12-
margin-left: 0;
13-
}
9+
1410

1511
.pageWrapper {
1612
padding: 0 100px;
@@ -29,6 +25,11 @@ p {
2925
margin-top: 0;
3026
}
3127

28+
.info {
29+
text-align: center;
30+
margin-left: 0;
31+
}
32+
3233
.datepickerContainer {
3334
width: 100%;
3435
text-align: center;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@
225225
.submissionsContainer {
226226
display: flex;
227227
flex-direction: column;
228+
gap:15px;
228229
margin: auto;
229230
width: 80%;
230231
margin-top: 20px;

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

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'
22
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 /*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'
@@ -37,13 +37,12 @@ const AssignmentDetailPage = () => {
3737
const [submissions, setSubmissions] = useState(new Array<Submission>())
3838
const [assignment, setAssignment] = useState<Assignment>()
3939
const [course, setCourse] = useState<Course>()
40-
const [notClickable, setClickable] = useState(true);
40+
const [notClickable, setNotClickable] = useState(true);
4141

4242

4343

4444
// const [containerAutograder, setContainerAutograder] = useState<ContainerAutoGrader | null>()
4545
// const contaierAutograder = false; //TODO: Use the above commented out code to get the container autograder
46-
const [nonContainerAutograders, setNonContainerAutograders] = useState(new Array<NonContainerAutoGrader>())
4746
const [showScoreboard, setShowScoreboard] = useState(false);
4847
setShowScoreboard;
4948
const location = useLocation();
@@ -83,9 +82,7 @@ const AssignmentDetailPage = () => {
8382
// const containerAutograder = (await RequestService.get<ContainerAutoGrader[]>(`/api/course/${courseId}/assignment/${assignmentId}/container-auto-graders`)).pop() ?? null
8483
// setContainerAutograder(containerAutograder)
8584

86-
const nonContainers = await RequestService.get<NonContainerAutoGrader[]>(`/api/course/${courseId}/assignment/${assignmentId}/non-container-auto-graders`)
87-
setNonContainerAutograders(nonContainers)
88-
nonContainerAutograders
85+
8986

9087

9188
} catch (err: any) {
@@ -127,7 +124,6 @@ const AssignmentDetailPage = () => {
127124
...prevState,
128125
[key]: value
129126
}));
130-
console.log(formData)
131127
}
132128
};
133129

@@ -137,7 +133,7 @@ const AssignmentDetailPage = () => {
137133
}
138134

139135
const handleCheckboxChange = () => {
140-
setClickable(!notClickable);
136+
setNotClickable(!notClickable);
141137
};
142138

143139
const handleSubmit = async () => {
@@ -153,8 +149,6 @@ const AssignmentDetailPage = () => {
153149
content: JSON.stringify(contentField),
154150
}
155151

156-
console.log(contentField)
157-
158152
setLoading(true)
159153

160154
try {
@@ -165,6 +159,7 @@ const AssignmentDetailPage = () => {
165159
submission.append('courseId', courseId)
166160
submission.append('content', JSON.stringify(contentField))
167161
submission.append('files', file)
162+
168163

169164
response = await RequestService.postMultipart(`/api/course/${courseId}/assignment/${assignmentId}/submissions`, submission);
170165
} else {
@@ -182,6 +177,7 @@ const AssignmentDetailPage = () => {
182177
const message = Array.isArray(err) ? err.map((e) => `${e.param} ${e.msg}`).join(', ') : err.message
183178
setAlert({ autoDelete: false, type: 'error', message })
184179
} finally {
180+
setNotClickable(true); // checkbox resets so this needs to too when submitted
185181
setLoading(false)
186182
await fetchData()
187183
}

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

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface Props {
2222
onClose: () => void;
2323
}
2424

25+
2526
const AddAssignmentModal = ({ open, onClose }: Props) => {
2627
const { courseId } = useParams<{ courseId: string }>()
2728
const [setAlert] = useActionless(SET_ALERT)
@@ -33,6 +34,15 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
3334
const [assignments, setAssignments] = useState<Assignment[]>([])
3435
const history = useHistory()
3536

37+
const isSubmittable = () => {
38+
if (!startDate || !endDate || !dueDate ||
39+
!formData.name || !formData.categoryName){
40+
return false;
41+
}
42+
return true;
43+
}
44+
45+
3646
const [formData, setFormData] = useState({
3747
courseId: courseId,
3848
name: '',
@@ -61,14 +71,24 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
6171
setCurrentCategory(newOption)
6272
};
6373

64-
const handleStartDateChange = (e: React.ChangeEvent<HTMLInputElement>) => { setStartDate(e.target.value) }
65-
const handleEndDateChange = (e: React.ChangeEvent<HTMLInputElement>) => { setEndDate(e.target.value) }
74+
const handleStartDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
75+
const date = new Date(e.target.value)
76+
date.setHours(24)
77+
setStartDate(date.toISOString())
78+
}
79+
const handleEndDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
80+
const date = new Date(e.target.value)
81+
date.setHours(23, 59)
82+
setEndDate(date.toISOString())
83+
}
6684
const handleDueDateChange = (e: React.ChangeEvent<HTMLInputElement>) => {
67-
setDueDate(e.target.value)
85+
const date = new Date(e.target.value)
86+
date.setHours(23, 59)
87+
setDueDate(date.toISOString())
6888

6989
// automatically set end date
7090
if (!endDate) {
71-
setEndDate(e.target.value)
91+
setEndDate(date.toISOString())
7292
}
7393
}
7494

@@ -133,7 +153,7 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
133153
}, [assignments])
134154

135155
return (
136-
<Modal title="Add Assignment" buttonAction={handleSubmit} open={open} onClose={onClose}>
156+
<Modal title="Add Assignment" buttonAction={handleSubmit} open={open} onClose={onClose} isSubmittable={isSubmittable}>
137157
<div className="input-group">
138158
<label htmlFor="categoryName" className="input-label">Assignment Category:</label>
139159
<TextDropdown
@@ -186,7 +206,10 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
186206
<div>
187207
<label htmlFor="end_date">End Date:</label>
188208
<br />
189-
<input type='date' id="end_date" value={endDate} onChange={handleEndDateChange} />
209+
<input type='date'
210+
id="end_date"
211+
value={endDate.split("T")[0]} // get rid of HH:MM info to display in date-only box :D
212+
onChange={handleEndDateChange} />
190213
</div>
191214
</div>
192215
<span>Select submission for final score:</span>

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

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,17 @@ const AssignmentUpdatePage = () => {
6464

6565
// taken out of the design for the moment, should get incorporated later
6666
/*const handleCheckbox = (e: React.ChangeEvent<HTMLInputElement>) => {setFormData(prevState => ({ ...prevState, disableHandins: e.target.checked }))}*/
67-
const handleStartDateChange = (e : React.ChangeEvent<HTMLInputElement>) => {setFormData(prevState => ({ ...prevState, startDate: e.target.value + "Z" }))}
68-
const handleEndDateChange = (e : React.ChangeEvent<HTMLInputElement>) => {setFormData(prevState => ({ ...prevState, endDate: e.target.value + "Z"}))}
69-
const handleDueDateChange = (e : React.ChangeEvent<HTMLInputElement>) => {setFormData(prevState => ({ ...prevState, dueDate: e.target.value + "Z"}))}
67+
const handleStartDateChange = (e : React.ChangeEvent<HTMLInputElement>) => {
68+
const newDate = new Date(e.target.value)
69+
setFormData(prevState => ({ ...prevState, startDate: isNaN(newDate.getTime()) ? "" : newDate.toISOString() }))
70+
}
71+
const handleEndDateChange = (e : React.ChangeEvent<HTMLInputElement>) => {
72+
const newDate = new Date(e.target.value)
73+
setFormData(prevState => ({ ...prevState, endDate: isNaN(newDate.getTime()) ? "" : newDate.toISOString() } )) }
74+
75+
const handleDueDateChange = (e : React.ChangeEvent<HTMLInputElement>) => {
76+
const newDate = new Date(e.target.value)
77+
setFormData(prevState => ({ ...prevState, dueDate: isNaN(newDate.getTime()) ? "" : newDate.toISOString() } ))}
7078

7179
const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {
7280
if (e.target.files) {
@@ -202,6 +210,8 @@ const AssignmentUpdatePage = () => {
202210

203211

204212

213+
214+
205215
const handleDeleteProblem = async (problem: AssignmentProblem) => {
206216
// const idsToDelete = nonContainerAutograders.filter(ncag => ncag.)
207217
const ncag = nonContainerAutograders.find((n) => (n.question === problem.problemName && n.createdAt === problem.createdAt))
@@ -240,12 +250,7 @@ const AssignmentUpdatePage = () => {
240250
};
241251

242252
const openEditModal = (problem: AssignmentProblem) => {
243-
const ncag = nonContainerAutograders.find((n) => (n.question === problem.problemName && n.createdAt === problem.createdAt))
244-
if (!ncag) {
245-
fetchAssignmentProblems()
246-
return
247-
}
248-
const type = JSON.parse(ncag?.metadata ?? "").type
253+
const type = JSON.parse(problem.metadata).type ?? ""
249254
if (type === "MCQ-mult" || type === "MCQ-single"){
250255
setMcqProblemId(problem.id)
251256
setMcqEditModal(true)
@@ -256,7 +261,12 @@ const AssignmentUpdatePage = () => {
256261
setTextProblemId(problem.id)
257262
setTextEditModal(true)
258263
}
259-
console.log(type)
264+
}
265+
266+
const utcToLocal = (currDate: Date) => {
267+
const diff = currDate.getTimezoneOffset() * 60000
268+
const newDate = new Date(currDate.getTime() - diff)
269+
return isNaN(newDate.getTime()) ? "" : newDate.toISOString().split("Z")[0]
260270
}
261271

262272

@@ -336,13 +346,13 @@ const AssignmentUpdatePage = () => {
336346
</div>
337347
</div>
338348
<div className={styles.datepickerContainer}>
339-
<label htmlFor="start_date">Start Date *</label>
340-
<label htmlFor="due_date">Due Date *</label>
341-
<label htmlFor="end_date">End Date *</label>
349+
<label htmlFor="start_date">Start Date (EDT)*</label>
350+
<label htmlFor="due_date">Due Date (EDT)*</label>
351+
<label htmlFor="end_date">End Date (EDT)*</label>
342352

343-
<input type='datetime-local' id="start_date" value={formData.startDate.slice(0,-1)} onChange={handleStartDateChange}/>
344-
<input type='datetime-local' id="due_date" value={formData.dueDate.slice(0,-1)} onChange={handleDueDateChange}/>
345-
<input type='datetime-local' id="end_date" value={formData.endDate.slice(0,-1)} onChange={handleEndDateChange}/>
353+
<input type='datetime-local' id="start_date" value={utcToLocal(new Date(formData.startDate))} onChange={handleStartDateChange}/>
354+
<input type='datetime-local' id="due_date" value={utcToLocal(new Date(formData.dueDate))} onChange={handleDueDateChange}/>
355+
<input type='datetime-local' id="end_date" value={utcToLocal(new Date(formData.endDate))} onChange={handleEndDateChange}/>
346356
</div>
347357
<h2 className={styles.header}>Attachments</h2>
348358
{(files.length != 0) ? (

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ const MultipleChoiceModal = ({ open, onClose, edit, problemId}: Props) => {
3636
const assignmentProblemData = await RequestService.get<AssignmentProblem>(`/api/course/${courseId}/assignment/${assignmentId}/assignment-problems/${problemId}`);
3737
const ncagData = await RequestService.get<NonContainerAutoGrader[]>(`/api/course/${courseId}/assignment/${assignmentId}/non-container-auto-graders`);
3838
const ncag = ncagData.find((as) => (as.id === problemId))
39-
if (ncag?.metadata){ // UPDATE for AssignmentProblem metadata
40-
const meta = JSON.parse(ncag.metadata)
39+
if (assignmentProblemData.metadata){
40+
const meta = JSON.parse(assignmentProblemData.metadata)
4141
const type = meta.type
4242
if (type === "MCQ-mult"){
4343
setBoxType("checkbox")
@@ -47,8 +47,8 @@ const MultipleChoiceModal = ({ open, onClose, edit, problemId}: Props) => {
4747
setFormData(({type: type,
4848
title: assignmentProblemData.problemName,
4949
maxScore: '' + assignmentProblemData.maxScore,
50-
correctAnswer: ncag.correctString,
51-
regex: ncag.isRegex
50+
correctAnswer: ncag?.correctString ?? "",
51+
regex: ncag?.isRegex ?? false
5252
}))
5353
const options = meta.options
5454
setOptions(new Map(Object.entries(options)))
@@ -144,6 +144,7 @@ const MultipleChoiceModal = ({ open, onClose, edit, problemId}: Props) => {
144144
maxScore: '',
145145
correctAnswer: '',
146146
regex: false})
147+
setOptions(new Map<string,string>([['a',''],['b',''],['c','']]))
147148
setBoxType('checkbox')
148149
}
149150

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const TextProblemModal = ({ open, onClose, edit, problemId }: Props) => {
6565
maxScore: parseInt(formData.maxScore),
6666
metadata: {
6767
type: 'Text'
68-
}
68+
}
6969
};
7070

7171
const graderFormData = {
@@ -76,9 +76,7 @@ const TextProblemModal = ({ open, onClose, edit, problemId }: Props) => {
7676
correctString: formData.correctAnswer,
7777
score: Number(formData.maxScore),
7878
isRegex: formData.regex,
79-
metadata: {
80-
type: 'Text'
81-
}
79+
8280
}
8381

8482
if (edit){ // If updating, we'll make a put request

devU-client/src/components/pages/gradebook/gradebookInstructorPage.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ const TableRow = ({ user, assignments, assignmentScores, maxScores }: RowProps)
4545
assignments.map(a => {
4646
const assignmentScore = assignmentScores.find(as => as.assignmentId === a.id && as.userId === user.id)
4747
if (a.id && assignmentScore){ // Submission defined, so...
48-
if (assignmentScore.createdAt){
49-
const late: boolean = new Date(assignmentScore.createdAt) > new Date(a.dueDate)
48+
if (assignmentScore.updatedAt){
49+
const late: boolean = new Date(assignmentScore.updatedAt) > new Date(a.dueDate) // UPDATE for grading opts
5050
if (late){ // render in red if assignment submission was late.
5151
return (<td className={styles.late} >{assignmentScore.score}/{maxScores.get(a.id)} <strong>!</strong></td>)
5252
}
@@ -170,6 +170,7 @@ const GradebookInstructorPage = () => {
170170

171171
const assignmentScores = await RequestService.get<AssignmentScore[]>(`/api/course/${courseId}/assignment-scores`)
172172
setAssignmentScores(assignmentScores)
173+
console.log(assignmentScores)
173174

174175

175176
} catch (error: any) {

0 commit comments

Comments
 (0)