Skip to content

Commit a13750e

Browse files
authored
Merge pull request #269 from makeopensource/102-edit-course
102 edit course
2 parents 65832ac + bfd58d7 commit a13750e

File tree

1 file changed

+87
-96
lines changed

1 file changed

+87
-96
lines changed

devU-client/src/components/pages/forms/courses/courseUpdatePage.tsx

Lines changed: 87 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,15 @@ import RequestService from 'services/request.service'
99
import { ExpressValidationError } from 'devu-shared-modules'
1010

1111
import { useActionless } from 'redux/hooks'
12-
import TextField from 'components/shared/inputs/textField'
12+
// import TextField from 'components/shared/inputs/textField'
1313
import AutomateDates from './automateDates'
1414
import { SET_ALERT } from 'redux/types/active.types'
1515
import {
1616
applyMessageToErrorFields,
1717
removeClassFromField
1818
} from "../../../../utils/textField.utils";
1919

20-
import formStyles from './coursesFormPage.scss'
21-
20+
import styles from '../assignments/assignmentUpdatePage.scss'
2221

2322
type UrlParams = {
2423
courseId: string
@@ -45,7 +44,7 @@ const CourseUpdatePage = ({ }) => {
4544
name: '',
4645
number: '',
4746
semester: 'f0000',
48-
isPublic: false
47+
isPublic: false
4948
})
5049
const [startDate, setStartDate] = useState(new Date().toISOString())
5150
const [endDate, setEndDate] = useState(new Date().toISOString())
@@ -63,11 +62,11 @@ const CourseUpdatePage = ({ }) => {
6362
name: res.name,
6463
number: res.number,
6564
semester: res.semester,
66-
isPublic: res.isPublic
65+
isPublic: res.isPublic
6766
});
6867
setStartDate(new Date(res.startDate).toISOString().split("T")[0]);
6968
setEndDate(new Date(res.endDate).toISOString().split("T")[0]);
70-
setPrivateDate(new Date(res.privateDate).toISOString().split("T")[0]);
69+
setPrivateDate(new Date(res.privateDate).toISOString().split("T")[0]);
7170
isMounted = true;
7271
});
7372
}
@@ -83,10 +82,11 @@ const CourseUpdatePage = ({ }) => {
8382
setEndDate(endDate);
8483
};
8584

86-
const handleChange = (value: string, e: React.ChangeEvent<HTMLInputElement>) => {
85+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
8786
const key = e.target.id
8887
const newInvalidFields = removeClassFromField(invalidFields, key)
8988
setInvalidFields(newInvalidFields)
89+
const value = e.target.value
9090

9191
// Update form data based on input field
9292
if (key === 'studentEmail') {
@@ -95,15 +95,15 @@ const CourseUpdatePage = ({ }) => {
9595
setFormData(prevState => ({ ...prevState, [key]: value }))
9696
}
9797
}
98-
const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
99-
setFormData(prevState => ({ ...prevState, isPublic: e.target.checked }));
100-
};
101-
const handleStartDateChange = (event: React.ChangeEvent<HTMLInputElement>) => { setStartDate(event.target.value) }
102-
const handleEndDateChange = (event: React.ChangeEvent<HTMLInputElement>) => { setEndDate(event.target.value) }
103-
104-
const handlePrivateDateChange = (event: React.ChangeEvent<HTMLInputElement>) => {
105-
setPrivateDate(event.target.value);
106-
};
98+
// const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
99+
// setFormData(prevState => ({ ...prevState, isPublic: e.target.checked }));
100+
// };
101+
// const handleStartDateChange = (event: React.ChangeEvent<HTMLInputElement>) => { setStartDate(event.target.value) }
102+
// const handleEndDateChange = (event: React.ChangeEvent<HTMLInputElement>) => { setEndDate(event.target.value) }
103+
104+
// const handlePrivateDateChange = (event: React.ChangeEvent<HTMLInputElement>) => {
105+
// setPrivateDate(event.target.value);
106+
// };
107107
const handleCourseUpdate = () => {
108108
const finalFormData = {
109109
name: formData.name,
@@ -158,7 +158,7 @@ const CourseUpdatePage = ({ }) => {
158158

159159
// Find the index of the email-related fields
160160
const emailIndex = headers.findIndex(header =>
161-
['email', 'e-mail', 'email address', 'e-mail address'].includes(header.trim())
161+
['email', 'e-mail', 'email address', 'e-mail address'].includes(header.trim().toLowerCase())
162162
);
163163

164164
if (emailIndex === -1) {
@@ -224,7 +224,7 @@ const CourseUpdatePage = ({ }) => {
224224

225225
const dropSingleStudent = async (email: string) => {
226226
const userID = await getUserId(email)
227-
227+
228228
if (userID == 0) {
229229
setAlert({ autoDelete: false, type: 'error', message: "userID not found" })
230230
return
@@ -239,121 +239,112 @@ const CourseUpdatePage = ({ }) => {
239239
}
240240
}
241241

242-
const addBulkStudent = async (emails: string[]) => {
243-
try {
244-
const reqBody = {
245-
users: emails
246-
}
247-
const res = await RequestService.post(`/api/course/${courseId}/user-courses/students/add`, reqBody)
248-
setAlert({ autoDelete: true, type: 'success', message: res.success })
249-
} catch (error: any) { // Use any if the error type isn't strictly defined
250-
const message = error.message || "An unknown error occurred"
251-
setAlert({ autoDelete: false, type: 'error', message })
252-
}
253-
}
254-
255-
const dropBulkStudent = async (emails: string[]) => {
256-
try {
257-
const reqBody = {
258-
users: emails
259-
}
260-
const res = await RequestService.post(`/api/course/${courseId}/user-courses/students/drop`, reqBody)
261-
setAlert({ autoDelete: true, type: 'success', message: res.success })
262-
} catch (error: any) { // Use any if the error type isn't strictly defined
263-
const message = error.message || "An unknown error occurred"
264-
setAlert({ autoDelete: false, type: 'error', message })
265-
}
266-
}
242+
// const addBulkStudent = async (emails: string[]) => {
243+
// try {
244+
// const reqBody = {
245+
// users: emails
246+
// }
247+
// const res = await RequestService.post(`/api/course/${courseId}/user-courses/students/add`, reqBody)
248+
// setAlert({ autoDelete: true, type: 'success', message: res.success })
249+
// } catch (error: any) { // Use any if the error type isn't strictly defined
250+
// const message = error.message || "An unknown error occurred"
251+
// setAlert({ autoDelete: false, type: 'error', message })
252+
// }
253+
// }
254+
255+
// const dropBulkStudent = async (emails: string[]) => {
256+
// try {
257+
// const reqBody = {
258+
// users: emails
259+
// }
260+
// const res = await RequestService.post(`/api/course/${courseId}/user-courses/students/drop`, reqBody)
261+
// setAlert({ autoDelete: true, type: 'success', message: res.success })
262+
// } catch (error: any) { // Use any if the error type isn't strictly defined
263+
// const message = error.message || "An unknown error occurred"
264+
// setAlert({ autoDelete: false, type: 'error', message })
265+
// }
266+
// }
267267

268268
const handleAddStudent = () => {
269269
console.log("emails: ", emails);
270-
if (emails.length<1) {
270+
if (emails.length < 1) {
271271
// if no file inputted then addSingleStudent with email
272272
console.log("adding single user")
273273
addSingleStudent(studentEmail)
274274
} else {
275275
// if file inputted then call
276276
console.log("adding multiple users")
277-
// emails.forEach(email => {
278-
// addSingleStudent(email)
279-
// })
280-
addBulkStudent(emails)
277+
emails.forEach(email => {
278+
addSingleStudent(email)
279+
})
280+
// addBulkStudent(emails)
281281
}
282282
}
283283

284284
const handleDropStudent = () => {
285-
if (emails.length<1) {
285+
if (emails.length < 1) {
286286
// if no file inputted then dropSingleStudent with email
287287
console.log("dropping single user")
288288
dropSingleStudent(studentEmail)
289289
} else {
290290
// if file inputted then for each email parsed from csv dropSingleStudent
291291
console.log("dropping multiple users")
292-
// emails.forEach(email => {
293-
// dropSingleStudent(email)
294-
// })
295-
dropBulkStudent(emails)
292+
emails.forEach(email => {
293+
dropSingleStudent(email)
294+
})
295+
// dropBulkStudent(emails)
296296
}
297297
}
298298

299299
return (
300300
<PageWrapper>
301301
<h1>Update Course Form</h1>
302-
<div className={formStyles.courseFormWrapper}>
303-
<div className={formStyles.updateDetailsForm}>
302+
<div className={styles.grid}>
303+
<div className={styles.form} style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
304304
<h2>Course Details</h2>
305-
<div className={formStyles.inputContainer}>
306-
<TextField id='name' label={"Course Name*"} onChange={handleChange} value={formData.name}
307-
invalidated={!!invalidFields.get("name")} helpText={invalidFields.get("name")}
308-
defaultValue={formData.name} />
309-
<TextField id='number' label={"Course Number*"} onChange={handleChange} value={formData.number}
310-
invalidated={!!invalidFields.get("number")} helpText={invalidFields.get("number")} />
311-
{/* <TextField id='semester' label={"Semester*"} onChange={handleChange} value={formData.semester}
312-
placeholder='e.g. f2022, w2023, s2024' invalidated={!!invalidFields.get("semester")}
313-
helpText={invalidFields.get("semester")} /> */}
305+
<div className="input-group">
306+
<label htmlFor="name" className="input-label">Course Title:</label>
307+
<input type="text" id="name" onChange={handleChange}
308+
placeholder='e.g. Web Applications' />
314309
</div>
315-
<AutomateDates onDatesChange={handleDatesChange} />
316-
<div className={formStyles.datepickerContainer}>
317-
<div className={formStyles.fieldContainer}>
318-
<label htmlFor='start-date'>Start Date *</label>
319-
<input type="date" id="start-date" value={startDate} onChange={handleStartDateChange} />
320-
</div>
321-
<div className={formStyles.fieldContainer}>
322-
<label htmlFor='end-date'>End Date *</label>
323-
<input type="date" id="end-date" value={endDate} onChange={handleEndDateChange} />
324-
</div>
325-
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column', gap: '5px' }}>
326-
<label htmlFor='private-date'>Private Date *</label>
327-
<input type="date" id="private-date" value={privateDate} onChange={handlePrivateDateChange} />
328-
</div>
329-
<div>
330-
<label>
331-
<input
332-
type="checkbox"
333-
checked={formData.isPublic}
334-
onChange={handleCheckboxChange}
335-
/>
336-
Make this course public
337-
</label>
338-
</div>
310+
<div className="input-group">
311+
<label htmlFor="number" className="input-label">Course Code:</label>
312+
<input type="text" id="number" onChange={handleChange}
313+
placeholder='e.g. CSE 312' />
339314
</div>
315+
<AutomateDates onDatesChange={handleDatesChange} />
340316
<div style={{ display: 'flex', justifyContent: 'center' }}>
341317
<button className='btnPrimary' onClick={handleCourseUpdate}>Update Course</button>
342318
</div>
343319
</div>
344-
<div className={formStyles.addDropForm}>
345-
<h2>Add/Drop Students</h2>
346-
<TextField id='studentEmail' label={"Email"} onChange={handleChange}
347-
placeholder='e.g. [email protected]' invalidated={!!invalidFields.get("studentEmail")} helpText={invalidFields.get("studentEmail")} />
320+
<div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
321+
<h2>Manage Roster</h2>
322+
{/* <TextField id='studentEmail' label={"Email"} onChange={handleChange}
323+
placeholder='e.g. [email protected]' invalidated={!!invalidFields.get("studentEmail")} helpText={invalidFields.get("studentEmail")} /> */}
324+
<div className="input-group">
325+
<label htmlFor="studentEmail" className="input-label">Student Email:</label>
326+
<input type="text" id="studentEmail" onChange={handleChange}
327+
placeholder='e.g. [email protected]' />
328+
</div>
348329
<label htmlFor="addDropFile">Add multiple students by uploading a CSV file below</label>
349-
{/* csv should be a good standard filetype */}
350330
<input type="file" accept='.csv' id="addDropFile" onChange={handleFileChange} />
351-
<div style={{ display: 'flex', justifyContent: 'center', flexDirection: 'column', marginTop: 'auto', gap: '1rem' }}>
352-
<button className='btnPrimary' onClick={handleAddStudent}>Add Student</button>
353-
<button className='btnDelete' onClick={handleDropStudent}>Drop Student</button>
331+
<button className="btnSecondary" style={{ width: 'fit-content' }} onClick={() => {
332+
setEmails([]);
333+
const fileInput = document.getElementById("addDropFile") as HTMLInputElement | null;
334+
// remove file from fileInput
335+
if (fileInput) {
336+
fileInput.value = "";
337+
}
338+
}}>Remove file</button>
339+
<span>The CSV file must have student emails in an "Email"/"E-mail"/"Email Addresses" column</span>
340+
<div style={{ display: 'flex', justifyContent: 'center', flexDirection: 'column', marginTop: '30px', gap: '1rem' }}>
341+
<button className='btnPrimary' onClick={handleAddStudent}>Add</button>
342+
<button className='btnDelete' onClick={handleDropStudent}>Drop</button>
354343
</div>
355344
</div>
356345
</div>
346+
{/* </div> */}
347+
{/* </div> */}
357348
</PageWrapper>
358349
)
359350
}

0 commit comments

Comments
 (0)