jam-cloud/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx....

376 lines
13 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}
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()
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.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')
createSearchDescription: () ->
searchOptions = TeacherSearchStore.getState()
summary = ''
if searchOptions.onlyMySchool
summary += "From My School Only"
instruments = searchOptions.instruments
if instruments? && instruments.length > 0
if instruments.length == 1
bit = "Instrument = #{InstrumentStore.display(instruments[0])}"
else
instruments.length > 1
bit = "Instruments = #{InstrumentStore.display(instruments[0])} ... "
if summary.length > 0
summary += ', '
summary += " #{bit}"
subjects = searchOptions.subjects
if subjects? && subjects.length > 0
if subjects.length == 1
bit = "Subject = #{SubjectStore.display(subjects[0])}"
else
subjects.length > 1
bit = "Subjects = #{SubjectStore.display(subjects[0])} ... "
if summary.length > 0
summary += ', '
summary += " #{bit}"
genres = searchOptions.genres
if genres? && genres.length > 0
if genres.length == 1
bit = "Genre = #{GenreStore.display(genres[0])}"
else
genres.length > 1
bit = "Genres = #{GenreStore.display(genres[0])} ... "
if summary.length > 0
summary += ', '
summary += " #{bit}"
languages = searchOptions.languages
if languages? && languages.length > 0
if languages.length == 1
bit = "Language = #{LanguageStore.display(languages[0])}"
else
languages.length > 1
bit = "Languages = #{LanguageStore.display(languages[0])} ... "
if summary.length > 0
summary += ', '
summary += " #{bit}"
if searchOptions.teaches_beginner || searchOptions.teaches_intermediate || searchOptions.teaches_advanced
bit = "Teaches "
qualifier = ''
if searchOptions.teaches_beginner
qualifier += "Beginner"
if searchOptions.teaches_intermediate
if qualifier.length > 0
qualifier += ", "
qualifier += "Intermediate"
if searchOptions.teaches_advanced
if qualifier.length > 0
qualifier += ", "
qualifier += "Advanced"
if summary.length > 0
summary += ', '
summary += " #{bit}#{qualifier}"
if searchOptions.student_age?
if summary.length > 0
summary += ', '
summary += "Student Age = #{searchOptions.student_age}"
if searchOptions.years_teaching?
if summary.length > 0
summary += ', '
summary += "Years Teaching = #{searchOptions.years_teaching}"
if searchOptions.location?.country?
if summary.length > 0
summary += ', '
summary += "Country = #{searchOptions.location.country}"
if searchOptions.location?.region?
if summary.length > 0
summary += ', '
summary += "Region = #{searchOptions.location.region}"
if summary.length == 0
summary = 'all teachers'
summary
render: () ->
searchDesc = @createSearchDescription()
resultsJsx = []
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
bookSingleBtn = null
bookTestDriveBtn = null
if !school_on_school && (!@state.user? || @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">
<a href="/client#/home">JamKazam Home</a>&nbsp;:&nbsp;
<a href="/client#/jamclass">JamClass Home</a>&nbsp;:&nbsp;
<a className="teacher-search-options" href="/client#/jamclass/searchOptions" >Teachers Search</a><span className="teacher-quote"> :</span>
<span className="search-results-options">
<span className="search-description">
<span className="results-text">Search Results / </span>
<span className="search-summary">{searchDesc}</span>
</span>
</span>
</div>
<div className="results">
{resultsJsx}
<div className="end-of-teacher-list end-of-list">No more Teachers</div>
</div>
</div>
</div>`
})