UNPKG

trc-client-core

Version:
229 lines (215 loc) 9.47 kB
import CancellationPolicy from 'trc-client-core/src/copy/_partials/CancellationPolicy.md'; import ClassBuilder from 'bd-stampy/utils/ClassBuilder'; import Col from 'trc-client-core/src/components/Col'; import Grid from 'trc-client-core/src/components/Grid'; import Icon from 'trc-client-core/src/components/Icon'; import InformationModal from 'trc-client-core/src/components/InformationModal'; import Markdown from 'trc-client-core/src/components/Markdown'; import ModalManager from 'trc-client-core/src/Modal/ModalManager'; import moment from 'moment'; import React from 'react'; import RegistrationActions from 'trc-client-core/src/course/RegistrationActions'; import Select from 'trc-client-core/src/components/Select'; import Site from 'trc-client-core/src/constants/Site'; import SubstitutionPolicy from 'trc-client-core/src/copy/_partials/SubstitutionPolicy.md'; import Table from 'bd-stampy/components/Table'; import Time from 'trc-client-core/src/components/Time'; import UserStore from 'trc-client-core/src/user/UserStore'; import {Link} from 'react-router'; function participantFrom(pp) { return function (reg) { return pp.get('participantId') === reg.get('participantId'); }; } var SoRegistrationBox = React.createClass({ displayName: 'SoRegistrationBox', mixins: [ require('trc-client-core/src/course/RegistrationMixin') ], propTypes: { type: React.PropTypes.oneOf(['registration', 'confirm']), registrations: React.PropTypes.object, candidates: React.PropTypes.object.isRequired, soData: React.PropTypes.object.isRequired }, getDefaultProps() { return { type: 'registration' }; }, getInitialState() { return { dirty: false }; }, getRefuseWaitlist() { var {course} = this.props; return (course.get('canWaitlist') === false && this.getRemainingPlaces() <= 0) }, onShowCancellationPolicy() { var concatMarkdown = CancellationPolicy.__content + '\n' + SubstitutionPolicy.__content; ModalManager.showModal(InformationModal, { title: 'Cancellation Policy', children: <Markdown context={Site[UserStore.get('site')]} html={concatMarkdown}/> }); }, onAddRegistration(ee, details) { // participantId, selectionArray if(details.valueArray && !details.valueArray.disabled) { RegistrationActions.addRegistration(details.value, this.props.soData.get('soId')); } this.makeDirty(); }, onRemoveRegistration(participantId) { RegistrationActions.updateRegistration(participantId, this.props.soData.get('soId')); this.makeDirty(); }, getRemainingPlaces() { return this.remainingPlaces(this.props.registrations, this.props.soData); }, onCheckConfirm(ee) { if (!this.state.dirty) { ee.preventDefault() } }, makeDirty() { this.setState({dirty: true}); }, render(){ return this[`render_${this.props.type}`](); }, render_confirm() { var {soData} = this.props; return ( <div className="margin-bottom3"> <h3 className="hug-top"> <Time type="short">{soData.get('soStartDate')}</Time> <span className="right">{soData.get('facility')}</span> </h3> <p>{this.renderCloseStartDateWarning()}</p> <ul> {this.renderEnrollmentList(this.props.cancellations)} {this.renderEnrollmentList(this.props.registrations)} </ul> </div> ); }, render_registration() { var {soData} = this.props; return ( <div className="SoRegistrationBox Widget padding2 margin-bottom3 clearfix"> <h2 className="hug-top"> <Time type="short">{soData.get('soStartDate')}</Time> <span className="right">{soData.get('facility')}</span> </h2> <Grid> <Col> <p> {this.renderCloseStartDateWarning()} {this.renderFullWarning()} </p> <Table modifier="data"> <tr> <td>Start Date:</td> <td><Time type="full" tz={soData.get('soTimeZone')}>{soData.get('soStartDate')}</Time></td> </tr> <tr> <td>Remaining places:</td> <td>{this.renderRemainingPlaces()}</td> </tr> <tr> <td>Facility:</td> <td>{soData.get('facilityDesc')}</td> </tr> </Table> </Col> <Col> <div> <ul> {this.renderEnrollmentList(this.props.cancellations)} {this.renderEnrollmentList(this.props.registrations)} </ul> <Select name="test" placeholder="Search for staff." disabled={this.getRefuseWaitlist()} onChange={this.onAddRegistration} options={this.renderStaffOptions()} /> </div> </Col> </Grid> <Link to={`/course/${this.props.courseCode}/confirm_registration`} className="Button right" onClick={this.onCheckConfirm} disabled={!this.state.dirty}>Confirm all Registrations</Link> </div> ); }, renderCloseStartDateWarning() { if(moment().add(21, "days").isAfter(this.props.soData.get('soStartDate'))) { return <em className="block">Course is within 21 days. Please read <a onClick={this.onShowCancellationPolicy} className="link">Cancellation Policy</a></em>; } }, renderFullWarning() { if(this.getRefuseWaitlist()) { return <em className="block">Course is currently full.</em> } if(this.getRemainingPlaces() < 1) { return <em className="block">Course is currently full. Only waitlisting available</em>; } }, renderRemainingPlaces() { return (this.getRemainingPlaces() > 0) ? this.getRemainingPlaces() : <span className="t-red">FULL</span>; }, renderEnrollmentList(list) { if(list) { return list.sortBy(reg => reg.get('status')).map((reg, key) => { var registrationStatus = this.currentStatus(reg, key, this.props.soData); var classes = new ClassBuilder('RegistrationList_item').is(true, registrationStatus); if(!registrationStatus) { classes.add('is-ENROLL'); } if(this.props.type === 'confirm') { if(registrationStatus === 'ENROLL' || registrationStatus === 'WAITLIST') { classes.add('is-old'); } } var participant = this.props.candidates.get(reg.get('participantId')); return ( <li className={classes.className} key={participant.get('participantId')}> {this.renderRegistrationStatus(reg, registrationStatus)} <span className="RegistrationList_name">{participant.get('firstName')} {participant.get('lastName')}</span> </li> ); }).toJS(); } }, renderRegistrationStatus(reg, registrationStatus) { var button = <Icon onClick={this.onRemoveRegistration.bind(null, reg.get('participantId'))} className="RegistrationList_remove" hexCode="E014" size="small" />; if(registrationStatus === 'UNENROLL' || registrationStatus === 'UNWAITLIST') { button = <span onClick={this.onRemoveRegistration.bind(null, reg.get('participantId'))} className="RegistrationList_remove">undo</span>; } var prettyTable = { ENROLL: 'Currently enrolled', UNENROLL: 'Cancellation of enrolment', UNWAITLIST: 'Cancellation of waitlist', WAITLIST: 'Currently waitlisted', WAITLISTING: 'Will be waitlisted' }; return <span className="right"> <span className="RegistrationList_status" >{prettyTable[registrationStatus] || 'New Enrolment'}</span> {(this.props.type === 'registration') ? button : null} </span>; }, renderStaffOptions() { return this.props.candidates.toList() .map((pp) => { return { value: pp.get('participantId'), label: `${pp.get('firstName')} ${pp.get('lastName')}`, disabled: this.props.allRegistrations.find(participantFrom(pp)) ? true : false }; }) .sortBy(ii => ii.label) .toJS(); } }); module.exports = SoRegistrationBox;