jam-cloud/web/app/assets/javascripts/react-components/AccountOnboarderScreen.js.j...

428 lines
16 KiB
CoffeeScript
Raw Permalink Normal View History

2018-01-23 03:50:45 +00:00
context = window
rest = context.JK.Rest()
logger = context.JK.logger
AppStore = context.AppStore
UserStore = context.UserStore
profileUtils = context.JK.ProfileUtils
@AccountOnboarderScreen = React.createClass({
mixins: [
Reflux.listenTo(AppStore, "onAppInit"),
Reflux.listenTo(UserStore, "onUserChanged")
]
shownOnce: false
screenVisible: false
updates: []
onAppInit: (@app) ->
@app.bindScreen('account/onboarder', {beforeShow: @beforeShow, afterShow: @afterShow, beforeHide: @beforeHide})
onRetailerChanged: (retailerState) ->
@setState(retailerState)
onUserChanged: (userState) ->
@getOnboardings(userState?.user)
@setState({user: userState?.user})
componentDidMount: () ->
@root = $(@getDOMNode())
componentDidUpdate: () ->
datePicked = @datePicked.bind(this)
@sessionDate = @root.find('.date-picker')
@sessionDate.each(() ->
$this = $(this)
id = $this.attr('data-id')
day = $this.attr('data-date')
$this.datepicker({
dateFormat: "D M d yy",
onSelect: ((e, inst) ->
datePicked(id, 'onboarding_test_session_at')
)
})
# initialize day
if(day)
$this.datepicker("setDate", new Date(day))
)
toggleDate: (dateText, inst) ->
console.log("THIS", this)
console.log("IDID ID #{$(this).attr('data-id')}")
'onboarding_test_session_at'
beforeHide: (e) ->
@screenVisible = false
return true
beforeShow: (e) ->
LocationActions.load()
getOnboardings: (user) ->
if user?.id? && @screenVisible
@setState({fetchingOnboardings: true})
rest.listOnboardings(context.JK.currentUserId).done((onboardings) =>
@setState({onboardings: onboardings, fetchingOnboardings: false})
)
.fail(() =>
@setState({fetchingOnboardings: false})
@app.layout.notify({
title: "onboarding list failure",
text: "Unable to list out your onboarders. Please contact support@jamkazam.com"
})
)
2018-03-13 02:53:24 +00:00
2018-01-23 03:50:45 +00:00
afterShow: (e) ->
@screenVisible = true
logger.debug("AccountOnboardingScreen: afterShow")
logger.debug("after show", @state.user)
@getOnboardings(@state.user)
getInitialState: () ->
{
onboardings: [],
user: null,
updating: false
}
onCancel: (e) ->
e.preventDefault()
context.location.href = '/client#/account'
onUpdate: (e) ->
if e?
e.preventDefault()
if this.state.updating
return
if @updates.length == 0
return
update = @updates.pop()
@setState({updating: true})
rest.updateOnboarding(update).done((response) => @onUpdateDone(response)).fail((jqXHR) => @onUpdateFail(jqXHR))
updateRow: (onboarding) ->
for match in this.state.onboardings
if match.id == onboarding.id
$.extend(match, onboarding)
break
this.setState({onboardings: this.state.onboardings})
onUpdateDone: (response) ->
this.setState({updating: false})
@updateRow(response)
if @updates.length > 0
@onUpdate()
onUpdateFail: (jqXHR) ->
this.setState({updating: false})
@app.layout.notify({
title: "update failure",
text: "Unable to update user. Please let us know which user and field you can not update."
})
if @updates.length > 0
@onUpdate()
updateField: (id, field, e) ->
if(e)
e.preventDefault()
console.log("Update Field Called for ", field)
$target = $(e.target)
console.log("TARGET", $target)
value = true
if $target.is('select')
value = $target.val()
options = {id: id}
options[field] = value
2018-03-03 21:39:55 +00:00
@postUpdate(field, value)
2018-01-23 03:50:45 +00:00
@queueUpdate(options)
2018-03-03 21:39:55 +00:00
postUpdate: (field, value) ->
if field == 'onboarding_onboarded_at'
console.log("onboarding onboarded at set")
context.JK.Banner.showAlert({title: "One Last Thing", html: "Please send this student Email #5 right now.<br/><br/>This is a critical email, and if you don't send it now, you'll forget. Thanks!"});
2018-01-23 03:50:45 +00:00
queueUpdate: (update) ->
@updates.push(update)
@onUpdate()
createLinkField: (id, onboarding, field, display, timeLabel = null) ->
if onboarding[field]
email = `<span style={{whiteSpace:'no-wrap'}}>{timeLabel} {onboarding[field]}</span>`
else
email = `<a href='#' className="daystamper" onClick={this.updateField.bind(this, id, field)}>{display}</a>`
email
showLostBanner: (id, field) ->
lostHtml = 'Please choose a reason why the user was lost:<br/><br/>' +
'<select><option value=""></option><option value="Lost Interest">Lost Interest</option><option value="No Win/Mac Computer">No Win/Mac Computer</option><option value="No Broadband Internet">No Broadband Internet</option><option value="No Webcam">No Webcam</option><option value="Bad Internet">Bad Internet</option><option value="Setup Wizard Failure">Setup Wizard Failure</option><option value="No Audio Stream In Session">No Audio Stream In Session</option><option value="No Video Stream In Session">No Video Stream In Session</option><option value="Other">Other</option></select>'
$item = context.JK.Banner.showAlert(
{buttons: [{name: 'CANCEL', click: () -> console.log('cancel clicked')}], html: lostHtml});
$item.find('select').change((e)=> @updateField(id, field, e); context.JK.Banner.hide())
showEscalationBanner: (id, field) ->
lostHtml = 'Please choose a reason why the user needs escalating:<br/><br/>' +
'<select><option value=""></option><option value="No Audio Stream In Session">No Audio Stream In Session</option><option value="No Video Stream In Session">No Video Stream In Session</option><option value="Setup Wizard Failure">Setup Wizard Failure</option><option value="Other">Other</option></select>'
$item = context.JK.Banner.showAlert(
{buttons: [{name: 'CANCEL', click: () -> console.log('cancel clicked')}], html: lostHtml});
$item.find('select').change((e)=> @updateField(id, field, e); context.JK.Banner.hide())
createLostField: (id, onboarding) ->
field = 'onboarding_lost_reason'
if onboarding[field]
field = `<span>{
onboarding[field]
}</span>`
else
field = `<a href='#' className="daystamper" onClick={this.showLostBanner.bind(this, id, field)}>lost student</a>`
field
createEscalatedField: (id, onboarding) ->
field = 'onboarding_escalation_reason'
if onboarding[field]
field = `<span>{
onboarding[field]
}</span>`
else
field = `<a href='#' className="daystamper" onClick={this.showEscalationBanner.bind(this, id, field)}>escalate
student</a>`
field
createOnboardingField: (onboarding) ->
@createLinkField(onboarding.id, onboarding, 'onboarding_onboarded_at', 'onboarded successfully')
watchTextArea: (id, field, e) ->
$text = $(e.target)
if @textTimeout
clearTimeout(@textTimeout)
@textTimeout = null
@textTimeout = setTimeout(() =>
data = {id: id}
data[field] = $text.val()
@queueUpdate(data)
@textTimeout = null
, 3000)
datePicked: (id, field) ->
$tr = @root.find("tr[data-id='" + id + "']")
picker = $tr.find(".date-picker")
hour = $tr.find('.hour').val()
minute = $tr.find('.minute').val()
am_pm = $tr.find('.am_pm').val()
if hour? and hour != ''
hour = new Number(hour)
if am_pm == 'PM'
hour += 12
else
hour = null
if minute? and minute != ''
minute = new Number(minute)
else
minute = null
date = picker.datepicker("getDate")
if date?
date.setHours(hour)
date.setMinutes(minute)
data = {id: id}
data[field] = date.toString()
@queueUpdate(data)
mainContent: () ->
cancelClasses = {"button-orange": true, "update": true}
onboardings = []
if @state.fetchingOnboardings
onboardings.push(`<tr>
<td colSpan="6" style={{textAlign:'center'}}>FETCHING STUDENTS</td>
</tr>`)
else if @state.onboardings.length > 0
for onboarding in @state.onboardings
hours = []
for hour in ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']
if hour == '12'
key = '00'
else
key = hour
2018-03-13 02:53:24 +00:00
hours.push(`<option key={key} value={new Number(key)}>{hour}</option>`)
2018-01-23 03:50:45 +00:00
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>`]
email1 = @createLinkField(onboarding.id, onboarding, 'onboarding_email_1_sent_at', 'sent email 1', 'email 1:')
email2 = @createLinkField(onboarding.id, onboarding, 'onboarding_email_2_sent_at', 'sent email 2', 'email 2:')
email3 = @createLinkField(onboarding.id, onboarding, 'onboarding_email_3_sent_at', 'sent email 3', 'email 3:')
email4 = @createLinkField(onboarding.id, onboarding, 'onboarding_email_4_sent_at', 'sent email 4', 'email 4:')
email5 = @createLinkField(onboarding.id, onboarding, 'onboarding_email_5_sent_at', 'sent email 5', 'email 5:')
scheduledSession = @createLinkField(onboarding.id, onboarding, 'onboarding_test_session_scheduled_at',
'scheduled session', 'scheduled session:')
sessionOutcomes = ['', "Successful", "Setup Wizard Failure", "No Audio Stream in Session",
"No Video Stream In Session", "Other"]
sessionOutcomesJSX = []
for sessionOutcome in sessionOutcomes
sessionOutcomesJSX.push(`<option key={sessionOutcome} value={sessionOutcome}>{sessionOutcome}</option>`)
selectSessionOutcome =
`<select value={onboarding.onboarding_test_session_outcome}
onChange={this.updateField.bind(this, onboarding.id, 'onboarding_test_session_outcome')}>{sessionOutcomesJSX}</select>`
session_at = onboarding.onboarding_test_session_at
amOrPm = 'AM'
currentHours = '01'
currentMinutes = '00'
if session_at
sessionTime = new Date(session_at)
session_at = sessionTime.toLocaleDateString()
currentHours = sessionTime.getHours()
if sessionTime.getHours() > 11
amOrPm = 'PM'
currentHours -= 12
currentMinutes = sessionTime.getMinutes()
active = onboarding.onboarding_status == 'Emailed' || onboarding.onboarding_status == 'Assigned'
if active
activeClass = 'active-row'
else
activeClass = 'inactive-row'
columns = []
if active
columns.push(`<td key="1">
<div className="info-unit">{email1}</div>
<div className="info-unit">{email2}</div>
<div className="info-unit">{email3}</div>
<div className="info-unit">{email4}</div>
<div className="info-unit">{email5}</div>
</td>`)
columns.push(`<td key="2">
<div className="info-unit" style={{textAlign:'center'}}>{scheduledSession}</div>
<div className="info-unit">
<label style={{marginBottom:'5px'}}>Test Session Date:</label> <input data-id={onboarding.id}
className="date-picker"
name="session-date" type="text"
data-date={session_at}></input>
<label style={{marginTop:'10px'}}>Test Session Time:</label>
<select value={currentHours}
onChange={this.datePicked.bind(this, onboarding.id, 'onboarding_test_session_at')}
className="hour">{hours}</select> : <select value={currentMinutes}
onChange={this.datePicked.bind(this, onboarding.id, 'onboarding_test_session_at')}
className="minute">{minutes}</select>
<select value={amOrPm} style={{marginLeft:'13px'}}
onChange={this.datePicked.bind(this, onboarding.id, 'onboarding_test_session_at')}
className="am_pm">{am_pm}</select>
</div>
<div className="info-unit"><label style={{marginTop:'10px'}}>Session Outcome:</label>
{selectSessionOutcome}</div>
</td>`)
columns.push(`<td key="3">
<div className="info-unit"
style={{marginBottom:'20px'}}>{this.createLostField(onboarding.id, onboarding)}</div>
<div className="info-unit">{this.createEscalatedField(onboarding.id, onboarding)}</div>
</td>`)
columns.push(`<td key="4">
<div className="info-unit">{this.createOnboardingField(onboarding)}</div>
</td>`)
else
columns.push(`<td colSpan="4" style={{textAlign:'center', fontSize:'18px'}}>
<span>{onboarding.onboarding_status}</span><br/><br/><span style={{fontSize:'12px', marginLeft:'10px'}}>This student will drop off your list now next time you visit this page.</span>
</td>`)
onboarding = `<tr className={activeClass} key={onboarding.id} data-id={onboarding.id}>
<td>
<div className="info-unit">Name: {onboarding.name}</div>
<div className="info-unit">Email: {onboarding.email}</div>
<div className="info-unit" style={{marginTop:'20px'}}>Assigned
on {onboarding.onboarder_assigned_at}</div>
</td>
{columns}
<td>
<div className="info-unit">
<textarea className="info-unit"
onChange={this.watchTextArea.bind(this, onboarding.id, 'onboarding_onboarder_notes')}>{onboarding.onboarding_onboarder_notes}</textarea>
</div>
</td>
</tr>`
onboardings.push(onboarding)
else
onboardings.push(`<tr>
<td colSpan="6" style={{textAlign:'center'}}>NO STUDENTS ASSIGNED</td>
</tr>`)
`<div className="account-block info-block">
<div>
<div className="instructions">
Manage the users here that you are responsible for onboarding.<br/><br/>
All links in the table below, when clicked, will immediately mark that item as done. For example, once
you send your first email to the user, click the <b>sent email 1</b> link.<br/><br/>
All other fields will automatically save as you use them, such as the <b>Session Outcome</b> dropdown,
and the <b>Notes</b> text box.
</div>
<table className="jamtable">
<thead>
<tr>
<th>User</th>
<th>Email</th>
<th>Test Session</th>
<th>Problems</th>
<th>Onboarded</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
{onboardings}
</tbody>
</table>
</div>
<div className="actions">
<a className={classNames(cancelClasses)} onClick={this.onCancel}>BACK</a>
</div>
</div>`
render: () ->
mainContent = @mainContent()
`<div className="content-body-scroller">
<div className="profile-header profile-head">
<div className="clearall"></div>
</div>
<div className="profile-body">
<div className="profile-wrapper">
<div className="main-content">
{mainContent}
<br />
</div>
</div>
</div>
</div>`
})