Skip to content

Commit 08807d2

Browse files
committed
Merge remote-tracking branch 'origin/develop' into develop
2 parents 6303787 + 11dd97c commit 08807d2

File tree

10 files changed

+289
-374
lines changed

10 files changed

+289
-374
lines changed

devU-client/src/assets/global.scss

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
text-align: center;
2424
}
2525

26-
a{
26+
a {
2727
color: var(--link-blue);
2828
}
29-
29+
3030
// general button template, extends to 3 types of buttons - primary, secondary, delete
3131
.btn {
3232
cursor: pointer;
@@ -42,26 +42,28 @@
4242
font-style: italic;
4343
margin-right: auto; // Keeps text locked left after hitting 738px
4444
margin-bottom: 20px;
45-
}
45+
}
4646

4747
button.btnPrimary {
4848
@extend .btn;
4949
background-color: var(--primary);
5050
border: 3px solid var(--primary);
5151
color: #fff; // primary button always white text
52-
&:hover{
52+
53+
&:hover {
5354
background-color: var(--hover-darker);
5455
border: 3px solid var(--hover-darker);
5556
}
5657
}
5758

5859
button.btnSecondary {
5960
@extend .btn;
60-
61+
6162
background-color: var(--btn-secondary-background);
6263
color: var(--btn-secondary-text);
6364
border: 3px solid var(--btn-secondary-border);
64-
&:hover{
65+
66+
&:hover {
6567
background-color: var(--hover-lighter);
6668
}
6769
}
@@ -90,21 +92,25 @@
9092
width: 100%
9193
}
9294

93-
.input-group>input, .input-group>textarea{
95+
.input-group>input,
96+
.input-group>textarea {
9497
padding: 10px;
9598
border-radius: 10px;
9699
// border: 1px solid var(--input-field-label);
97100
border: none;
98101
background-color: var(--input-field-background);
99102
color: var(--text-color);
100-
font-family: 'Source Sans Pro', 'Helvetica', 'Arial', sans-serif;;
103+
font-family: 'Source Sans Pro', 'Helvetica', 'Arial', sans-serif;
104+
;
101105
}
102106

103-
.input-group>input::placeholder, .input-group>textarea::placeholder {
107+
.input-group>input::placeholder,
108+
.input-group>textarea::placeholder {
104109
color: var(--input-field-label);
105110
}
106111

107-
.modal-header, .input-subgroup-2col {
112+
.modal-header,
113+
.input-subgroup-2col {
108114
display: flex;
109115
justify-content: space-between;
110116
gap: 20px;
@@ -127,6 +133,21 @@
127133
align-self: center;
128134
}
129135

136+
.pageHeader {
137+
display: grid;
138+
grid-template-columns: 1fr 2fr 1fr;
139+
align-items: center;
140+
}
141+
142+
.pageHeader > h1 {
143+
grid-column-start: 2;
144+
}
145+
146+
.pageHeaderBtn {
147+
@extend .btnPrimary;
148+
margin-left: auto;
149+
}
150+
130151
body {
131152
font-family: 'Source Sans Pro', 'Helvetica', 'Arial', sans-serif;
132153
margin: 0;
@@ -187,7 +208,7 @@
187208
--grey-lighter: #c5c5c5;
188209
--grey: #555555;
189210
--grey-darker: #444444;
190-
--grey-darkest: #333333;
211+
--grey-darkest: #333333;
191212

192213
--blue-lighter: #78B7FF;
193214
--blue: #1F3D7A;
@@ -239,9 +260,7 @@
239260
--hover-darker: var(--purple-lighterer);
240261
--hover-lighter: var(--purple);
241262

242-
--btn-text-color: var(--purple-lighter)
243-
244-
--btn-delete-border: var(--red-lighter);
263+
--btn-text-color: var(--purple-lighter) --btn-delete-border: var(--red-lighter);
245264
--btn-delete-background: var(--red);
246265
--btn-delete-text: #FFF;
247266

@@ -258,13 +277,14 @@
258277
color: var(--text-color);
259278
}
260279

261-
// General Error Message
280+
// General Error Message
262281
.error-message {
263282
color: var(--error-text);
264283
font-size: 0.875rem;
265284
font-weight: bold;
266285
margin-top: 5px;
267286
}
287+
268288
// Validation Error Container
269289
.error-container {
270290
background-color: var(--error-background);
@@ -273,6 +293,7 @@
273293
margin: 10px 0;
274294
border-radius: 5px;
275295
}
296+
276297
// Error Page Styling (From `errorPage.scss`)
277298
.error-page {
278299
background-color: var(--error-page-background);
@@ -281,14 +302,17 @@
281302
justify-content: center;
282303
height: 100vh;
283304
}
305+
284306
.error-heading {
285307
font-size: 2rem;
286308
color: var(--error-text);
287309
}
310+
288311
.error-description {
289312
font-size: 1.2rem;
290313
color: var(--text-color);
291314
}
315+
292316
// Global Input Field Styles
293317
.input-field {
294318
width: 100%;
@@ -304,15 +328,16 @@
304328
border-color: var(--focus);
305329
outline: none;
306330
}
331+
307332
&:disabled {
308333
background-color: var(--grey-lightest);
309334
color: var(--grey-lighter);
310335
cursor: not-allowed;
311336
}
312337
}
313338

314-
315-
339+
340+
316341
// Placeholder Styling
317342
::placeholder {
318343
color: var(--text-color-secondary);
@@ -322,4 +347,4 @@
322347
*:focus {
323348
outline-color: var(--focus);
324349
}
325-
}
350+
}

devU-client/src/components/authenticatedRouter.tsx

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react'
2-
import {Route, Switch} from 'react-router-dom'
2+
import { Route, Switch } from 'react-router-dom'
33

44
import AssignmentDetailPage from 'components/pages/assignments/assignmentDetailPage'
55
import AssignmentUpdatePage from 'components/pages/forms/assignments/assignmentUpdatePage'
@@ -24,44 +24,46 @@ import UserCoursesListPage from "./pages/listPages/courses/coursesListPage";
2424
import JoinCoursePage from "./pages/listPages/joinwithcodepage";
2525

2626
import WebhookURLForm from './pages/webhookURLForm'
27-
// import AddAssignmentModal from 'components/pages/forms/assignments/assignmentFormPage'
2827

2928
const AuthenticatedRouter = () => (
3029
<Switch>
3130

32-
<Route exact path='/' component={HomePage}/>
33-
<Route exact path='/courses' component={CoursesListPage}/>
34-
<Route exact path='/addCoursesForm' component={EditCourseFormPage}/>
31+
<Route exact path='/' component={HomePage} />
32+
<Route exact path='/courses' component={CoursesListPage} />
33+
<Route exact path='/addCoursesForm' component={EditCourseFormPage} />
3534

36-
<Route exact path='/user/:userId/update' component={UserDetailPage}/>
35+
<Route exact path='/user/:userId/update' component={UserDetailPage} />
3736

38-
<Route exact path='/course/:courseId' component={CourseDetailPage}/>
39-
<Route exact path='/course/:courseId/preview' component={CoursePreviewPage}/>
40-
<Route exact path='/course/:courseId/update' component={CourseUpdatePage}/>
41-
<Route exact path='/course/:courseId/gradebook' component={GradebookStudentPage}/>
42-
<Route exact path='/course/:courseId/gradebook/instructor' component={GradebookInstructorPage}/>
37+
<Route exact path='/course/:courseId' component={CourseDetailPage} />
38+
<Route exact path='/course/:courseId/preview' component={CoursePreviewPage} />
39+
<Route exact path='/course/:courseId/update' component={CourseUpdatePage} />
40+
<Route exact path='/course/:courseId/gradebook' component={GradebookStudentPage} />
41+
<Route exact path='/course/:courseId/gradebook/instructor' component={GradebookInstructorPage} />
4342

44-
<Route exact path='/course/:courseId/assignment/:assignmentId' component={AssignmentDetailPage}/>
45-
<Route exact path='/course/:courseId/assignment/:assignmentId/update' component={AssignmentUpdatePage}/>
43+
<Route exact path='/course/:courseId/assignment/:assignmentId' component={AssignmentDetailPage} />
44+
<Route exact path='/course/:courseId/assignment/:assignmentId/update' component={AssignmentUpdatePage} />
4645
<Route exact path='/course/:courseId/assignment/:assignmentId/createNCAG'
47-
component={NonContainerAutoGraderForm}/>
48-
<Route exact path='/course/:courseId/assignment/:assignmentId/createCAG' component={ContainerAutoGraderForm}/>
49-
<Route exact path='/course/:courseId/assignment/:assignmentId/createProblem' component={AssignmentProblemFormPage}/>
50-
<Route exact path='/course/:courseId/webhooks' component={WebhookURLForm}/>
46+
component={NonContainerAutoGraderForm} />
47+
<Route exact path='/course/:courseId/assignment/:assignmentId/createCAG' component={ContainerAutoGraderForm} />
48+
<Route exact path='/course/:courseId/assignment/:assignmentId/createProblem' component={AssignmentProblemFormPage} />
49+
<Route exact path='/course/:courseId/webhooks' component={WebhookURLForm} />
5150

5251
<Route exact path='/course/:courseId/assignment/:assignmentId/submission/:submissionId'
53-
component={SubmissionDetailPage}/>
54-
<Route exact path='/course/:courseId/assignment/:assignmentId/submissions'
55-
component={InstructorSubmissionspage}/>
52+
component={SubmissionDetailPage} />
53+
<Route exact path='/course/:courseId/assignment/:assignmentId/submissions'
54+
component={InstructorSubmissionspage} />
55+
56+
{/* NOTE: maybe get rid of separate feedback page, instead have page to view source (/submissions/:submissionID/view on autolab)*/}
5657
<Route exact path='/course/:courseId/assignment/:assignmentId/submission/:submissionId/feedback'
57-
component={SubmissionFeedbackPage}/>
58-
<Route exact path ='/course/:courseId/assignment/:assignmentId/submission/:submissionId/fileView' component={SubmissionFileView}/>
59-
<Route path="/join-course" component={JoinCoursePage} />
60-
<Route path="/" component={UserCoursesListPage} />
61-
// TBD, undecided where webhooks should be placed
58+
component={SubmissionFeedbackPage} />
59+
60+
<Route exact path='/course/:courseId/assignment/:assignmentId/submission/:submissionId/fileView' component={SubmissionFileView} />
61+
<Route path="/join-course" component={JoinCoursePage} />
62+
<Route path="/" component={UserCoursesListPage} />
63+
{/* // TBD, undecided where webhooks should be placed */}
6264
{/*<Route exact path='/webhookURLPage' component={webhookURLForm}/>*/}
6365

64-
<Route component={NotFoundPage}/>
66+
<Route component={NotFoundPage} />
6567
</Switch>
6668
)
6769

devU-client/src/components/misc/editAssignmentModal.tsx

Whitespace-only changes.

devU-client/src/components/misc/footer.scss

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@
44
background-color: $primary;
55
color: #fff;
66
text-align: left;
7-
width: 100%;
8-
position: fixed;
9-
bottom: 0;
10-
left: 0;
7+
margin-top: auto;
118
font-size: 14px;
129
font-size: 16px;
13-
padding: 10px 0;
10+
padding: 10px $pagePadding;
1411
display: flex;
1512
flex-direction: row;
1613
align-items: center;

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
grid-row-gap: 10px;
88
width: 100%;
99
}
10-
.pageHeader{
10+
11+
.pageHeader {
1112
display: grid;
1213
grid-template-columns: 1fr 2fr 1fr;
1314
align-items: center;
1415
}
16+
1517
.backToCourse{
1618
margin-left: auto;
1719
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React, { useState } from 'react'
2+
import {useParams} from 'react-router-dom'
3+
import { useActionless } from 'redux/hooks'
4+
import { SET_ALERT } from 'redux/types/active.types'
5+
6+
import {SubmissionScore} from 'devu-shared-modules'
7+
import RequestService from 'services/request.service'
8+
import Modal from 'components/shared/layouts/modal'
9+
10+
interface Props {
11+
open: boolean;
12+
onClose: () => void;
13+
submissionScore: SubmissionScore | null;
14+
15+
}
16+
17+
const ManualGradeModal = ({ open, onClose, submissionScore }: Props) => {
18+
const [setAlert] = useActionless(SET_ALERT)
19+
const { assignmentId, courseId } = useParams<{assignmentId: string, courseId: string}>()
20+
21+
const [formData, setFormData] = useState({
22+
submissionId: submissionScore?.submissionId,
23+
score: submissionScore?.score,
24+
feedback: submissionScore?.feedback,
25+
releasedAt: "2024-10-05T14:48:00.00Z"
26+
})
27+
28+
const handleManualGrade = async () => {
29+
// set releasedAt to now in ISO 8601 format
30+
setFormData(prevState => ({ ...prevState, ["releasedAt"]: new Date().toISOString() }))
31+
32+
if (submissionScore) {
33+
// Update the submission score
34+
console.log('Submission Exists')
35+
await RequestService.put(`/api/course/${courseId}/assignment/${assignmentId}/submission-scores/${submissionScore.id}`, formData)
36+
.then(() => {
37+
setAlert({ autoDelete: true, type: 'success', message: 'Submission Score Updated' })
38+
window.location.reload()
39+
})
40+
41+
}
42+
else {
43+
// Create a new submission score
44+
console.log('No Submission')
45+
await RequestService.post(`/api/course/${courseId}/assignment/${assignmentId}/submission-scores`, formData)
46+
.then(() => {
47+
setAlert({ autoDelete: true, type: 'success', message: 'Submission Score Created' })
48+
window.location.reload()
49+
})
50+
}
51+
}
52+
53+
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
54+
const key = e.target.id
55+
const value = e.target.value
56+
57+
setFormData(prevState => ({ ...prevState, [key]: value }))
58+
}
59+
60+
return (
61+
<Modal title="Grade Assignment" buttonAction={handleManualGrade} open={open} onClose={onClose}>
62+
<div className="input-group">
63+
<label htmlFor="score" className="input-label">Assignment Score:</label>
64+
<input type="number" id="score" value={Number(formData.score)} onChange={handleChange} />
65+
</div>
66+
<div className="input-group">
67+
<label htmlFor="feedback" className="input-label">Overall Feedback:</label>
68+
<textarea rows={4} id="feedback" onChange={handleChange} value={String(formData.feedback)}
69+
placeholder='Provide assignment feedback...'/>
70+
</div>
71+
</Modal>
72+
)
73+
}
74+
75+
export default ManualGradeModal;

0 commit comments

Comments
 (0)