forked from WikiEducationFoundation/WikiEduDashboard
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e10ea2e
commit 0d4621e
Showing
1 changed file
with
123 additions
and
119 deletions.
There are no files selected for viewing
242 changes: 123 additions & 119 deletions
242
app/assets/javascripts/components/wizard/form_panel.jsx
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,144 +1,148 @@ | ||
import React from 'react'; | ||
import createReactClass from 'create-react-class'; | ||
import React, { useRef, useCallback } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import Panel from './panel.jsx'; | ||
import DatePicker from '../common/date_picker.jsx'; | ||
import Calendar from '../common/calendar.jsx'; | ||
import CourseDateUtils from '../../utils/course_date_utils.js'; | ||
|
||
const FormPanel = createReactClass({ | ||
displayName: 'FormPanel', | ||
|
||
propTypes: { | ||
course: PropTypes.object.isRequired, | ||
shouldShowSteps: PropTypes.bool, | ||
updateCourse: PropTypes.func.isRequired, | ||
isValid: PropTypes.bool.isRequired | ||
}, | ||
// Utility function for safe property access and transformation | ||
function __guard__(value, transform) { | ||
return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined; | ||
} | ||
|
||
setAnyDatesSelected(bool) { | ||
return this.setState({ anyDatesSelected: bool }); | ||
}, | ||
const FormPanel = ({ course, shouldShowSteps, updateCourse, isValid, persistCourse, noDates }) => { | ||
const noDatesRef = useRef(null); | ||
|
||
setBlackoutDatesSelected(bool) { | ||
return this.setState({ blackoutDatesSelected: bool }); | ||
}, | ||
setNoBlackoutDatesChecked() { | ||
const { checked } = this.noDates; | ||
const toPass = this.props.course; | ||
toPass.no_day_exceptions = checked; | ||
return this.props.updateCourse(toPass); | ||
}, | ||
const setNoBlackoutDatesChecked = useCallback(() => { | ||
const { checked } = noDatesRef.current; | ||
const toPass = { ...course, no_day_exceptions: checked }; | ||
updateCourse(toPass); | ||
}, [course, updateCourse]); | ||
|
||
updateCourseDates(valueKey, value) { | ||
const updatedCourse = CourseDateUtils.updateCourseDates(this.props.course, valueKey, value); | ||
return this.props.updateCourse(updatedCourse); | ||
}, | ||
const updateCourseDates = useCallback((valueKey, value) => { | ||
const updatedCourse = CourseDateUtils.updateCourseDates(course, valueKey, value); | ||
updateCourse(updatedCourse); | ||
}, [course, updateCourse]); | ||
|
||
saveCourse() { | ||
if (this.props.isValid) { | ||
this.props.persistCourse(this.props.course.slug); | ||
const saveCourse = useCallback(() => { | ||
if (isValid) { | ||
persistCourse(course.slug); | ||
return true; | ||
} | ||
alert(I18n.t('error.form_errors')); | ||
return false; | ||
}, | ||
nextEnabled() { | ||
if (__guard__(this.props.course.weekdays, x => x.indexOf(1)) >= 0 && (__guard__(this.props.course.day_exceptions, x1 => x1.length) > 0 || this.props.course.no_day_exceptions)) { | ||
return true; | ||
} | ||
return false; | ||
}, | ||
}, [isValid, persistCourse, course.slug]); | ||
|
||
render() { | ||
const dateProps = CourseDateUtils.dateProps(this.props.course); | ||
const nextEnabled = useCallback(() => { | ||
return (__guard__(course.weekdays, x => x.indexOf(1)) >= 0) | ||
&& (__guard__(course.day_exceptions, x => x.length) > 0 || course.no_day_exceptions); | ||
}, [course.weekdays, course.day_exceptions, course.no_day_exceptions]); | ||
|
||
const step1 = this.props.shouldShowSteps | ||
? <h2><span>1.</span><small> Confirm the course’s start and end dates.</small></h2> | ||
: <p>Confirm the course’s start and end dates.</p>; | ||
const dateProps = CourseDateUtils.dateProps(course); | ||
|
||
const rawOptions = ( | ||
<div> | ||
<div className="course-dates__step"> | ||
{step1} | ||
<div className="vertical-form full-width"> | ||
<DatePicker | ||
onChange={this.updateCourseDates} | ||
value={this.props.course.start} | ||
value_key="start" | ||
editable={true} | ||
validation={CourseDateUtils.isDateValid} | ||
label="Course Start" | ||
/> | ||
<DatePicker | ||
onChange={this.updateCourseDates} | ||
value={this.props.course.end} | ||
value_key="end" | ||
editable={true} | ||
validation={CourseDateUtils.isDateValid} | ||
label="Course End" | ||
date_props={dateProps.end} | ||
enabled={Boolean(this.props.course.start)} | ||
/> | ||
</div> | ||
</div> | ||
<hr /> | ||
<div className="course-dates__step"> | ||
<p>{I18n.t('wizard.assignment_description')}</p> | ||
<div className="vertical-form full-width"> | ||
<DatePicker | ||
onChange={this.updateCourseDates} | ||
value={this.props.course.timeline_start} | ||
value_key="timeline_start" | ||
editable={true} | ||
validation={CourseDateUtils.isDateValid} | ||
label={I18n.t('courses.assignment_start')} | ||
date_props={dateProps.timeline_start} | ||
/> | ||
<DatePicker | ||
onChange={this.updateCourseDates} | ||
value={this.props.course.timeline_end} | ||
value_key="timeline_end" | ||
editable={true} | ||
validation={CourseDateUtils.isDateValid} | ||
label={I18n.t('courses.assignment_end')} | ||
date_props={dateProps.timeline_end} | ||
enabled={Boolean(this.props.course.start)} | ||
/> | ||
</div> | ||
const step1 = shouldShowSteps | ||
? <h2><span>1.</span><small>{I18n.t('wizard.confirm_dates')}</small></h2> | ||
: <p>{I18n.t('wizard.confirm_dates')}</p>; | ||
|
||
const rawOptions = ( | ||
<div> | ||
<div className="course-dates__step"> | ||
{step1} | ||
<div className="vertical-form full-width"> | ||
<DatePicker | ||
onChange={updateCourseDates} | ||
value={course.start} | ||
value_key="start" | ||
editable={true} | ||
validation={CourseDateUtils.isDateValid} | ||
label="Course Start" | ||
/> | ||
<DatePicker | ||
onChange={updateCourseDates} | ||
value={course.end} | ||
value_key="end" | ||
editable={true} | ||
validation={CourseDateUtils.isDateValid} | ||
label="Course End" | ||
date_props={dateProps.end} | ||
enabled={Boolean(course.start)} | ||
/> | ||
</div> | ||
<hr /> | ||
<div className="wizard__form course-dates course-dates__step"> | ||
<Calendar | ||
course={this.props.course} | ||
</div> | ||
<hr /> | ||
<div className="course-dates__step"> | ||
<p>{I18n.t('wizard.assignment_description')}</p> | ||
<div className="vertical-form full-width"> | ||
<DatePicker | ||
onChange={updateCourseDates} | ||
value={course.timeline_start} | ||
value_key="timeline_start" | ||
editable={true} | ||
validation={CourseDateUtils.isDateValid} | ||
label="Assignment Start" | ||
date_props={dateProps.timeline_start} | ||
/> | ||
<DatePicker | ||
onChange={updateCourseDates} | ||
value={course.timeline_end} | ||
value_key="timeline_end" | ||
editable={true} | ||
save={true} | ||
setAnyDatesSelected={this.setAnyDatesSelected} | ||
setBlackoutDatesSelected={this.setBlackoutDatesSelected} | ||
calendarInstructions={I18n.t('wizard.calendar_instructions')} | ||
updateCourse={this.props.updateCourse} | ||
validation={CourseDateUtils.isDateValid} | ||
label="Assignment End" | ||
date_props={dateProps.timeline_end} | ||
enabled={Boolean(course.start)} | ||
/> | ||
<label> I have no class holidays | ||
<input type="checkbox" onChange={this.setNoBlackoutDatesChecked} ref={(checkbox) => { this.noDates = checkbox; }} /> | ||
</label> | ||
</div> | ||
</div> | ||
); | ||
<hr /> | ||
<div className="wizard_form course-dates course-dates_step"> | ||
<Calendar | ||
course={course} | ||
editable={true} | ||
save={true} | ||
setAnyDatesSelected={() => {}} | ||
setBlackoutDatesSelected={() => {}} | ||
calendarInstructions={I18n.t('wizard.calendar_instructions')} | ||
updateCourse={updateCourse} | ||
/> | ||
<label> | ||
{I18n.t('I have no class holidays')} | ||
<input | ||
type="checkbox" | ||
onChange={setNoBlackoutDatesChecked} | ||
ref={(checkbox) => { | ||
noDatesRef.current = checkbox; | ||
if (noDates) { | ||
noDates.current = checkbox; | ||
} | ||
}} | ||
/> | ||
</label> | ||
</div> | ||
</div> | ||
); | ||
|
||
return ( | ||
<Panel | ||
{...this.props} | ||
raw_options={rawOptions} | ||
nextEnabled={this.nextEnabled} | ||
saveCourse={this.saveCourse} | ||
helperText = "Select meeting days and holiday dates, then continue." | ||
/> | ||
); | ||
} | ||
}); | ||
return ( | ||
<Panel | ||
course={course} | ||
shouldShowSteps={shouldShowSteps} | ||
updateCourse={updateCourse} | ||
isValid={isValid} | ||
raw_options={rawOptions} | ||
nextEnabled={nextEnabled} | ||
saveCourse={saveCourse} | ||
helperText={I18n.t('wizard.select_dates_and_continue')} | ||
/> | ||
); | ||
}; | ||
|
||
export default FormPanel; | ||
FormPanel.propTypes = { | ||
course: PropTypes.object.isRequired, | ||
shouldShowSteps: PropTypes.bool, | ||
updateCourse: PropTypes.func.isRequired, | ||
isValid: PropTypes.bool.isRequired, | ||
persistCourse: PropTypes.func.isRequired, | ||
noDates: PropTypes.shape({ current: PropTypes.object }) | ||
}; | ||
|
||
function __guard__(value, transform) { | ||
return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined; | ||
} | ||
export default FormPanel; |