307 lines
11 KiB
CoffeeScript
307 lines
11 KiB
CoffeeScript
@LessonBookingDecision = React.createClass({
|
|
|
|
#slot.creatorRole
|
|
#slot.slotTime
|
|
|
|
# props.initial
|
|
# props.counter
|
|
# props.slots
|
|
# props.is_recurring
|
|
# props.slot_decision
|
|
# props.otherRole
|
|
# props.cancelErrors
|
|
# props.counterErrors
|
|
|
|
mixins: [
|
|
ICheckMixin,
|
|
]
|
|
|
|
propTypes: {
|
|
onSlotDecision: React.PropTypes.func.isRequired
|
|
onUserCancel: React.PropTypes.func.isRequired
|
|
onUserDecision: React.PropTypes.func.isRequired
|
|
onUpdateAllDecision: React.PropTypes.func.isRequired
|
|
}
|
|
|
|
getInitialState: () ->
|
|
{
|
|
slot_decision: null
|
|
}
|
|
|
|
componentWillMount: () ->
|
|
@days = []
|
|
@days.push(`<option key='choose' value=''>Choose a day of the week...</option>`)
|
|
@days.push(`<option key='0' value="0">Sunday</option>`)
|
|
@days.push(`<option key='1' value="1">Monday</option>`)
|
|
@days.push(`<option key='2' value="2">Tuesday</option>`)
|
|
@days.push(`<option key='3' value="3">Wednesday</option>`)
|
|
@days.push(`<option key='4' value="4">Thursday</option>`)
|
|
@days.push(`<option key='5' value="5">Friday</option>`)
|
|
@days.push(`<option key='6' value="6">Saturday</option>`)
|
|
|
|
@hours = []
|
|
for hour in ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']
|
|
if hour == '12'
|
|
key = '00'
|
|
else
|
|
key = hour
|
|
@hours.push(`<option key={key} value={key}>{hour}</option>`)
|
|
|
|
@minutes = []
|
|
for minute in ['00', '15', '30', '45']
|
|
@minutes.push(`<option key={minute} value={minute}>{minute}</option>`)
|
|
|
|
@am_pm = [`<option key="AM" value="AM">AM</option>`, `<option key="PM" value="PM">PM</option>`]
|
|
|
|
componentDidMount: () ->
|
|
@checkboxes = [{selector: 'input.slot-decision', stateKey: 'slot-decision'}, {selector: 'input.update-all', propsKey: 'update_all'}]
|
|
@root = $(@getDOMNode())
|
|
@iCheckify()
|
|
@slotDate = @root.find('.date-picker')
|
|
@slotDate.datepicker({
|
|
dateFormat: "D M d yy",
|
|
onSelect: ((e) => @toggleDate(e))
|
|
})
|
|
|
|
componentDidUpdate: () ->
|
|
@iCheckify()
|
|
@slotDate = @root.find('.date-picker')
|
|
@slotDate.datepicker({
|
|
dateFormat: "D M d yy",
|
|
onSelect: ((e) => @toggleDate(e))
|
|
})
|
|
|
|
toggleDate: (e) ->
|
|
|
|
componentWillReceiveProps: (nextProps) ->
|
|
if @onlyOption()
|
|
console.log("setting it counter")
|
|
# if this isn't a counter situation, then there is no 'Accept their time', so there should only be one radio button, and we'll select that value already
|
|
@setState({"slot-decision": "counter"})
|
|
|
|
checkboxChanged: (e) ->
|
|
|
|
|
|
name = $(e.target).attr('name')
|
|
|
|
if name == 'slot-decision'
|
|
value = $(e.target).val()
|
|
|
|
logger.debug("LessonBookingDecision: slot-decision made with value: " + value)
|
|
|
|
@setState({"slot-decision": value})
|
|
@props.onSlotDecision({slot_decision: value})
|
|
else if name == 'update-all'
|
|
checked = $(e.target).is(':checked')
|
|
logger.debug("LessonBookingDecision: update-all changed: " + checked)
|
|
@props.onUpdateAllDecision({update_all: checked})
|
|
else
|
|
throw "checkbox changed with unknown name #{name}"
|
|
|
|
|
|
onUserDecision: (e) ->
|
|
e.preventDefault()
|
|
|
|
if this.props.disabled
|
|
return
|
|
|
|
this.props.onUserDecision(this.state.slot_decision)
|
|
|
|
onUserCancel: (e) ->
|
|
e.preventDefault()
|
|
|
|
if this.props.disabled
|
|
return
|
|
|
|
this.props.onUserCancel()
|
|
|
|
dayOfWeek: (slot) ->
|
|
switch slot.day_of_week
|
|
when 0 then "Sunday"
|
|
when 1 then "Monday"
|
|
when 2 then "Tuesday"
|
|
when 3 then "Wednesday"
|
|
when 4 then "Thursday"
|
|
when 5 then "Friday"
|
|
when 6 then "Saturday"
|
|
|
|
slotLabelText: (index, slot) ->
|
|
if @props.counter
|
|
"Accept #{slot.creatorRoleRelative} proposed day/time"
|
|
else
|
|
if index == 0
|
|
"Accept #{slot.creatorRoleRelative} preferred day/time"
|
|
else
|
|
"Accept #{slot.creatorRoleRelative} secondary day/time"
|
|
|
|
showDeclineVerb: () ->
|
|
this.props.initial && this.props.otherRole == 'student'
|
|
|
|
nullOp: ()->
|
|
|
|
onlyOption: () ->
|
|
# (!this.props.initial && this.props.selfLastToAct ) || !(this.props.counter && !this.props.selfLastToAct)
|
|
!@multipleOptions()
|
|
|
|
multipleOptions: () ->
|
|
if this.props.initial
|
|
if this.props.noSlots
|
|
false
|
|
else
|
|
!(!this.props.counter && this.props.selfLastToAct)
|
|
else if this.props.counter
|
|
!this.props.selfLastToAct
|
|
else
|
|
false
|
|
|
|
render: () ->
|
|
|
|
#showUpdateAll = !this.props.initial
|
|
|
|
if (!this.props.initial && !this.props.counter) || this.props.selfLastToAct
|
|
userPromptHeader = `<h3>Would you like to update this lesson?</h3>`
|
|
messagePromptHeader = `<h3>Send message to {this.props.otherRole} with your update.</h3>`
|
|
else
|
|
userPromptHeader = `<h3>How do you want to handle this request?</h3>`
|
|
messagePromptHeader = `<h3>Send message to {this.props.otherRole} with your response.</h3>`
|
|
if this.props.slot_decision == 'counter'
|
|
if this.props.is_recurring && this.props.update_all
|
|
actionBtnText = "PROPOSE TIME FOR ALL LESSONS"
|
|
else
|
|
if @props.noSlots
|
|
actionBtnText = 'PROPOSE TIME'
|
|
else
|
|
actionBtnText = "PROPOSE ALTERNATE TIME"
|
|
|
|
else if this.props.slot_decision == 'decline'
|
|
|
|
if @showDeclineVerb()
|
|
verb = "DECLINE"
|
|
else
|
|
verb = "CANCEL"
|
|
|
|
if this.props.update_all
|
|
actionBtnText = "#{verb} ALL LESSONS"
|
|
else
|
|
actionBtnText = "#{verb} LESSON"
|
|
else if this.props.initial
|
|
actionBtnText = "ACCEPT & SCHEDULE LESSON"
|
|
else
|
|
actionBtnText = "ACCEPT & UPDATE LESSON"
|
|
|
|
counterClasses={field: true, 'slot-decision-field': true, error: this.props.counterErrors?, counterSelected: this.props.slot_decision == 'counter', onlyOption: @onlyOption()}
|
|
|
|
|
|
if this.props.counterErrors?
|
|
errorText = window.JK.reactErrors(this.props.counterErrors, {day_of_week: 'Day' })
|
|
|
|
if this.props.is_recurring && this.props.update_all
|
|
|
|
slotAltPrompt = `<div className="slot-alt-prompt">
|
|
<span className="alt-date-block">
|
|
<span className="alt-date">Day:</span>
|
|
<select disabled={this.props.disabled} className="day_of_week" data-slot={i}>{this.days}</select>
|
|
</span>
|
|
<span className="alt-time-block">
|
|
<span className="alt-time">Time:</span>
|
|
<select className="hour" defaultValue="06" disabled={this.props.disabled}>{this.hours}</select> : <select disabled={this.props.disabled} className="minute">{this.minutes}</select>
|
|
<select disabled={this.props.disabled} className="am_pm" defaultValue="PM">{this.am_pm}</select>
|
|
<br/>
|
|
<span>* Time will be local to {window.JK.currentTimezone()}</span>
|
|
{errorText}
|
|
</span>
|
|
|
|
</div>`
|
|
#if @props.update_all
|
|
# updateAllField =
|
|
# `<div className="field update-all-field">
|
|
# <input disabled={this.props.disabled} className="update-all" type="checkbox" name="update-all" readyOnly="true" onChange={this.nullOp} checked={this.props.update_all} /><label>Update all lessons</label>
|
|
# </div>`
|
|
updateAllField = null
|
|
|
|
else
|
|
slotAltPrompt = `<div className="slot-alt-prompt">
|
|
<span className="alt-date-block">
|
|
<span className="alt-date">Date:</span>
|
|
<input className="date-picker" name="alt-date-input" type="text" data-slot={i}></input>
|
|
</span>
|
|
<span className="alt-time-block">
|
|
<span className="alt-time">Time:</span>
|
|
<select className="hour" defaultValue="06" disabled={this.props.disabled}>{this.hours}</select> : <select disabled={this.props.disabled} className="minute">{this.minutes}</select>
|
|
<select disabled={this.props.disabled} className="am_pm" defaultValue="PM">{this.am_pm}</select>
|
|
<br/>
|
|
<span>*Time will be local to {window.JK.currentTimezone()}</span>
|
|
{errorText}
|
|
</span>
|
|
</div>`
|
|
|
|
if @showDeclineVerb()
|
|
declineVerb = "Decline"
|
|
else
|
|
declineVerb = "Cancel"
|
|
|
|
cancelClasses = {cancel: true, "button-grey": true, disabled: this.props.disabled}
|
|
scheduleClasses = {schedule: true, "button-orange": true, disabled: this.props.disabled}
|
|
slots = []
|
|
|
|
if !(this.props.counter && this.props.selfLastToAct)
|
|
if this.props.noSlots
|
|
proposeAltLabelText = 'Propose a day/time'
|
|
else
|
|
proposeAltLabelText = "Propose alternate day/time"
|
|
for slot, i in @props.slots
|
|
|
|
if this.props.is_recurring
|
|
slotDetail = `<div className="slot-detail">Each {slot.slotTime}</div>`
|
|
else
|
|
slotDetail = `<div className="slot-detail">{slot.slotTime}</div>`
|
|
|
|
slots.push(`<div key={slot.id} data-slot-id={slot.id} className="field slot-decision-field">
|
|
<div className="label-area">
|
|
<input disabled={this.props.disabled} className="slot-decision" type="radio" name="slot-decision"
|
|
value={slot.id} readyOnly={true} defaultChecked={slot.id == this.props.slot_decision} /><label>{this.slotLabelText(i, slot)}</label>
|
|
</div>
|
|
{slotDetail}
|
|
</div>`)
|
|
else
|
|
if this.props.noSlots
|
|
proposeAltLabelText = 'Propose a day/time'
|
|
else
|
|
proposeAltLabelText = "Propose new alternate day/time"
|
|
|
|
# if you have issued a counter, you should be able to withdraw it
|
|
# TODO
|
|
|
|
#cancelField = `<div className="field slot-decision-field">
|
|
# <input disabled={this.props.disabled} className="slot-decision" type="radio" name="slot-decision" value="decline" readyOnly={true} defaultChecked={this.props.slot_decision == 'decline'} /><label>{declineVerb} lesson
|
|
# request</label>
|
|
#</div>`
|
|
cancelField = null
|
|
|
|
`<div className="row">
|
|
<div className="column column-left">
|
|
{userPromptHeader}
|
|
|
|
<div className="slot-decision slot-1">
|
|
{slots}
|
|
<div className={classNames(counterClasses)}>
|
|
<div className="label-area">
|
|
<input disabled={this.props.disabled} className="slot-decision" type="radio" readyOnly={true} name="slot-decision" value="counter" defaultChecked={this.props.slot_decision == 'counter'}/>
|
|
<label>{proposeAltLabelText}</label>
|
|
</div>
|
|
{slotAltPrompt}
|
|
</div>
|
|
{cancelField}
|
|
{updateAllField}
|
|
</div>
|
|
</div>
|
|
<div className="column column-right">
|
|
{messagePromptHeader}
|
|
<textarea className="message" name="message" disabled={this.props.disabled}></textarea>
|
|
<div className="actions">
|
|
<a className={classNames(cancelClasses)} onClick={this.onUserCancel}>CANCEL</a>
|
|
<a className={classNames(scheduleClasses)} onClick={this.onUserDecision}>{actionBtnText}</a>
|
|
</div>
|
|
</div>
|
|
</div>`
|
|
}) |