Skip to content

Commit 65832ac

Browse files
authored
Merge pull request #267 from makeopensource/86-submission-page-single-file
86 submission page single file
2 parents 21e3cfb + fbc6b5d commit 65832ac

File tree

6 files changed

+340
-285
lines changed

6 files changed

+340
-285
lines changed

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

Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,95 +8,104 @@ import FaIcon from 'components/shared/icons/faIcon'
88

99
type Props = {
1010
problem: AssignmentProblem
11-
handleChange?: (e : React.ChangeEvent<HTMLInputElement>) => void
11+
handleChange?: (e: React.ChangeEvent<HTMLInputElement>) => void
1212
disabled?: boolean
1313
}
1414

15-
const AssignmentProblemListItem = ({problem, handleChange, disabled}: Props) => {
16-
const [meta, setMeta] = useState<{options: {[key:string]: string}, type: string}>()
15+
const AssignmentProblemListItem = ({ problem, handleChange, disabled }: Props) => {
16+
const [meta, setMeta] = useState<{ options: { [key: string]: string }, type: string }>()
1717

1818

1919
const getMeta = () => {
2020
setMeta(problem.metadata)
2121
}
22-
22+
2323
useEffect(() => {
2424
getMeta()
2525
}, [problem])
26-
2726

28-
if (!meta){
27+
28+
if (!meta) {
2929
return (
30-
<div className={styles.problem}>
31-
<div>File Input Problems are not done yet pending backend changes! :D</div>
32-
</div>)
30+
<div className={styles.problem}>
31+
<div>File Input Problems are not done yet pending backend changes! :D</div>
32+
</div>)
3333
}
3434

35-
const type = meta.type
35+
const type = meta.type
3636

3737
if (type == "Text") {
3838
return (
39-
<div key={problem.id} className={styles.problem}>
40-
<h4 className={styles.problem_header}>{problem.problemName}</h4>
41-
<input className={styles.textField}
42-
type='text'
43-
placeholder='Answer'
44-
onChange={handleChange ?? undefined}
45-
disabled={disabled ?? false}
46-
47-
id={problem.problemName}
39+
<div key={problem.id} className={styles.problem}>
40+
<h4 className={styles.problem_header}>{problem.problemName}</h4>
41+
<input className={styles.textField}
42+
type='text'
43+
placeholder='Answer'
44+
onChange={handleChange ?? undefined}
45+
disabled={disabled ?? false}
46+
47+
id={problem.problemName}
4848
/>
49-
</div>
50-
)}
51-
52-
else if(type == "MCQ-mult") {
49+
</div>
50+
)
51+
}
52+
53+
else if (type == "MCQ-mult") {
5354
const options = meta.options
54-
if (!options){
55+
if (!options) {
5556
return <div></div>
5657
}
5758
return (
5859
<div key={problem.id} className={styles.problem}>
5960
<h4 className={styles.problem_header}>{problem.problemName}</h4>
60-
{Object.keys(options).map((key : string) => (
61-
<label key={key} className={styles.mcqLabel} style={disabled ? {cursor: 'default'} : undefined}>
62-
<input id={problem.problemName}
63-
type='checkbox'
64-
value={key}
65-
onChange={handleChange}
66-
disabled={disabled ?? false}/> {options[key]}
67-
61+
{Object.keys(options).map((key: string) => (
62+
<label key={key} className={styles.mcqLabel} style={disabled ? { cursor: 'default' } : undefined}>
63+
<input id={problem.problemName}
64+
type='checkbox'
65+
value={key}
66+
onChange={handleChange}
67+
disabled={disabled ?? false} /> {options[key]}
68+
6869
<span className={styles.checkbox}>
69-
<FaIcon icon='check' className={styles.checkboxCheck}/>
70+
<FaIcon icon='check' className={styles.checkboxCheck} />
7071
</span>{/* custom checkbox */}
7172
</label>))}
7273
</div>)
73-
}
74-
75-
else if(type == "MCQ-single") {
74+
}
75+
76+
else if (type == "MCQ-single") {
7677
const options = meta.options
77-
if (!options){
78+
if (!options) {
7879
return <div></div>
7980
}
8081
return (
8182
<div key={problem.id} className={styles.problem}>
8283
<h4 className={styles.problem_header}>{problem.problemName}</h4>
83-
{Object.keys(options).map((key : string) => (
84-
<label key={key} className={styles.mcqLabel} style={disabled ? {cursor: 'default'} : undefined}>
85-
<input id={problem.problemName}
86-
type='radio'
87-
name={`${problem.id}_answer`}
88-
value={key}
89-
onChange={handleChange}
90-
disabled={disabled ?? false}/> {options[key]}
84+
{Object.keys(options).map((key: string) => (
85+
<label key={key} className={styles.mcqLabel} style={disabled ? { cursor: 'default' } : undefined}>
86+
<input id={problem.problemName}
87+
type='radio'
88+
name={`${problem.id}_answer`}
89+
value={key}
90+
onChange={handleChange}
91+
disabled={disabled ?? false} /> {options[key]}
9192
<span className={styles.radio}></span>{/* custom radio button */}
9293
</label>))}
9394
</div>)
94-
}
95-
95+
}
96+
97+
else if (type == "File") {
98+
return (
99+
<div key={problem.id} className={styles.problem}>
100+
<h4 className={styles.problem_header}>{problem.problemName}</h4>
101+
</div>
102+
)
103+
}
104+
96105
else {
97-
return(
106+
return (
98107
<div>Unknown type, something is wrong on the backend!</div>)
99-
}
108+
}
100109
}
101110

102111

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

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { prettyPrintDateTime, fullWordPrintDate } from "../../../utils/date.util
2020

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

2525
const AssignmentDetailPage = () => {
2626
const [setAlert] = useActionless(SET_ALERT)
@@ -38,6 +38,7 @@ const AssignmentDetailPage = () => {
3838
const [assignment, setAssignment] = useState<Assignment>()
3939
const [course, setCourse] = useState<Course>()
4040
const [notClickable, setNotClickable] = useState(true);
41+
const [hasFileProblem, setHasFileProblem] = useState(false);
4142

4243

4344

@@ -60,8 +61,13 @@ const AssignmentDetailPage = () => {
6061
const courses = await RequestService.get<Course>(`/api/courses/${courseId}`)
6162
setCourse(courses)
6263

63-
const assignmentProblemsReq = await RequestService.get<AssignmentProblem[]>(`/api/course/${courseId}/assignment/${assignmentId}/assignment-problems/`)
64-
setAssignmentProblems(assignmentProblemsReq)
64+
let assignmentProblemsReq = await RequestService.get<AssignmentProblem[]>(`/api/course/${courseId}/assignment/${assignmentId}/assignment-problems/`)
65+
66+
const hasFile = assignmentProblemsReq.some(problem => problem.metadata.type === "File")
67+
setHasFileProblem(hasFile)
68+
69+
const filteredProblems = assignmentProblemsReq.filter(problem => problem.metadata.type !== "File")
70+
setAssignmentProblems(filteredProblems)
6571

6672
const submissionsReq = await RequestService.get<Submission[]>(`/api/course/${courseId}/assignment/${assignmentId}/submissions/`)
6773
submissionsReq.sort((a, b) => (Date.parse(b.createdAt ?? '') - Date.parse(a.createdAt ?? '')))
@@ -81,10 +87,6 @@ const AssignmentDetailPage = () => {
8187

8288
// const containerAutograder = (await RequestService.get<ContainerAutoGrader[]>(`/api/course/${courseId}/assignment/${assignmentId}/container-auto-graders`)).pop() ?? null
8389
// setContainerAutograder(containerAutograder)
84-
85-
86-
87-
8890
} catch (err: any) {
8991
setError(err)
9092
const message = "Submission past due date"//Array.isArray(err) ? err.map((e) => `${e.param} ${e.msg}`).join(', ') : err.message
@@ -118,7 +120,7 @@ const AssignmentDetailPage = () => {
118120
[key]: res
119121
};
120122
});
121-
}
123+
}
122124
else {
123125
setFormData(prevState => ({
124126
...prevState,
@@ -128,8 +130,8 @@ const AssignmentDetailPage = () => {
128130
};
129131

130132

131-
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
132-
setFile(e.target.files?.item(0))
133+
const handleFileChange = (file: File) => {
134+
setFile(file)
133135
}
134136

135137
const handleCheckboxChange = () => {
@@ -159,7 +161,7 @@ const AssignmentDetailPage = () => {
159161
submission.append('courseId', courseId)
160162
submission.append('content', JSON.stringify(contentField))
161163
submission.append('files', file)
162-
164+
163165

164166
response = await RequestService.postMultipart(`/api/course/${courseId}/assignment/${assignmentId}/submissions`, submission);
165167
} else {
@@ -191,14 +193,14 @@ const AssignmentDetailPage = () => {
191193
return false;
192194
};
193195

194-
handleFileChange;
196+
// handleFileChange;
195197

196198

197199
return (
198200
<PageWrapper>
199201
<div className={styles.header}>
200-
<h1 style={{gridColumnStart:2}}>Submit Assignment</h1>
201-
<button style={{marginLeft:'auto'}} className='btnPrimary' onClick={() => {history.push(`/course/${courseId}`)}}>Back to Course</button>
202+
<h1 style={{ gridColumnStart: 2 }}>Submit Assignment</h1>
203+
<button style={{ marginLeft: 'auto' }} className='btnPrimary' onClick={() => { history.push(`/course/${courseId}`) }}>Back to Course</button>
202204
</div>
203205

204206
<div className={styles.details}>
@@ -241,11 +243,15 @@ const AssignmentDetailPage = () => {
241243
</div>
242244

243245
<div className={styles.problems_section}>
244-
245-
{/* <div className={styles.file_upload}>
246-
<h4 className={styles.problem_header}>File Upload:</h4>
247-
<DragDropFile handleFile={(e) => {console.log(e)}} />
248-
</div> */}
246+
{/* conditionally render file upload */}
247+
{hasFileProblem && (
248+
<div className={styles.file_upload}>
249+
<h4 className={styles.problem_header}>File Upload:</h4>
250+
<DragDropFile handleFile={handleFileChange} />
251+
<span style={{margin: '15px 0', marginRight: '10px'}}>{file?.name}</span>
252+
{file && (<button className="btnDelete" onClick={() => setFile(null)}>Remove Files</button>)}
253+
</div>
254+
)}
249255

250256
<div className={styles.problems_list}>
251257
<h2>Problems</h2>
@@ -271,29 +277,29 @@ const AssignmentDetailPage = () => {
271277
</div>
272278
</div>
273279

274-
275-
{submissions.length !== 0 &&
276-
<div>
277-
<div className={styles.submissionsContainer}>
278-
{submissions.map((submission, index) => (
279-
<div className={styles.submissionCard} key={index} onClick={() => {
280-
history.push(`/course/${courseId}/assignment/${assignmentId}/submission/${submission.id}`)
281-
}}>
280+
281+
{submissions.length !== 0 &&
282+
<div>
283+
<div className={styles.submissionsContainer}>
284+
{submissions.map((submission, index) => (
285+
<div className={styles.submissionCard} key={index} onClick={() => {
286+
history.push(`/course/${courseId}/assignment/${assignmentId}/submission/${submission.id}`)
287+
}}>
282288
<div>
283289
<div className={styles.submissionHeading}>{`Submission ${submissions.length - index}`}</div>
284290
<div className={styles.submissionTime}>{`Submitted at: ${submission.createdAt && prettyPrintDateTime(submission.createdAt)}`}</div>
285291
</div>
286-
</div>
287-
))}
292+
</div>
293+
))}
288294

289-
{showScoreboard && (
290-
<div className={styles.scoreboardContainer}>
291-
<Scoreboard courseId={courseId} assignmentId={assignmentId} />
295+
{showScoreboard && (
296+
<div className={styles.scoreboardContainer}>
297+
<Scoreboard courseId={courseId} assignmentId={assignmentId} />
292298

293-
</div>
294-
)}
295-
</div>
296-
</div>}
299+
</div>
300+
)}
301+
</div>
302+
</div>}
297303

298304
</PageWrapper>
299305
)

0 commit comments

Comments
 (0)