@@ -9,16 +9,15 @@ import RequestService from 'services/request.service'
9
9
import { ExpressValidationError } from 'devu-shared-modules'
10
10
11
11
import { useActionless } from 'redux/hooks'
12
- import TextField from 'components/shared/inputs/textField'
12
+ // import TextField from 'components/shared/inputs/textField'
13
13
import AutomateDates from './automateDates'
14
14
import { SET_ALERT } from 'redux/types/active.types'
15
15
import {
16
16
applyMessageToErrorFields ,
17
17
removeClassFromField
18
18
} from "../../../../utils/textField.utils" ;
19
19
20
- import formStyles from './coursesFormPage.scss'
21
-
20
+ import styles from '../assignments/assignmentUpdatePage.scss'
22
21
23
22
type UrlParams = {
24
23
courseId : string
@@ -45,7 +44,7 @@ const CourseUpdatePage = ({ }) => {
45
44
name : '' ,
46
45
number : '' ,
47
46
semester : 'f0000' ,
48
- isPublic : false
47
+ isPublic : false
49
48
} )
50
49
const [ startDate , setStartDate ] = useState ( new Date ( ) . toISOString ( ) )
51
50
const [ endDate , setEndDate ] = useState ( new Date ( ) . toISOString ( ) )
@@ -63,11 +62,11 @@ const CourseUpdatePage = ({ }) => {
63
62
name : res . name ,
64
63
number : res . number ,
65
64
semester : res . semester ,
66
- isPublic : res . isPublic
65
+ isPublic : res . isPublic
67
66
} ) ;
68
67
setStartDate ( new Date ( res . startDate ) . toISOString ( ) . split ( "T" ) [ 0 ] ) ;
69
68
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 ] ) ;
71
70
isMounted = true ;
72
71
} ) ;
73
72
}
@@ -83,10 +82,11 @@ const CourseUpdatePage = ({ }) => {
83
82
setEndDate ( endDate ) ;
84
83
} ;
85
84
86
- const handleChange = ( value : string , e : React . ChangeEvent < HTMLInputElement > ) => {
85
+ const handleChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
87
86
const key = e . target . id
88
87
const newInvalidFields = removeClassFromField ( invalidFields , key )
89
88
setInvalidFields ( newInvalidFields )
89
+ const value = e . target . value
90
90
91
91
// Update form data based on input field
92
92
if ( key === 'studentEmail' ) {
@@ -95,15 +95,15 @@ const CourseUpdatePage = ({ }) => {
95
95
setFormData ( prevState => ( { ...prevState , [ key ] : value } ) )
96
96
}
97
97
}
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
+ // };
107
107
const handleCourseUpdate = ( ) => {
108
108
const finalFormData = {
109
109
name : formData . name ,
@@ -158,7 +158,7 @@ const CourseUpdatePage = ({ }) => {
158
158
159
159
// Find the index of the email-related fields
160
160
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 ( ) )
162
162
) ;
163
163
164
164
if ( emailIndex === - 1 ) {
@@ -224,7 +224,7 @@ const CourseUpdatePage = ({ }) => {
224
224
225
225
const dropSingleStudent = async ( email : string ) => {
226
226
const userID = await getUserId ( email )
227
-
227
+
228
228
if ( userID == 0 ) {
229
229
setAlert ( { autoDelete : false , type : 'error' , message : "userID not found" } )
230
230
return
@@ -239,121 +239,112 @@ const CourseUpdatePage = ({ }) => {
239
239
}
240
240
}
241
241
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
+ // }
267
267
268
268
const handleAddStudent = ( ) => {
269
269
console . log ( "emails: " , emails ) ;
270
- if ( emails . length < 1 ) {
270
+ if ( emails . length < 1 ) {
271
271
// if no file inputted then addSingleStudent with email
272
272
console . log ( "adding single user" )
273
273
addSingleStudent ( studentEmail )
274
274
} else {
275
275
// if file inputted then call
276
276
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)
281
281
}
282
282
}
283
283
284
284
const handleDropStudent = ( ) => {
285
- if ( emails . length < 1 ) {
285
+ if ( emails . length < 1 ) {
286
286
// if no file inputted then dropSingleStudent with email
287
287
console . log ( "dropping single user" )
288
288
dropSingleStudent ( studentEmail )
289
289
} else {
290
290
// if file inputted then for each email parsed from csv dropSingleStudent
291
291
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)
296
296
}
297
297
}
298
298
299
299
return (
300
300
< PageWrapper >
301
301
< 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' } } >
304
304
< 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' />
314
309
</ 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' />
339
314
</ div >
315
+ < AutomateDates onDatesChange = { handleDatesChange } />
340
316
< div style = { { display : 'flex' , justifyContent : 'center' } } >
341
317
< button className = 'btnPrimary' onClick = { handleCourseUpdate } > Update Course</ button >
342
318
</ div >
343
319
</ 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 >
348
329
< label htmlFor = "addDropFile" > Add multiple students by uploading a CSV file below</ label >
349
- { /* csv should be a good standard filetype */ }
350
330
< 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 >
354
343
</ div >
355
344
</ div >
356
345
</ div >
346
+ { /* </div> */ }
347
+ { /* </div> */ }
357
348
</ PageWrapper >
358
349
)
359
350
}
0 commit comments