280 lines
10 KiB
CoffeeScript
280 lines
10 KiB
CoffeeScript
context = window
|
|
rest = context.JK.Rest()
|
|
TeacherSearchStore = @TeacherSearchStore
|
|
TeacherSearchActions = @TeacherSearchActions
|
|
TeacherSearchResultsActions = @TeacherSearchResultsActions
|
|
LocationActions = @LocationActions
|
|
InstrumentStore = @InstrumentStore
|
|
SubjectStore = @SubjectStore
|
|
GenreStore = @GenreStore
|
|
LanguageStore = @LanguageStore
|
|
ProfileActions = @ProfileActions
|
|
|
|
@TeacherSearchScreen = React.createClass({
|
|
|
|
# Reflux.listenTo(@TeacherSearchStore, "onTeacherSearchChanged"),
|
|
|
|
mixins: [Reflux.listenTo(@AppStore, "onAppInit"), Reflux.listenTo(@UserStore, "onUserChanged"),
|
|
Reflux.listenTo(@TeacherSearchResultsStore, "onTeacherSearchResultsStore"),
|
|
Reflux.listenTo(@TeacherSearchStore, "onTeacherSearchStore")]
|
|
|
|
LIMIT: 20
|
|
visible: false
|
|
needToSearch: true
|
|
root: null
|
|
screen: null
|
|
endOfList: null
|
|
contentBodyScroller: null
|
|
refreshing: false
|
|
|
|
getInitialState: () ->
|
|
{searchOptions: {}, results: [], user: null, searching: false}
|
|
|
|
onAppInit: (@app) ->
|
|
@app.bindScreen('teachers/search', {beforeShow: @beforeShow, afterShow: @afterShow, afterHide: @afterHide})
|
|
|
|
beforeShow: (e) ->
|
|
@visible = true
|
|
|
|
afterShow: (e) ->
|
|
UserActions.refresh()
|
|
|
|
#@setState(TeacherSearchStore.getState())
|
|
#if @state.results.length == 0
|
|
# don't issue a new search every time someone comes to the screen, to preserve location from previous browsing
|
|
if @needToSearch
|
|
@contentBodyScroller.off('scroll')
|
|
@endOfList.hide()
|
|
|
|
TeacherSearchResultsActions.reset()
|
|
@needToSearch = false
|
|
|
|
afterHide: (e) ->
|
|
@visible = false
|
|
@contentBodyScroller.off('scroll')
|
|
@hideSideBubble()
|
|
|
|
onTeacherSearchStore: (storeChanged) ->
|
|
@needToSearch = true
|
|
|
|
onTeacherSearchResultsStore: (results) ->
|
|
#results.searching = false
|
|
@refreshing = false
|
|
@contentBodyScroller.find('.infinite-scroll-loader-2').remove()
|
|
@setState(results)
|
|
|
|
onUserChanged: (@user) ->
|
|
@setState({user: @user?.user})
|
|
|
|
#onTeacherSearchChanged: (options) ->
|
|
# if @visible
|
|
# @setState(options)
|
|
|
|
componentDidMount: () ->
|
|
@root = $(@getDOMNode())
|
|
@screen = $('#teacherSearch')
|
|
@resultsNode = @root.find('.results')
|
|
@endOfList = @root.find('.end-of-teacher-list')
|
|
@contentBodyScroller = @root
|
|
|
|
|
|
registerInfiniteScroll:() ->
|
|
$scroller = @contentBodyScroller
|
|
logger.debug("registering infinite scroll")
|
|
$scroller.off('scroll')
|
|
$scroller.on('scroll', () =>
|
|
# be sure to not fire off many refreshes when user hits the bottom
|
|
return if @refreshing
|
|
|
|
if $scroller.scrollTop() + $scroller.innerHeight() + 100 >= $scroller[0].scrollHeight
|
|
$scroller.append('<div class="infinite-scroll-loader-2">... Loading more Teachers ...</div>')
|
|
@refreshing = true
|
|
#@setState({searching: true})
|
|
logger.debug("refreshing more teachers for infinite scroll")
|
|
TeacherSearchResultsActions.nextPage()
|
|
)
|
|
showSideBubble: () ->
|
|
setTimeout(
|
|
(() => (
|
|
if @visible
|
|
context.JK.HelpBubbleHelper.didntFindTeacher(@screen, null, @state.user || {}, ((note, email, phone) => @postHelp(note, email, phone)))
|
|
)), 3000)
|
|
|
|
|
|
hideSideBubble: () ->
|
|
if @screen.btOff
|
|
@screen.btOff()
|
|
|
|
postHelp: (value, email, phone) ->
|
|
|
|
if !value? || value == ''
|
|
@app.layout.notify({title: 'note required', text: 'Please enter something about what you are looking for.'})
|
|
return
|
|
if !context.JK.currentUserId? && (!email? || email == '')
|
|
@app.layout.notify({title: 'email required', text: 'Please enter your email.'})
|
|
return
|
|
|
|
rest.askSearchHelp({note: value, email: email, phone: phone}).done((response) => @postHelpDone()).fail(@app.ajaxError)
|
|
|
|
postHelpDone: () ->
|
|
console.log("show notice")
|
|
context.JK.Banner.showNotice("request received", "We got your note. We will reach back shortly!")
|
|
@hideSideBubble()
|
|
|
|
componentDidUpdate: () ->
|
|
@resultsNode.find('.teacher-bio').each((index, element) => (
|
|
$this = $(element)
|
|
if !$this.data('dotdotdot')
|
|
$this.dotdotdot({
|
|
after: "a.readmore"
|
|
})
|
|
))
|
|
|
|
|
|
if @visible
|
|
if @state.currentPage > 1
|
|
@showSideBubble()
|
|
|
|
if @state.next == null
|
|
@contentBodyScroller.off('scroll')
|
|
if @state.currentPage == 1 and @state.results.length == 0
|
|
@endOfList.text('No Teachers found matching your search').show()
|
|
logger.debug("TeacherSearch: empty search")
|
|
else if @state.currentPage > 0
|
|
logger.debug("end of search")
|
|
@endOfList.text('No more Teachers').show()
|
|
else
|
|
@registerInfiniteScroll(@contentBodyScroller)
|
|
|
|
moreAboutTeacher: (user, e) ->
|
|
e.preventDefault()
|
|
|
|
context.location = "/client#/profile/teacher/#{user.id}"
|
|
|
|
#ProfileActions.viewTeacherProfile(user, '/client#/teachers/search', 'BACK TO TEACHER SEARCH')
|
|
|
|
bookTestDrive: (user, e) ->
|
|
e.preventDefault()
|
|
|
|
rest.getTestDriveStatus({id: context.JK.currentUserId, teacher_id: user.id})
|
|
.done((response) =>
|
|
if response.jamclass_credits > 0
|
|
logger.debug('TeacherSearchScreen: user has jamclass credits available')
|
|
window.location.href = '/client#/jamclass/book-lesson/test-drive_' + user.id
|
|
else if response.remaining_test_drives == 0 && response['can_buy_test_drive?']
|
|
logger.debug("TeacherSearchScreen: user offered test drive")
|
|
#@app.layout.showDialog('try-test-drive', {d1: user.teacher.id})
|
|
window.location.href = '/client#/jamclass/test-drive-selection/' + user.id
|
|
else if response.remaining_test_drives > 0
|
|
if response.booked_with_teacher && !context.JK.currentUserAdmin
|
|
logger.debug("TeacherSearchScreen: teacher already test-drived")
|
|
|
|
context.JK.Banner.showAlert('TestDrive', "You have already taken a TestDrive lesson from this teacher. With TestDrive, you need to use your lessons on 4 different teachers to find one who is best for you. We're sorry, but you cannot take multiple TestDrive lessons from a single teacher.")
|
|
else
|
|
# send on to booking screen for this teacher
|
|
logger.debug("TeacherSearchScreen: user being sent to book a lesson")
|
|
|
|
window.location.href = '/client#/jamclass/book-lesson/test-drive_' + user.id
|
|
#window.location.href = '/client#/jamclass/test-drive-selection/' + user.id
|
|
else
|
|
# user has no remaining test drives and can't buy any
|
|
logger.debug("TeacherSearchScreen: test drive all done")
|
|
context.JK.Banner.showAlert('TestDrive', "You have already taken advantage of the TestDrive program within the past year, so we are sorry, but you are not eligible to use TestDrive again now. You may book a normal lesson with this teacher by closing this message, and clicking the BOOK LESSON button for this teacher.")
|
|
)
|
|
.fail((jqXHR, textStatus, errorMessage) =>
|
|
@app.ajaxError(jqXHR, textStatus, errorMessage)
|
|
)
|
|
|
|
bookNormalLesson: (user, e) ->
|
|
e.preventDefault()
|
|
|
|
rest.getTestDriveStatus({id: context.JK.currentUserId, teacher_id: user.id})
|
|
.done((response) =>
|
|
if response.remaining_test_drives > 0
|
|
buttons = []
|
|
buttons.push({name: 'CANCEL', buttonStyle: 'button-grey'})
|
|
buttons.push({name: 'PAY NORMALLY', buttonStyle: 'button-orange', click:(() => ( window.location.href = '/client#/jamclass/book-lesson/normal_' + user.id ))})
|
|
buttons.push({name: 'USE TEST DRIVE', buttonStyle: 'button-orange', click:(() => ( window.location.href = '/client#/jamclass/book-lesson/test-drive_' + user.id ))})
|
|
context.JK.Banner.show({title: 'You still have TestDrive Credits!', html: "You have #{response.remaining_test_drives} TestDrive credits remaining. Would you rather use your TestDrive credit for a lesson with this teacher?", buttons: buttons})
|
|
else
|
|
window.location.href = '/client#/jamclass/book-lesson/normal_' + user.id
|
|
)
|
|
.fail((jqXHR, textStatus, errorMessage) =>
|
|
@app.ajaxError(jqXHR, textStatus, errorMessage)
|
|
)
|
|
|
|
bookFreeLesson: (e) ->
|
|
e.preventDefault()
|
|
|
|
readMore: (e) ->
|
|
e.preventDefault()
|
|
|
|
target = $(e.target)
|
|
teacherBio = target.closest('.teacher-bio')
|
|
teacherBio.css('height', 'auto')
|
|
target.trigger( 'destroy.dot' );
|
|
teacherBio.css('height', 'auto')
|
|
|
|
|
|
render: () ->
|
|
|
|
resultsJsx = []
|
|
|
|
if @state.currentPage == 1 && @state.searching
|
|
resultsJsx = `<div className="spinner spinner-large"></div>`
|
|
else
|
|
for user in @state.results
|
|
|
|
photo_url = user.photo_url
|
|
if !photo_url?
|
|
photo_url = '/assets/shared/avatar_generic.png'
|
|
|
|
bio = user.teacher.biography
|
|
if !bio?
|
|
bio = 'No bio'
|
|
|
|
#school_on_school = user.teacher.school_id? && @state.user?.school_id? && user.teacher.school_id == @state.user.school_id
|
|
school_on_school = false
|
|
|
|
bookSingleBtn = null
|
|
bookTestDriveBtn = null
|
|
|
|
if !school_on_school && (!@state.user? || @state.user.jamclass_credits > 0 || @state.user.remaining_test_drives > 0 || @state.user['can_buy_test_drive?'])
|
|
bookTestDriveBtn = `<a className="button-orange try-test-drive" onClick={this.bookTestDrive.bind(this, user)}>BOOK TESTDRIVE LESSON</a>`
|
|
else
|
|
bookSingleBtn = `<a className="button-orange try-normal" onClick={this.bookNormalLesson.bind(this, user)}>BOOK LESSON</a>`
|
|
resultsJsx.push(`<div key={user.id} className="teacher-search-result" data-teacher-id={user.id}>
|
|
<div className="user-avatar">
|
|
<div className="avatar small">
|
|
<img src={photo_url} />
|
|
</div>
|
|
<div className="user-name">
|
|
{user.name}
|
|
</div>
|
|
</div>
|
|
<div className="user-info">
|
|
<div className="teacher-bio">
|
|
{bio}
|
|
<a className="readmore" onClick={this.readMore}>more</a>
|
|
</div>
|
|
<div className="teacher-actions">
|
|
<a className="button-orange more-about-teacher" onClick={this.moreAboutTeacher.bind(this, user)}>MORE ABOUT THIS TEACHER</a>
|
|
{bookTestDriveBtn}
|
|
{bookSingleBtn}
|
|
</div>
|
|
</div>
|
|
<br className="clearall" />
|
|
</div>`)
|
|
|
|
`<div className="content-body-scroller">
|
|
<div className="screen-content">
|
|
<div className="header">
|
|
<JamClassSearchHeader/>
|
|
</div>
|
|
<div className="results">
|
|
{resultsJsx}
|
|
<div className="end-of-teacher-list end-of-list">No more Teachers</div>
|
|
</div>
|
|
</div>
|
|
</div>`
|
|
}) |