Skip to content

Commit 5af7147

Browse files
authored
Merge pull request #229 from makeopensource/77-category-dropdowns
77 - Added editable dropdowns for assignment creation/editing
2 parents e226fce + d0568b6 commit 5af7147

21 files changed

Lines changed: 382 additions & 170 deletions

devU-client/src/assets/global.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@
165165

166166
background-color: var(--background);
167167
color: var(--text-color);
168-
168+
169169
--background: white;
170170
--text-color: black;
171171
--text-color-secondary: #363636;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const AssignmentProblemListItem = ({problem, handleChange, disabled}: Props) =>
4040
if (!meta || !meta.type){
4141
return (
4242
<div className={styles.problem}>
43+
<span>Metadata missing, error!</span>
4344
</div>)
4445
}
4546

devU-client/src/components/listItems/simpleAssignmentListItem.scss

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,13 @@
4949
flex-direction: column;
5050

5151

52-
border-radius: 0.6rem;
53-
transition: background-color 0.2s linear;
52+
transition: all 0.2s ease;
5453

5554
// color: $primary;
5655

5756
color: $text-color;
58-
// &:hover,
59-
// &:focus {
60-
// background: $list-simple-item-background-hover;
61-
// }
57+
&:hover,
58+
&:focus {
59+
background-color: $list-item-background-hover;
60+
}
6261
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ type Props = {
1010
}
1111

1212
const SimpleAssignmentListItem = ({assignment}: Props) => (
13+
<div onClick={(e) => (e.stopPropagation())}> {/*Wrapped in div so that clicking this item does not propogate to course cards onClick and take you to course detail page */}
1314
<ListItemWrapper to={`/course/${assignment.courseId}/assignment/${assignment.id}`} tag={assignment.name}
1415
className={styles.title} tagStyle={styles.tag} containerStyle={styles.container}>
1516
<div className={styles.subText}>{assignment.name}</div>
@@ -18,9 +19,8 @@ const SimpleAssignmentListItem = ({assignment}: Props) => (
1819
<span>&nbsp;|&nbsp;</span>
1920
<span style={{fontWeight:'700'}}>End:&nbsp;</span>{wordPrintDate(assignment.endDate)}
2021
</div>
21-
22-
2322
</ListItemWrapper>
23+
</div>
2424
)
2525

2626

devU-client/src/components/listItems/userCourseListItem.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
font-weight: 600;
77
margin: 0;
88
padding: 15px;
9-
/* Add padding to the text inside the name block */
109
background: $primary;
1110
width: 100%;
1211
text-align: center;
@@ -33,12 +32,12 @@
3332
text-overflow: ellipsis;
3433
overflow-wrap: break-word;
3534
border-bottom: 1px solid #ddd;
36-
3735
}
3836

3937
.Buttons {
4038
display: flex;
4139
justify-content: center;
40+
cursor: default;
4241
margin-top: auto;
4342
padding: 15px;
4443
gap: 20px;

devU-client/src/components/pages/courses/courseDetailPage.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@
9191
margin-bottom: 20px;
9292
}
9393

94+
95+
9496
.class_title{
9597
grid-column-start: 2;
9698
padding: 0 20px;

devU-client/src/components/pages/courses/courseDetailPage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const CourseDetailPage = () => {
101101
</div>
102102
</div>
103103
<div>
104-
<h3>Course Links</h3>
104+
<h3 className={styles.meta_header}>Course Links</h3>
105105
<div className={styles.buttons_container}>
106106
<button className='btnSecondary' onClick={() => {
107107
role.isInstructor() ? history.push(`/course/${courseId}/gradebook/instructor`) :
@@ -112,7 +112,7 @@ const CourseDetailPage = () => {
112112
<AddAssignmentModal open={openModal} onClose={handleCloseModal} />
113113
</div>
114114
</div>
115-
<div className={styles.subheader}><h3>Assignments</h3>
115+
<div className={styles.subheader}><h3 className={styles.meta_header}>Assignments</h3>
116116
{role.isInstructor() &&(
117117
<button className='btnPrimary' id={styles.parallel_button} onClick={() => {
118118
setOpenModal(true)}}>Add Assignment

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
@import 'variables';
22

33

4-
5-
64
h2 {
75
text-align: center;
86
}
@@ -16,6 +14,10 @@ p {
1614
padding: 0 100px;
1715
}
1816

17+
.input {
18+
font-size: 14px;
19+
}
20+
1921
.flex {
2022
display: flex;
2123
justify-content: space-between;

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

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import React, { useState } from 'react'
1+
import React, { useState, useEffect } from 'react'
22
// import { useHistory } from 'react-router-dom'
3-
import { ExpressValidationError } from 'devu-shared-modules'
3+
import { ExpressValidationError, Assignment } from 'devu-shared-modules'
44
import 'react-datepicker/dist/react-datepicker.css'
55
// import PageWrapper from 'components/shared/layouts/pageWrapper'
66

@@ -9,6 +9,8 @@ import { useActionless } from 'redux/hooks'
99
// import TextField from 'components/shared/inputs/textField'
1010
// import Button from '../../../shared/inputs/button'
1111
// import DragDropFile from 'components/utils/dragDropFile'
12+
import { Option } from 'components/shared/inputs/dropdown'
13+
1214

1315
import { SET_ALERT } from 'redux/types/active.types'
1416

@@ -17,6 +19,7 @@ import { useParams } from 'react-router-dom'
1719

1820
import formStyles from './assignmentFormPage.scss'
1921
import Modal from 'components/shared/layouts/modal'
22+
import TextDropdown from 'components/shared/inputs/textDropDown'
2023

2124
interface Props {
2225
open: boolean;
@@ -29,6 +32,8 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
2932
const [endDate, setEndDate] = useState('')
3033
const [dueDate, setDueDate] = useState('')
3134
const [startDate, setStartDate] = useState('')
35+
const [categoryOptions, setAllCategoryOptions] = useState<Option<String>[]>([])
36+
const [assignments, setAssignments] = useState<Assignment[]>([])
3237

3338
const [formData, setFormData] = useState({
3439
courseId: courseId,
@@ -47,6 +52,20 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
4752
setFormData(prevState => ({ ...prevState, [key]: value }))
4853
}
4954

55+
const handleCategoryChange = (value: Option<String>) => {
56+
setFormData(prevState => ({ ...prevState, categoryName: value.label }))
57+
};
58+
59+
const handleCategoryCreate = (value: string) => {
60+
const newOption : Option = {value: value, label: value}
61+
setAllCategoryOptions(prevState => {
62+
const newArr: Option<String>[] = (prevState);
63+
newArr.push(newOption);
64+
return newArr;
65+
})
66+
setFormData(prevState => ({ ...prevState, categoryName: value }))
67+
};
68+
5069
const handleStartDateChange = (e: React.ChangeEvent<HTMLInputElement>) => { setStartDate(e.target.value) }
5170
const handleEndDateChange = (e: React.ChangeEvent<HTMLInputElement>) => { setEndDate(e.target.value) }
5271
const handleDueDateChange = (e: React.ChangeEvent<HTMLInputElement>) => { setDueDate(e.target.value) }
@@ -99,36 +118,54 @@ const AddAssignmentModal = ({ open, onClose }: Props) => {
99118
.finally(() => {
100119

101120
})
102-
103121
}
104122

123+
useEffect(() => {RequestService.get(`/api/course/${courseId}/assignments`).then((res) => { setAssignments(res) })}, [formData])
124+
125+
126+
useEffect(() => {
127+
const categories = [...new Set(assignments.map(a => a.categoryName))];
128+
const options = categories.map((category) => ({
129+
value: category,
130+
label: category
131+
}));
132+
133+
setAllCategoryOptions(options);
134+
}, [assignments])
105135

106136
return (
107137
<Modal title="Add Assignment" buttonAction={handleSubmit} open={open} onClose={onClose}>
108138
<div className="input-group">
109139
<label htmlFor="categoryName" className="input-label">Assignment Category:</label>
110-
<input type="text" id="categoryName" onChange={handleChange}
111-
placeholder='Type assignment category' />
140+
<TextDropdown
141+
onChange={handleCategoryChange}
142+
onCreate={handleCategoryCreate}
143+
options={categoryOptions}
144+
custom={{control: () => ({border:'none', padding:'3px 0'}),
145+
placeholder: () => ({color: '#555555'}),
146+
input: () => ({fontSize: '14px'}),
147+
singleValue: () => ({fontSize: '14px'})}}
148+
value={formData.categoryName ? {value: formData.categoryName, label: formData.categoryName} : undefined}/>
112149
</div>
113150
<div className="input-group">
114151
<label htmlFor="name" className="input-label">Assignment Name:</label>
115-
<input type="text" id="name" onChange={handleChange}
152+
<input type="text" id="name" onChange={handleChange} className={formStyles.input}
116153
placeholder='e.g. PA3'/>
117154
</div>
118155
<div className="input-group">
119156
<label htmlFor="description" className="input-label">Description: <span>(optional)</span></label>
120-
<textarea rows={4} id="description" onChange={handleChange}
157+
<textarea rows={4} id="description" onChange={handleChange} className={formStyles.input}
121158
placeholder='Provide an optional assignment description'/>
122159
</div>
123160
<div className='input-subgroup-2col'>
124161
<div className="input-group">
125162
<label htmlFor="maxSubmissions" className="input-label">Maximum Submissions:</label>
126-
<input type="number" id="maxSubmissions" onChange={handleChange}
163+
<input type="number" id="maxSubmissions" onChange={handleChange} className={formStyles.input}
127164
placeholder='e.g. 1' value={formData.maxSubmissions} min="0"/>
128165
</div>
129166
<div className="input-group">
130167
<label htmlFor="maxFileSize" className="input-label">Maximum File Size (KB):</label>
131-
<input type="number" id="maxFileSize" onChange={handleChange}
168+
<input type="number" id="maxFileSize" onChange={handleChange} className={formStyles.input}
132169
placeholder='e.g. 100' value={formData.maxFileSize} min="0"/>
133170
</div>
134171
</div>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
.textField {
4040
align-items: center;
4141
margin-bottom: 0;
42-
background: none;
4342
border: 2px solid #ccc;
43+
width: inherit;
4444
}
4545

4646
.textFieldHeader{
@@ -155,7 +155,7 @@ input[type='datetime-local'] {
155155
font-weight: 700;
156156
font-size: 14px;
157157
color: #fff;
158-
padding: 5px 15px;
158+
padding: 3px 14px;
159159
font-style: normal;
160160
max-width: fit-content;
161161
transition: all 0.2s ease;

0 commit comments

Comments
 (0)