UNPKG

trc-client-core

Version:
347 lines (311 loc) 13.5 kB
/*global window, document*/ import React from 'react'; import ReactDOM from 'react-dom' import PureRenderMixin from 'react-addons-pure-render-mixin'; import _ from 'lodash'; import Reflux from 'reflux'; import StoreMixin from 'reflux-immutable/StoreMixin'; import Button from 'bd-stampy/components/Button'; import CourseActions from 'trc-client-core/src/course/CourseActions'; import CourseActivityHistory from 'trc-client-core/src/course/CourseActivityHistory'; import CourseStore from 'trc-client-core/src/course/CourseStore'; import Icon from 'trc-client-core/src/components/Icon'; import Loader from 'trc-client-core/src/components/Loader'; import ManagerSelectForm from 'trc-client-core/src/course/ManagerSelectForm'; import ModalView from 'trc-client-core/src/components/ModalView'; import PathwayStore from 'trc-client-core/src/course/PathwayStore'; import RegistrationActions from 'trc-client-core/src/course/RegistrationActions'; import RegistrationSingle from 'trc-client-core/src/course/RegistrationSingle'; import RegistrationStore from 'trc-client-core/src/course/RegistrationStore'; import SodataStore from 'trc-client-core/src/sodata/SodataStore'; import UserStore from 'trc-client-core/src/user/UserStore'; import Video from 'trc-client-core/src/components/Video'; var CourseActivityModal = React.createClass({ displayName: 'CourseActivityModal', mixins: [ Reflux.listenTo(SodataStore, 'onStoreChange'), Reflux.listenTo(CourseStore, 'onStoreChange'), Reflux.listenTo(RegistrationStore, 'onStoreChange'), PureRenderMixin, StoreMixin ], propTypes: { courseCode: React.PropTypes.string.isRequired, participantId: React.PropTypes.string.isRequired, actionable: React.PropTypes.bool }, getDefaultProps() { return { actionable: true }; }, getStoreState() { return { course: CourseStore.get('course'), soData: SodataStore.get('soData'), fetchingParticipation: CourseStore.get('fetchingParticipation'), fetchingCourse: CourseStore.get('fetchingCourse'), participation: CourseStore.get('participation') }; }, getInitialState () { return { selectSoItem: null, soId: null, managers: null, videoButtonDisabled: true }; }, componentDidMount() { var query = { courseCode: this.props.courseCode, participantId: this.props.participantId }; CourseActions.fetchCourse(query.courseCode); CourseActions.fetchParticipation(query); }, onRequestChange(e, details) { this.setState(details); }, onRequestEvaluation() { ReactDOM.findDOMNode(this.refs.form).submit(); }, onRequestSubmit() { if(UserStore.is('ROLE_MANAGER')) { RegistrationActions.sendRegistrationData([{ participantId: this.props.participantId, soId: this.state.soId, courseCode: this.props.courseCode, operation: 'ENROLL', regId: null, operator: UserStore.get('username'), message: null }]); } else { RegistrationActions.requestTraining(this.state.manager, this.state.soId); } this.onClose(); }, // // Product Pathway modal specifics // TODO: remove to a more generic completion endpoint // startThenCompleteCourse() { PathwayStore .startComplete({ participantId: this.props.participantId, courseCode: this.props.courseCode }) .then(this.fauxCompletion); }, fauxCompletion() { switch (this.getCourseType()){ case 'DOCUMENT': var documentURL = this.state.course.getIn(['documentTag','documents',0,'url']) window.location = `upload/view?objectKey=${documentURL}`; break; case 'VIDEO': window.location.reload(); break; } }, onClose() { if(this.props.onClose) { return this.props.onClose(); } // // TODO: SOOPER HACK. Remove along with backbone ReactDOM.unmountComponentAtNode(document.getElementById('Modal_content')); }, onVideoFinish(){ this.setState({videoButtonDisabled: false}); }, getCourseType() { // Documents and Videos are not poropertly // supported through course.type // var type = this.state.course.get('type'); if (this.state.course.get('documentTag')) { type = 'DOCUMENT'; } if (this.state.course.get('videoTag')) { type = 'VIDEO'; } return type; }, render() { var {course, participation} = this.state; if(!course || !participation) { return <ModalView title="Loading..." loading={false}> <Loader></Loader> </ModalView> } var title = ( <span>{participation.get('firstName')} {participation.get('lastName')}&apos;s Training Activity</span> ); return ( <ModalView title={title} loading={this.state.fetchingCourse || this.state.fetchingParticipation}> <div className="margin-bottom2"> <h3 className="hug-top"> <Icon modifier="inline" hexCode={course.get('courseIcon')}></Icon> {course.get('workshopName')} </h3> <CourseActivityHistory {...this.state} courseType={this.getCourseType()}/> </div> {this.renderModalBody()} <div className="ButtonBar right margin-top"> {this.renderCourseDetailsButton()} <a className="Button Button-grey" onClick={this.onClose} data-js="close">Close</a> {this.renderMainActionButton()} </div> </ModalView> ); }, renderModalBody() { return this[`render_${this.getCourseType()}`](); }, render_E_LEARNING() { return this.renderCourseStatusText(this.props.process, { action: 'Go To Module' }); }, render_LOCAL_QUIZ() { return this.renderCourseStatusText(this.props.process, { action: 'Go To Exam' }); }, render_EVALUATION() { var courseCode = this.state.course.get('courseCode'); var managerForm = <ManagerSelectForm name="managers" />; var copy = <p>In order to become certified a Manager must complete a Service Advisor Performance Evaluation and deem you to be Competent. Please select a Manager from below to be notified of your desire to be evaluated.</p>; if (courseCode === 'BT_EVAL' || courseCode === 'PT_EVAL') { copy = <p>In order to become certified you need a TMCA Staff Member or a Dealer Manager to complete your evaluation and deem you to be competent. Please click request to notify a TMCA Staff Member to complete your evaluation.</p>; managerForm = null; } return <div> {copy} <form ref="form" action="/careerPathway/managers" method="post"> <input type="hidden" name="courseCode" value={courseCode} /> <input type="hidden" name="careerPlanId" value={this.props.pathwayId} /> {managerForm} </form> </div>; }, render_FACE_TO_FACE() { var message; switch(this.state.course.get('stream')) { case 'PRO': message = 'You have not yet successfully completed the courses from the previous stage, however, to continue to complete this course or module, click the Course Details button below.'; break; case 'TECH': message = `Unfortunately, ${this.state.participation.get('firstName')} is not yet eligible to be enrolled into this course as they have not completed the pre-requisites.`; break; } if(!this.state.participation.get('eligible')) { return <div className="InfoBox">{message}</div>; } var currentEnrollment = this.state.participation.get('history').find(item => item.get('process') === 'ENROLL'); return ( <div> <RegistrationSingle {...this.props} onChange={this.onRequestChange} currentEnrollment={currentEnrollment}/> </div> ); }, render_DOCUMENT() {}, render_ACHIEVEMENT() {}, render_CERTIFICATION() {}, render_VIDEO() { var view; var {participation} = this.state; if(participation.get('status')) { view = `${participation.get('firstName')} completed this video. Please feel free to watch again to refresh your product knowledge.`; } else { view = 'Please watch the above video content. Once finished you will be able to Complete and return to your Product Plan.'; } return ( <div> <Video id={this.state.course.get('videoTag').get('videos').get(0).get('url')} onVideoFinish={this.onVideoFinish}/> <div className="margin-top">{view}</div> </div> ); }, renderCourseStatusText(process, termOverride) { var copy; var {participation} = this.state; var participationHistory = participation.get('history'); var firstName = participation.get('firstName'); var terms = _.defaults(termOverride, { action: 'Go To Course' }); if(participationHistory.get('0')){ process = participationHistory.getIn(['0','process']); } switch(process) { case 'ATTENDED': case 'COMPLETED': copy = <p>{firstName} completed this course. If you wish to do a refresh, please {terms.action}.</p>; break; case 'CREDIT': copy = <p>{firstName} was credited for this course. If you wish to do a refresh, please {terms.action}.</p>; break; case 'IN_PROGRESS': copy = <p>The TRC recognises that {firstName} has launched this module previously. <br/>If the module was completed on the LMS, completion may take up to 36 hours to be displayed. To reattempt the module, please click {terms.action}.</p>; break; case 'FAILED': copy = <p>Our records indicate {firstName} failed this course. To retry the module please {terms.action}.</p>; break; default: copy = <p>Our records indicate {firstName} has not yet completed this course. Please {terms.action} to complete the course.</p>; } return <div>{copy}</div>; }, renderCourseDetailsButton() { if(this.state.course.get('viewableInList')) { return <a className="Button Button-clear" href={`/#/course/${this.state.course.get('courseCode')}`} onClick={this.onClose}>Course Details</a>; } }, renderMainActionButton() { var {participation, course} = this.state; var button = null; var buttonProps = { className: 'Button', disabled: !participation.get('eligible') }; if(!this.props.actionable) { return null; } switch (this.getCourseType()) { case 'FACE_TO_FACE': if(UserStore.is('ROLE_MANAGER')) { button = <Button {...buttonProps} onClick={this.onRequestSubmit} disabled={!this.state.soId}>Enrol</Button>; } else { button = <Button {...buttonProps} onClick={this.onRequestSubmit} disabled={!(this.state.soId && this.state.manager)}>Request</Button>; } break; case 'E_LEARNING': button = <a {...buttonProps} href={`/#/course/${course.get('courseCode')}/launch`} onClick={this.onClose} data-js="close">Go To Module</a>; break; case 'LOCAL_QUIZ': var href = `/careerPathway/${this.props.pathwayId}/assessment/quiz/${course.get('courseCode')}?participantId=${this.props.participantId}`; if(!this.props.pathwayId || !course.get('courseCode') || participation.get('eligible') === false) { button = <Button {...buttonProps} disabled={true}>Go To Exam</Button>; } else { button = <a {...buttonProps} href={href}>Go To Exam</a>; } break; case 'EVALUATION': button = <a {...buttonProps} onClick={this.onRequestEvaluation}>Request</a>; break; case 'DOCUMENT': if(this.state.course.getIn(['documentTag','documents']).size !== 0){ button = <a {...buttonProps} onClick={this.startThenCompleteCourse}>View</a>; } break; case 'VIDEO': button = <Button {...buttonProps} disabled={this.state.videoButtonDisabled} onClick={this.startThenCompleteCourse}>Complete</Button>; break; } return button; } }); module.exports = CourseActivityModal;