* working on lesson payment screen

This commit is contained in:
Seth Call 2016-02-10 04:44:13 -06:00
parent 61fbc24a15
commit b0477ff511
9 changed files with 292 additions and 9 deletions

View File

@ -0,0 +1,139 @@
context = window
rest = context.JK.Rest()
logger = context.JK.logger
UserStore = context.UserStore
@FreeLessonPayment = React.createClass({
mixins: [
Reflux.listenTo(AppStore, "onAppInit"),
Reflux.listenTo(UserStore, "onUserChanged")
]
onAppInit: (@app) ->
@app.bindScreen('jamclass/free-lesson-payment',
{beforeShow: @beforeShow, afterShow: @afterShow, beforeHide: @beforeHide})
onUserChanged: (userState) ->
@setState({user: userState?.user})
componentDidMount: () ->
@root = $(@getDOMNode())
getInitialState: () ->
{user: null,
lesson: null,
updating: false}
beforeHide: (e) ->
@resetErrors()
beforeShow: (e) ->
afterShow: (e) ->
@resetState()
@resetErrors()
@setState({updating:true})
rest.getUnprocessedLesson().done((response) => @unprocessLoaded(response)).fail((jqXHR) => @failedBooking(jqXHR))
resetState: () ->
@setState({update: false, lesson: null})
unprocessLoaded: (response) ->
@setState({updating: false})
@setState({lesson: response})
failedUnprocessLoad: (jqXHR) ->
@setState({updating: false})
@app.layout.notify({title: 'Unable to load lesson', text: 'Please attempt to book a free lesson first or refresh this page.'})
onBack: (e) ->
e.preventDefault()
onSubmit: (e) ->
e.preventDefault()
render: () ->
disabled = @state.updating
if @state.updating
photo_url = '/assets/shared/avatar_generic.png'
name = 'Loading ...'
teacherDetails = `<div className="teacher-header">
<div className="avatar">
<img src={photo_url}/>
</div>
{name}
</div>`
else
if @state.lesson?
photo_url = @state.lesson.teacher.photo_url
name = @state.lesson.teacher.name
if !photo_url?
photo_url = '/assets/shared/avatar_generic.png'
teacherDetails = `<div className="teacher-header">
<div className="avatar">
<img src={photo_url}/>
</div>
{name}
</div>`
if lesson.lesson_type == 'single-free'
bookingInfo = `<p>You are booking a single free {this.state.lesson.lesson_length}-minute lesson.</p>`
bookingDetail = `<p>To book this lesson, you will need to enter your credit card information.
You will absolutely not be charged for this free lesson, and you have no further commitment to purchase
anything. We have to collect a credit card to prevent abuse by some users who would otherwise set up
multiple free accounts to get multiple free lessons.
<br/>
<div className="jamclass-policies"><a href="/corp/terms" rel="external" onClick={this.jamclassPolicies}>jamclass
policies</a></div>
</p>`
else if lesson.lesson_type == 'test-drive'
bookingInfo = `<p>This is not the correct page to pay for TestDrive.</p>`
bookingDetail = ''
else if lesson.lesson_type == 'paid'
bookingInfo = `<p>This is not the correct page for entering pay for a normal lesson.</p>`
bookingDetail = ''
`<div className="content-body-scroller">
<div className="column column-left">
<h2>enter card info</h2><div className="no-charge">Your card wil not be charged.<br/>See explanation to the right.</div>
<div className="field card-number">
<label>Card Number:</label>
<input disabled={disabled} type="text" name="card-number"></input>
</div>
<div className="field expiration">
<label>Expiration Date:</label>
<input disabled={disabled} type="text" name="expiration"></input>
</div>
<div className="field cvv">
<label>CVV:</label>
<input disabled={disabled} type="text" name="cvv"></input>
</div>
<div className="field zip">
<label>Zip/Postal Code:</label>
<input disabled={disabled} type="text" name="zip"></input>
</div>
</div>
<div className="column column-right">
{teacherDetails}
<div className="booking-info">
{bookingInfo}
{bookingDetail}
</div>
</div>
<div className="actions">
<a className={backClasses} onClick={this.onBack}>BACK</a><a className={submitClasses} onClick={this.onSubmit}>SUBMIT CARD INFORMATION</a>
</div>
</div>`
})

View File

@ -22,7 +22,8 @@ UserStore = context.UserStore
@root = $(@getDOMNode())
getInitialState: () ->
{user: null}
{user: null,
lesson: null}
beforeHide: (e) ->
@resetErrors()
@ -34,6 +35,30 @@ UserStore = context.UserStore
rest.getUnprocessedLesson().done((response) => @booked(response)).fail((jqXHR) => @failedBooking(jqXHR))
render: () ->
if @state.updating
else
if @state.lesson?
photo_url = @state.lesson.teacher.photo_url
if !photo_url?
photo_url = '/assets/shared/avatar_generic.png'
teacherDetails = `<div className="teacher-header">
<div className="avatar">
<img src={photo_url}/>
</div>
{name}
</div>`
if lesson.lesson_type == 'single-free'
bookingInfo = `<p>This is not the correct page to pay for TestDrive.</p>`
else if lesson.lesson_type == 'test-drive'
bookingInfo = `<p>This is not the correct page to pay for TestDrive.</p>`
else if lesson.lesson_type == 'paid'
bookingInfo = `<p>You are booking a {this.state.lesson.lesson_length} minute lesson for ${this.state.lesson.booked_price.toFixed(2)}</p>`
`<div className="content-body-scroller">
<div className="column column-left">
<h2>enter payment info for lesson</h2>
@ -57,14 +82,9 @@ UserStore = context.UserStore
</div>
</div>
<div className="column column-right">
<div className="teacher-header">
<div className="avatar">
<img src={photo_url}/>
</div>
{name}
</div>
{teacherDetails}
<div className="booking-info">
<p>BOOKING INFO TODO</p>
<p>{bookingInfo}</p>
<p>BOOKING DETAIL TODO<br/>

View File

@ -0,0 +1,100 @@
@import "client/common";
#free-lesson-payment {
.content-body-scroller {
height:100%;
padding:30px;
}
h2 {
font-size: 20px;
font-weight:700;
margin-bottom: 20px !important;
display:inline-block;
}
.no-charge {
float:right;
}
.column {
@include border_box_sizing;
width:50%;
}
.column-left {
float:left;
padding-right:20px;
}
.column-right {
float:right;
padding-left:20px;
}
label {
display:inline-block;
}
select {
display:inline-block;
}
input {
display:inline-block;
width: calc(100% - 150px);
@include border_box_sizing;
}
textarea {
width:100%;
@include border_box_sizing;
height:125px;
}
.field {
position:relative;
display:block;
margin-top:15px;
margin-bottom:25px;
label {
width:150px;
}
}
p {
line-height:125% !important;
font-size:14px !important;
margin:0 0 20px 0 !important;
}
.avatar {
display:inline-block;
padding:1px;
width:48px;
height:48px;
background-color:#ed4818;
margin:10px 20px 0 0;
-webkit-border-radius:24px;
-moz-border-radius:24px;
border-radius:24px;
float:none;
}
.avatar img {
width: 48px;
height: 48px;
-webkit-border-radius:24px;
-moz-border-radius:24px;
border-radius:24px;
}
.teacher-name {
font-size:16px;
display:inline-block;
height:48px;
vertical-align:middle;
}
.jamclass-policies {
text-align:center;
margin-top:-20px;
}
.actions {
margin-left:-3px;
margin-bottom:20px;
}
.error-text {
display:block;
}
}

View File

@ -0,0 +1,5 @@
@import "client/common";
#lesson-payment {
}

View File

@ -49,6 +49,7 @@ class ApiLessonBookingsController < ApiController
end
def unprocessed
@show_teacher = true
@lesson_booking = LessonBooking.unprocessed(current_user)
end
end

View File

@ -8,4 +8,8 @@ child(:lesson_booking_slots => :slots) {
child(:user => :user) {
attributes :id, :has_stored_credit_card?
}
child (:teacher => :teacher) { |teacher|
partial "api_users/show", object: teacher
}

View File

@ -0,0 +1,3 @@
object @lesson_booking
extends "api_lesson_bookings/show"

View File

@ -47,6 +47,7 @@
<%= render "clients/teachers/search/search_results" %>
<%= render "clients/jamclass/book_lesson_free" %>
<%= render "clients/jamclass/lesson_payment" %>
<%= render "clients/jamclass/free_lesson_payment" %>
<%= render "users/feed_music_session_ajax" %>
<%= render "users/feed_recording_ajax" %>
<%= render "jamtrack_search" %>

View File

@ -0,0 +1,10 @@
#free-lesson-payment.screen.secondary layout="screen" layout-id="jamclass/free-lesson-payment"
.content-head
.content-icon
= image_tag "content/icon_account.png", :size => "27x20"
h1
| jamclass
= render "screen_navigation"
.content-body
= react_component 'FreeLessonPayment', {}