-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #178 from makeopensource/130-ability-to-make-cours…
…e-public 130 ability to make course public
- Loading branch information
Showing
9 changed files
with
158 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,16 +55,23 @@ async function SendPOST(path: string, requestBody: string | FormData, requesterE | |
return responseBody | ||
} | ||
|
||
async function CreateCourse(name: string, number: string, semester: string) { | ||
async function CreateCourse( | ||
name: string, | ||
number: string, | ||
semester: string, | ||
isPublic: boolean | ||
) { | ||
const courseData = { | ||
name: name, | ||
semester: semester, | ||
number: number, | ||
startDate: '2024-01-24T00:00:00-0500', | ||
endDate: '2024-05-10T23:59:59-0500', | ||
} | ||
console.log('Creating course: ', courseData.name) | ||
return await SendPOST('/courses/instructor', JSON.stringify(courseData), 'admin') | ||
name: name, | ||
semester: semester, | ||
number: number, | ||
startDate: '2024-01-24T00:00:00-0500', | ||
endDate: '2024-05-10T23:59:59-0500', | ||
is_public: isPublic // Include the public property | ||
}; | ||
|
||
console.log('Creating course: ', courseData.name); | ||
return await SendPOST('/courses/instructor', JSON.stringify(courseData), 'admin'); | ||
} | ||
|
||
async function joinCourse(courseId: number, userId: number, role: string) { | ||
|
@@ -208,8 +215,8 @@ async function runCourseAndSubmission() { | |
const jones = await fetchToken('[email protected]', 'jones') | ||
|
||
//Create courses | ||
const courseId1 = (await CreateCourse('Testing Course Name1', 'CSE101', 's2024')).id | ||
const courseId2 = (await CreateCourse('Testing Course Name2', 'CSE102', 's2024')).id | ||
const courseId1 = (await CreateCourse('Testing Course Name1', 'CSE101', 's2024',true)).id | ||
const courseId2 = (await CreateCourse('Testing Course Name2', 'CSE102', 's2024',true)).id | ||
|
||
//Enroll students | ||
await joinCourse(courseId1, billy, 'student') | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
147 changes: 88 additions & 59 deletions
147
devU-client/src/components/pages/forms/courses/coursesFormPage.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,102 +1,131 @@ | ||
import React, { useState } from 'react' | ||
import { useHistory } from 'react-router-dom' | ||
import { ExpressValidationError } from 'devu-shared-modules' | ||
|
||
import PageWrapper from 'components/shared/layouts/pageWrapper' | ||
|
||
import RequestService from 'services/request.service' | ||
|
||
import { useActionless } from 'redux/hooks' | ||
import TextField from 'components/shared/inputs/textField' | ||
import { SET_ALERT } from 'redux/types/active.types' | ||
import formStyles from './coursesFormPage.scss' | ||
import { applyMessageToErrorFields, removeClassFromField } from "../../../../utils/textField.utils"; | ||
|
||
import React, { useState } from 'react'; | ||
import { useHistory } from 'react-router-dom'; | ||
import RequestService from 'services/request.service'; | ||
import { useActionless } from 'redux/hooks'; | ||
import TextField from 'components/shared/inputs/textField'; | ||
import { SET_ALERT } from 'redux/types/active.types'; | ||
import formStyles from './coursesFormPage.scss'; | ||
import PageWrapper from 'components/shared/layouts/pageWrapper'; | ||
|
||
const EditCourseFormPage = () => { | ||
const [setAlert] = useActionless(SET_ALERT) | ||
const [setAlert] = useActionless(SET_ALERT); | ||
const history = useHistory(); | ||
|
||
const [formData, setFormData] = useState({ | ||
name: '', | ||
number: '', | ||
semester: '', | ||
}) | ||
isPublic: false | ||
}); | ||
|
||
const [startDate, setStartDate] = useState(new Date().toISOString().split("T")[0]) | ||
const [endDate, setEndDate] = useState(new Date().toISOString().split("T")[0]) | ||
const [invalidFields, setInvalidFields] = useState(new Map<string, string>()) | ||
const [startDate, setStartDate] = useState(new Date().toISOString().split("T")[0]); | ||
const [endDate, setEndDate] = useState(new Date().toISOString().split("T")[0]); | ||
const [privateDate, setPrivateDate] = useState(new Date().toISOString().split("T")[0]); | ||
|
||
const handleChange = (value: String, e: React.ChangeEvent<HTMLInputElement>) => { | ||
const key = e.target.id | ||
setFormData(prevState => ({ ...prevState, [key]: value })) | ||
const handleChange = (value: string, e: React.ChangeEvent<HTMLInputElement>) => { | ||
const key = e.target.id; | ||
setFormData(prevState => ({ ...prevState, [key]: value })); | ||
}; | ||
|
||
const newInvalidFields = removeClassFromField(invalidFields, key) | ||
setInvalidFields(newInvalidFields) | ||
} | ||
const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||
setFormData(prevState => ({ ...prevState, isPublic: e.target.checked })); | ||
}; | ||
|
||
const handleStartDateChange = (event: React.ChangeEvent<HTMLInputElement>) => { setStartDate(event.target.value) } | ||
const handleEndDateChange = (event: React.ChangeEvent<HTMLInputElement>) => { setEndDate(event.target.value) } | ||
const handleStartDateChange = (event: React.ChangeEvent<HTMLInputElement>) => { | ||
setStartDate(event.target.value); | ||
}; | ||
|
||
const handleEndDateChange = (event: React.ChangeEvent<HTMLInputElement>) => { | ||
setEndDate(event.target.value); | ||
}; | ||
|
||
const handlePrivateDateChange = (event: React.ChangeEvent<HTMLInputElement>) => { | ||
setPrivateDate(event.target.value); | ||
}; | ||
|
||
const formatDateForSubmission = (date: string) => { | ||
return new Date(date).toISOString(); | ||
}; | ||
|
||
const isFormValid = () => { | ||
return formData.name && formData.number && formData.semester && startDate && endDate; | ||
}; | ||
|
||
const handleSubmit = () => { | ||
const finalFormData = { | ||
name: formData.name, | ||
number: formData.number, | ||
semester: formData.semester, | ||
startDate: startDate + "T16:02:41.849Z", | ||
endDate: endDate + "T16:02:41.849Z", | ||
} | ||
startDate: formatDateForSubmission(startDate), | ||
endDate: formatDateForSubmission(endDate), | ||
isPublic: formData.isPublic, | ||
privateDate: formatDateForSubmission(privateDate) | ||
}; | ||
|
||
RequestService.post('/api/courses/instructor', finalFormData) | ||
.then(() => { | ||
setAlert({ autoDelete: true, type: 'success', message: 'Course Added' }) | ||
history.goBack() | ||
setAlert({ autoDelete: true, type: 'success', message: 'Course Added' }); | ||
history.goBack(); | ||
}) | ||
.catch((err: ExpressValidationError[] | Error) => { | ||
const message = Array.isArray(err) ? err.map((e) => `${e.param} ${e.msg}`).join(', ') : err.message | ||
|
||
const newFields = new Map<string, string>() | ||
Array.isArray(err) ? err.map((e) => applyMessageToErrorFields(newFields, e.param, e.msg)) : newFields | ||
setInvalidFields(newFields); | ||
setAlert({ autoDelete: false, type: 'error', message }) | ||
}) | ||
.finally(() => { | ||
}) | ||
} | ||
.catch((err) => { | ||
setAlert({ autoDelete: false, type: 'error', message: err.message }); | ||
}); | ||
}; | ||
|
||
return ( | ||
<PageWrapper> | ||
<h1>Create Course</h1> | ||
|
||
<div className={formStyles.courseFormWrapper}> | ||
<div className={formStyles.createDetailsForm}> | ||
<TextField id='name' label={"Course Name*"} onChange={handleChange} value={formData.name} | ||
invalidated={!!invalidFields.get("name")} helpText={invalidFields.get("name")} /> | ||
<TextField id='number' label={"Course Number*"} onChange={handleChange} value={formData.number} | ||
invalidated={!!invalidFields.get("number")} helpText={invalidFields.get("number")} /> | ||
<TextField id='semester' label={"Semester*"} onChange={handleChange} value={formData.semester} | ||
placeholder='Ex. f2022, w2023, s2024' invalidated={!!invalidFields.get("semester")} | ||
helpText={invalidFields.get("semester")} /> | ||
<TextField | ||
id='name' | ||
label={"Course Name*"} | ||
onChange={handleChange} | ||
value={formData.name} | ||
/> | ||
<TextField | ||
id='number' | ||
label={"Course Number*"} | ||
onChange={handleChange} | ||
value={formData.number} | ||
/> | ||
<TextField | ||
id='semester' | ||
label={"Semester*"} | ||
onChange={handleChange} | ||
value={formData.semester} | ||
/> | ||
<div className={formStyles.datepickerContainer}> | ||
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column', gap: '5px' }}> | ||
<div> | ||
<label htmlFor='start-date'>Start Date *</label> | ||
<input type="date" id="start-date" value={startDate} onChange={handleStartDateChange} /> | ||
</div> | ||
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column', gap: '5px' }}> | ||
<div> | ||
<label htmlFor='end-date'>End Date *</label> | ||
<input type="date" id="end-date" value={endDate} onChange={handleEndDateChange} /> | ||
</div> | ||
<div> | ||
<label htmlFor='private-date'>Private Date *</label> | ||
<input type="date" id="private-date" value={privateDate} onChange={handlePrivateDateChange} /> | ||
</div> | ||
</div> | ||
<div> | ||
<label> | ||
<input | ||
type="checkbox" | ||
checked={formData.isPublic} | ||
onChange={handleCheckboxChange} | ||
/> | ||
Make this course public | ||
</label> | ||
</div> | ||
<div style={{ display: 'flex', justifyContent: 'center' }}> | ||
<button className='btnPrimary' onClick={handleSubmit}>Create Course</button> | ||
<button className='btnPrimary' onClick={handleSubmit} disabled={!isFormValid()}>Create Course</button> | ||
</div> | ||
</div> | ||
</div> | ||
</PageWrapper> | ||
) | ||
|
||
} | ||
|
||
); | ||
}; | ||
|
||
export default EditCourseFormPage | ||
export default EditCourseFormPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters