bunch of jamclass fixes
This commit is contained in:
parent
1abacf0ec6
commit
d4aa3bef2b
|
|
@ -1,4 +1,4 @@
|
|||
ActiveAdmin.register JamRuby::TestDrivePackage, :as => 'TestDrivePackages' do
|
||||
ActiveAdmin.register JamRuby::TestDrivePackage, :as => 'TestDrivePackage' do
|
||||
|
||||
menu :label => 'Test Drive Packages', :parent => 'JamClass'
|
||||
|
||||
|
|
@ -11,42 +11,88 @@ ActiveAdmin.register JamRuby::TestDrivePackage, :as => 'TestDrivePackages' do
|
|||
form :partial => 'form'
|
||||
|
||||
|
||||
controller do
|
||||
=begin
|
||||
def new
|
||||
test_drive_package = TestDrivePackage.new
|
||||
t = TestDrivePackageTeacher.new
|
||||
t.test_drive_package = test_drive_package
|
||||
test_drive_package.test_drive_package_teachers << t
|
||||
|
||||
t = TestDrivePackageTeacher.new
|
||||
t.test_drive_package = test_drive_package
|
||||
test_drive_package.test_drive_package_teachers << t
|
||||
|
||||
@test_drive_package = test_drive_package
|
||||
puts "OK #{test_drive_package.test_drive_package_teachers.length}"
|
||||
super
|
||||
end
|
||||
=end
|
||||
|
||||
|
||||
# def create
|
||||
# puts params.inspect
|
||||
# hash = params[:jam_ruby_test_drive_package]
|
||||
# package = TestDrivePackage.new
|
||||
# package.name = hash[:name]
|
||||
# package.package_type = hash[:package_type]
|
||||
# package.description = hash[:description]
|
||||
# if package.save
|
||||
# redirect_to admin_test_drive_package_path(package.id)
|
||||
# else
|
||||
# redirect_to admin_test_drive_packages_path, :notice => "Unable to create package. Error: #{package.errors.first[1][0]}"
|
||||
# end
|
||||
#end
|
||||
end
|
||||
index do
|
||||
|
||||
column "Package ID" do |package|
|
||||
link_to package.name, "#{APP_CONFIG.external_root_url}/landing/jamclass/students?utm-teachers=#{package.name}"
|
||||
end
|
||||
|
||||
column "Package Type" do |package|
|
||||
package.package_type
|
||||
end
|
||||
|
||||
column "Teachers" do |package|
|
||||
span do
|
||||
package.test_drive_package_teachers.each do |package_teacher|
|
||||
teacher = package_teacher
|
||||
|
||||
span do
|
||||
teacher = package_teacher.user
|
||||
link_to "#{teacher.name} (#{teacher.email})", "#{Rails.application.config.external_root_url}/client#/profile/teacher/#{teacher.id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
column "Detail" do |package|
|
||||
link_to "Detail", admin_test_drive_package_path(package.id)
|
||||
br
|
||||
end
|
||||
end
|
||||
|
||||
column "Detail" do |package|
|
||||
link_to "Detail", admin_test_drive_package_path(package.id)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
show do
|
||||
|
||||
attributes_table do
|
||||
row "Package ID" do |package|
|
||||
link_to package.name, "#{APP_CONFIG.external_root_url}/landing/jamclass/students?utm-teachers=#{package.name}"
|
||||
end
|
||||
|
||||
row "Package Type" do |package|
|
||||
package.package_type
|
||||
end
|
||||
|
||||
row "Teachers" do |package|
|
||||
span do
|
||||
package.test_drive_package_teachers.each do |package_teacher|
|
||||
teacher = package_teacher
|
||||
|
||||
span do
|
||||
teacher = package_teacher.user
|
||||
link_to "#{teacher.name} (#{teacher.email})", "#{Rails.application.config.external_root_url}/client#/profile/teacher/#{teacher.id}"
|
||||
end
|
||||
br
|
||||
end
|
||||
end
|
||||
|
||||
row "Description" do |package|
|
||||
package.description
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
<%= semantic_form_for([:admin, resource], html: {:multipart => true}, url: resource.new_record? ? admin_test_drive_packages_path : "#{ENV['RAILS_RELATIVE_URL_ROOT']}/admin/test_drive_packages/#{resource.id}") do |f| %>
|
||||
<%= semantic_form_for([:admin, @test_drive_package], html: {:multipart => true}, url: @test_drive_package.new_record? ? admin_test_drive_packages_path : "#{ENV['RAILS_RELATIVE_URL_ROOT']}/admin/test_drive_packages/#{@test_drive_package.id}") do |f| %>
|
||||
<%= f.semantic_errors *f.object.errors.keys %>
|
||||
<%= f.inputs do %>
|
||||
<%= f.input :name, label: "Package ID", hint: "The name to use as the utm-teachers parameter in the student landing URL" %>
|
||||
<%= f.input :package_type, label: "Package Type", as: :select, collection: ['1', '2', '4'], hint: "TestDrive package type" %>
|
||||
<%= f.input :name, required: true, label: "Package ID", hint: "The name to use as the utm-teachers parameter in the student landing URL" %>
|
||||
<%= f.input :package_type, required: true, label: "Package Type", as: :select, collection: ['1', '2', '4'], hint: "TestDrive package type" %>
|
||||
<%= f.input :description, label: "Package Description", hint: "Admin-only friendly description of the package" %>
|
||||
|
||||
<%= f.semantic_fields_for :test_drive_package_teachers do |teacher| %>
|
||||
<%= render 'test_drive_package_teacher_fields', f: teacher %>
|
||||
<% end %>
|
||||
|
||||
<% if !@test_drive_package.new_record? %>
|
||||
<div class="links">
|
||||
<%= link_to_add_association 'Add Teacher', f, :test_drive_package_teachers, class: 'button', style: 'margin:20px;padding:10px 20px' %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= f.actions %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
= f.inputs name: 'Teachers' do
|
||||
|
||||
ol.nested-fields
|
||||
= f.input :test_drive_package, :required=>true, collection: TestDrivePackage.all, include_blank: false
|
||||
= f.input :user, :required=>true, collection: User.where(is_a_teacher: true, phantom: false), include_blank: false
|
||||
//= f.input :test_drive_package, :required=>true, value: @test_drive_package, include_blank: true
|
||||
= f.input :user, :required=>true, collection: User.where(is_a_teacher: true, phantom: false), include_blank: true
|
||||
= f.input :short_bio
|
||||
|
||||
= link_to_remove_association "Delete Teacher", f, class: 'button', style: 'margin-left:10px'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
class JamRuby::Teacher
|
||||
|
||||
attr_accessible :short_bio, as: :admin
|
||||
|
||||
end
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
class JamRuby::User
|
||||
|
||||
attr_accessible :admin, :raw_password, :musician, :can_invite, :photo_url, :session_settings, :confirm_url, :email_template # :invite_email
|
||||
attr_accessible :admin, :raw_password, :musician, :can_invite, :photo_url, :session_settings, :confirm_url, :teacher_attributes, :email_template # :invite_email
|
||||
|
||||
accepts_nested_attributes_for :teacher, allow_destroy: true
|
||||
|
||||
def raw_password
|
||||
''
|
||||
|
|
|
|||
|
|
@ -9,10 +9,30 @@ CREATE TABLE test_drive_packages (
|
|||
|
||||
CREATE TABLE test_drive_package_teachers (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id VARCHAR(64) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
test_drive_package_id VARCHAR(64) NOT NULL REFERENCES test_drive_packages(id) ON DELETE CASCADE,
|
||||
user_id VARCHAR(64) REFERENCES users(id) ON DELETE CASCADE,
|
||||
test_drive_package_id VARCHAR(64) REFERENCES test_drive_packages(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
ALTER TABLE lesson_bookings ADD COLUMN test_drive_package_id VARCHAR(64) REFERENCES test_drive_packages(id);
|
||||
|
||||
CREATE TABLE test_drive_package_choices (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
test_drive_package_id VARCHAR(64) REFERENCES test_drive_packages(id) ON DELETE CASCADE,
|
||||
user_id VARCHAR(64) REFERENCES users(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE test_drive_package_choice_teachers (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
test_drive_package_choice_id VARCHAR(64) REFERENCES test_drive_package_choices(id) ON DELETE CASCADE,
|
||||
teacher_id VARCHAR(64) REFERENCES users(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
ALTER TABLE teachers ADD COLUMN short_bio VARCHAR;
|
||||
ALTER TABLE test_drive_package_teachers ADD COLUMN short_bio VARCHAR;
|
||||
|
|
@ -256,6 +256,8 @@ require "jam_ruby/models/broadcast_notification"
|
|||
require "jam_ruby/models/broadcast_notification_view"
|
||||
require "jam_ruby/models/test_drive_package"
|
||||
require "jam_ruby/models/test_drive_package_teacher"
|
||||
require "jam_ruby/models/test_drive_package_choice"
|
||||
require "jam_ruby/models/test_drive_package_choice_teacher"
|
||||
require "jam_ruby/calendar_manager"
|
||||
require "jam_ruby/jam_tracks_manager"
|
||||
require "jam_ruby/jam_track_importer"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<% provide(:title, 'Welcome to JamKazam!') %>
|
||||
|
||||
<p>We’re delighted you have joined our community of 30,000+ musicians. We’d like to send you an orientation email with information and resource links that will help you get the most out of JamKazam. Please <a style="color: #ffcc00;" href="<%= @signup_confirm_url %>">click here to confirm this email</a> has reached you successfully and we will then send the orientation email.</p>
|
||||
<p>We’re delighted you have joined our community of <%= APP_CONFIG.musician_count %> musicians. We’d like to send you an orientation email with information and resource links that will help you get the most out of JamKazam. Please <a style="color: #ffcc00;" href="<%= @signup_confirm_url %>">click here to confirm this email</a> has reached you successfully and we will then send the orientation email.</p>
|
||||
|
||||
<p>If you have received this email but aren’t familiar with JamKazam or JamTracks, then someone has registered at our website using your email address, and you can just ignore and delete this email.</p>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Welcome to JamKazam!
|
||||
|
||||
We’re delighted you have joined our community of 30,000+ musicians. We’d like to send you an orientation email with information and resource links that will help you get the most out of JamKazam. Please click <%= @signup_confirm_url %> to confirm this email has reached you successfully and we will then send the orientation email.
|
||||
We’re delighted you have joined our community of <%= APP_CONFIG.musician_count %> musicians. We’d like to send you an orientation email with information and resource links that will help you get the most out of JamKazam. Please click <%= @signup_confirm_url %> to confirm this email has reached you successfully and we will then send the orientation email.
|
||||
|
||||
If you have received this email but aren’t familiar with JamKazam or JamTracks, then someone has registered at our website using your email address, and you can just ignore and delete this email.
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
Thank you for signing up to take online music lessons using the JamClass service by JamKazam. JamKazam technology was
|
||||
built from the ground up for playing music live in sync with high quality audio from different locations over the
|
||||
Internet. Unlike other lesson services, this means we can deliver a massively better online music lesson experience
|
||||
than voice/chat apps like Skype, etc. Our rapidly growing community of 35,000+ musicians will attest to this.
|
||||
than voice/chat apps like Skype, etc. Our rapidly growing community of <%= APP_CONFIG.musician_count %> musicians will attest to this.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -20,58 +20,31 @@
|
|||
|
||||
<p><b style="color: white">1. Find a Teacher & Book Lessons</b><br/>
|
||||
|
||||
If you already know the teacher from whom you want to learn, then you can simply
|
||||
<a href="https://www.jamkazam.com/client#/jamclass/searchOptions" style="color:#fc0">use this link to search for
|
||||
them</a>, and
|
||||
click the Book Lesson button to get started. But if you're like most of us, you don't know. In this case, we strongly
|
||||
advise signing up for our unique TestDrive service.
|
||||
<br/>
|
||||
<br/>
|
||||
If you haven't done so already, <a href="https://www.jamkazam.com/client#/jamclass/searchOptions" style="color:#fc0">use this link to search our teachers</a>, and click to book a TestDrive with a teacher who looks good for you. When you do this, you'll be given the option to take full 30-minute TestDrive lessons:
|
||||
|
||||
TestDrive lets you take 4 full lessons (30 minutes each) from 4 different teachers for just $49.99 to find the best
|
||||
teacher for you. Finding the right teacher is the single most important determinant of success in your lessons. Would
|
||||
you marry the first person you ever dated? No? Same here. Pick 4 teachers who look great, and then see who you click
|
||||
with. It's a phenomenal value, and then you can stick with the best teacher for you.
|
||||
<a href="https://www.jamkazam.com/client#/jamclass/lesson-payment/test-drive" style="color:#fc0">Click this link
|
||||
to sign up now
|
||||
for TestDrive</a>. Then you can book 4 TestDrive lessons to get rolling.
|
||||
<ul>
|
||||
<li>With 4 different teachers for just $12.50 each</li>
|
||||
<li>With 2 different teachers for just $14.99 each</li>
|
||||
<li>Or with 1 teacher for just $14.99</li>
|
||||
</ul>
|
||||
<p>
|
||||
Pick whichever option you prefer. TestDrive lets you safely and easily try multiple teachers to find the one who is best specifically for you, which is a great way to maximize the benefit from your lessons. And TestDrive lessons are heavily discounted to give you a risk-free way to get started. We'd suggest scheduling your first lesson for about a week in the future to give you plenty of time to get up and running with our free app.
|
||||
</p>
|
||||
</p>
|
||||
|
||||
<p><b style="color: white">2. Set Up Your Gear</b><br/>
|
||||
Use this link to a set of
|
||||
<a href="https://jamkazam.desk.com/customer/en/portal/topics/673197-first-time-setup/articles" style="color:#fc0">help
|
||||
articles on how to set up your gear</a> to be ready to teach online. After you have signed
|
||||
up, someone from JamKazam will contact you to schedule a test online session, in which we will make sure your audio
|
||||
and video gear are working properly in an online session, and to make sure you feel comfortable with the key features
|
||||
you will be using in sessions with teachers.
|
||||
Please review our <a href="https://jamkazam.desk.com/customer/en/portal/topics/564807-gear-recommendations/articles" style="color:#fc0">help articles on gear recommendations</a>
|
||||
to make sure you have everything you need to get set up properly for best results in your online lessons.
|
||||
If you have everything you need, then you can follow the instructions on our <a href="https://jamkazam.desk.com/customer/en/portal/topics/930331-setting-up-your-gear-to-play-in-online-sessions/articles" style="color:#fc0">setup help articles</a> to download and install our free app and set it up with your audio gear and webcam. Please email us at <a href="mailto:support@jamkaazm.com" style="color:#fc0">support@jamkazam.com</a> or call us at 1-877-376-8742 any time so that we can help you with these steps. We are very happy to help, and we also strongly suggest that you let one of our staff get into an online session with you to make sure everything is working properly and to make sure you're comfortable with the app and ready for your first lesson.
|
||||
</p>
|
||||
|
||||
<p><b style="color: white">3. Learn About JamClass Features</b><br/>
|
||||
Use this link to a set of
|
||||
<a href="https://jamkazam.desk.com/customer/en/portal/topics/926073-jamclass-online-music-lessons---for-students/articles" style="color:#fc0">help
|
||||
articles for students on JamClass</a> to familiarize yourself with the most useful features
|
||||
for online lessons. This includes how to search for the best teacher for you, how to request/book lessons, how to join
|
||||
your teacher in online lessons, features you can use while in lessons, and much more. There is very important basic
|
||||
information, plus some really nifty stuff here, so be sure to look through it at least briefly to see how we can
|
||||
turbocharge your online lessons!
|
||||
</p>
|
||||
|
||||
<p><b style="color: white">4. Play With Other Musicians Online - It's Free!</b><br/>
|
||||
With JamKazam, you can use the things you're learning in lessons to play with other amateur musicians in online
|
||||
sessions, free! Or just play for fun. Once you've set up your gear for lessons, you can
|
||||
<a href="https://jamkazam.desk.com/customer/en/portal/articles/1599977-creating-a-session" style="color:#fc0">create
|
||||
online music sessions</a>
|
||||
that others can join, or <a href="https://jamkazam.desk.com/customer/en/portal/articles/1599978-finding-a-session" style="color:#fc0">find other musicians' online music sessions</a> and hop into those to play with others. If you
|
||||
want to take advantage of this part of the JamKazam platform, we'd advise that you <a href="https://www.jamkazam.com/client#/account/profile" style="color:#fc0">edit your musician profile</a> to make
|
||||
it easier to <a href="https://jamkazam.desk.com/customer/en/portal/articles/1707418-connecting-with-other-musicians" style="color:#fc0">connect with other musicians</a> in our community to expand your set of musician friends. It's a ton of fun,
|
||||
so give it a try!
|
||||
Please review our <a href="https://jamkazam.desk.com/customer/en/portal/topics/926073-jamclass-online-music-lessons---for-students/articles" style="color:#fc0">JamClass user guide for students</a> to familiarize yourself with the features and resources available to you through our JamClass lesson service. This includes how to search for the best teacher for you, how to request/book lessons, how to join your teacher in online lessons, features you can use while in lessons, and much more.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As you work through these things, if you ever get stuck or have questions, please don't hesitate to reach out for
|
||||
help. You can email us any time at <a href="mailto:support@jamkazam.com" style="color:#fc0">support@jamkazam.com</a>. We are happy to
|
||||
help you, and we look forward to helping you
|
||||
learn and grow as a musician, and expand your musical universe!
|
||||
|
||||
Again, welcome to JamKazam and our JamClass online music lesson service, and we look forward to helping you learn and grow as a musician!
|
||||
</p>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
Thank you for signing up to take online music lessons using the JamClass service by JamKazam. JamKazam technology was
|
||||
built from the ground up for playing music live in sync with high quality audio from different locations over the
|
||||
Internet. Unlike other lesson services, this means we can deliver a massively better online music lesson experience
|
||||
than voice/chat apps like Skype, etc. Our rapidly growing community of 35,000+ musicians will attest to this.
|
||||
than voice/chat apps like Skype, etc. Our rapidly growing community of <%= APP_CONFIG.musician_count %> musicians will attest to this.
|
||||
|
||||
|
||||
To get ready to take JamClass lessons online, here are the things you'll want to do:
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ module JamRuby
|
|||
end
|
||||
|
||||
|
||||
def to_s
|
||||
"#{name} (#{amount_charged})"
|
||||
end
|
||||
|
||||
def name
|
||||
lesson_package_type.sale_display
|
||||
|
|
|
|||
|
|
@ -10,6 +10,16 @@ module JamRuby
|
|||
|
||||
validates :name, presence: true, uniqueness: true
|
||||
validates :package_type, presence: true
|
||||
|
||||
#validate :teacher_count
|
||||
|
||||
def teacher_count
|
||||
if package_type != test_drive_package_teachers.length
|
||||
self.errors.add(:test_drive_package_teachers, "wrong number of teachers specified for the given package type #{package_type}")
|
||||
end
|
||||
end
|
||||
|
||||
accepts_nested_attributes_for :test_drive_package_teachers, allow_destroy: true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
# when a user picks a package, we mark which teachers they actually went with from the package
|
||||
module JamRuby
|
||||
class TestDrivePackageChoice < ActiveRecord::Base
|
||||
|
||||
@@log = Logging.logger[TestDrivePackageChoice]
|
||||
|
||||
belongs_to :test_drive_package, class_name: "JamRuby::TestDrivePackage"
|
||||
belongs_to :user, class_name: "JamRuby::User"
|
||||
has_many :test_drive_package_choice_teachers, class_name: "JamRuby::TestDrivePackageChoiceTeacher", foreign_key: :teacher_id
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# when a user picks a package, we mark which teachers they actually went with from the package
|
||||
module JamRuby
|
||||
class TestDrivePackageChoiceTeacher < ActiveRecord::Base
|
||||
|
||||
@@log = Logging.logger[TestDrivePackageChoiceTeacher]
|
||||
|
||||
belongs_to :test_drive_package_choice, class_name: "JamRuby::TestDrivePackageChoice"
|
||||
belongs_to :teacher, class_name: "JamRuby::User", foreign_key: :teacher_id
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -4,13 +4,30 @@ module JamRuby
|
|||
|
||||
@@log = Logging.logger[TestDrivePackageTeacher]
|
||||
|
||||
attr_accessible :user_id, :test_drive_package_id, as: :admin
|
||||
attr_accessor :short_bio_temp
|
||||
attr_accessible :user_id, :test_drive_package_id, :short_bio, as: :admin
|
||||
|
||||
belongs_to :test_drive_package, class_name: "JamRuby::TestDrivePackage"
|
||||
belongs_to :user, class_name: "JamRuby::User"
|
||||
|
||||
validates :user, presence: true
|
||||
validates :test_drive_package, presence: true
|
||||
|
||||
after_save :after_save
|
||||
|
||||
# silly pass through for activeadmin. We pass short_bio set here on to teacher
|
||||
def after_save
|
||||
if user && user.teacher
|
||||
user.teacher.short_bio = short_bio
|
||||
user.teacher.save!
|
||||
end
|
||||
end
|
||||
|
||||
def short_bio
|
||||
if user && user.teacher
|
||||
user.teacher.short_bio
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1159,7 +1159,7 @@ module JamRuby
|
|||
elsif user.is_a_teacher
|
||||
school = School.find_by_id(school_id)
|
||||
school_name = school ? school.name : 'a music school'
|
||||
user.teacher = Teacher.build_teacher(user, validate_introduction: true, biography: "Teaches for #{school_name}", school_id: school_id)
|
||||
user.teacher = Teacher.build_teacher(user, validate_introduction: true, biography: "Empty biography", school_id: school_id)
|
||||
user.affiliate_referral = school.affiliate_partner
|
||||
end
|
||||
else
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ FactoryGirl.define do
|
|||
specific_instruments nil
|
||||
end
|
||||
|
||||
sequence(:email) { |n| "person_#{n}@example.com"}
|
||||
sequence(:email) { |n| "person_#{n}@example.com" }
|
||||
sequence(:first_name) { |n| "Person" }
|
||||
sequence(:last_name) { |n| "#{n}" }
|
||||
password "foobar"
|
||||
|
|
@ -208,7 +208,7 @@ FactoryGirl.define do
|
|||
client_type 'client'
|
||||
gateway 'gateway1'
|
||||
last_jam_audio_latency { user.last_jam_audio_latency if user }
|
||||
sequence(:channel_id) { |n| "Channel#{n}"}
|
||||
sequence(:channel_id) { |n| "Channel#{n}" }
|
||||
association :user, factory: :user
|
||||
scoring_timeout Time.now
|
||||
end
|
||||
|
|
@ -260,26 +260,26 @@ FactoryGirl.define do
|
|||
|
||||
factory :track, :class => JamRuby::Track do
|
||||
sound "mono"
|
||||
sequence(:client_track_id) { |n| "client_track_id#{n}"}
|
||||
sequence(:client_resource_id) { |n| "resource_id#{n}"}
|
||||
sequence(:client_track_id) { |n| "client_track_id#{n}" }
|
||||
sequence(:client_resource_id) { |n| "resource_id#{n}" }
|
||||
end
|
||||
|
||||
factory :backing_track, :class => JamRuby::BackingTrack do
|
||||
sequence(:client_track_id) { |n| "client_track_id#{n}"}
|
||||
sequence(:client_track_id) { |n| "client_track_id#{n}" }
|
||||
filename 'foo.mp3'
|
||||
end
|
||||
|
||||
factory :video_source, :class => JamRuby::VideoSource do
|
||||
#client_video_source_id "test_source_id"
|
||||
sequence(:client_video_source_id) { |n| "client_video_source_id#{n}"}
|
||||
sequence(:client_video_source_id) { |n| "client_video_source_id#{n}" }
|
||||
end
|
||||
|
||||
factory :recorded_track, :class => JamRuby::RecordedTrack do
|
||||
instrument JamRuby::Instrument.first
|
||||
sound 'stereo'
|
||||
sequence(:client_id) { |n| "client_id-#{n}"}
|
||||
sequence(:track_id) { |n| "track_id-#{n}"}
|
||||
sequence(:client_track_id) { |n| "client_track_id-#{n}"}
|
||||
sequence(:client_id) { |n| "client_id-#{n}" }
|
||||
sequence(:track_id) { |n| "track_id-#{n}" }
|
||||
sequence(:client_track_id) { |n| "client_track_id-#{n}" }
|
||||
md5 'abc'
|
||||
length 1
|
||||
fully_uploaded true
|
||||
|
|
@ -288,11 +288,11 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
factory :recorded_backing_track, :class => JamRuby::RecordedBackingTrack do
|
||||
sequence(:client_id) { |n| "client_id-#{n}"}
|
||||
sequence(:backing_track_id) { |n| "track_id-#{n}"}
|
||||
sequence(:client_track_id) { |n| "client_track_id-#{n}"}
|
||||
sequence(:filename) { |n| "filename-{#n}"}
|
||||
sequence(:url) { |n| "/recordings/blah/#{n}"}
|
||||
sequence(:client_id) { |n| "client_id-#{n}" }
|
||||
sequence(:backing_track_id) { |n| "track_id-#{n}" }
|
||||
sequence(:client_track_id) { |n| "client_track_id-#{n}" }
|
||||
sequence(:filename) { |n| "filename-{#n}" }
|
||||
sequence(:url) { |n| "/recordings/blah/#{n}" }
|
||||
md5 'abc'
|
||||
length 1
|
||||
fully_uploaded true
|
||||
|
|
@ -301,7 +301,7 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
factory :recorded_video, :class => JamRuby::RecordedVideo do
|
||||
sequence(:client_video_source_id) { |n| "client_video_source_id-#{n}"}
|
||||
sequence(:client_video_source_id) { |n| "client_video_source_id-#{n}" }
|
||||
fully_uploaded true
|
||||
length 1
|
||||
association :user, factory: :user
|
||||
|
|
@ -359,7 +359,7 @@ FactoryGirl.define do
|
|||
sequence(:mp3_url) { |n| "recordings/mp3/#{n}" }
|
||||
completed true
|
||||
|
||||
before(:create) {|mix, evaluator|
|
||||
before(:create) { |mix, evaluator|
|
||||
if evaluator.autowire
|
||||
user = FactoryGirl.create(:user)
|
||||
mix.recording = FactoryGirl.create(:recording_with_track, owner: user)
|
||||
|
|
@ -382,7 +382,7 @@ FactoryGirl.define do
|
|||
mp3_url nil
|
||||
completed false
|
||||
|
||||
before(:create) {|mix, evaluator|
|
||||
before(:create) { |mix, evaluator|
|
||||
if evaluator.autowire
|
||||
user = FactoryGirl.create(:user)
|
||||
mix.user = user
|
||||
|
|
@ -539,8 +539,8 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
factory :icecast_server, :class => JamRuby::IcecastServer do
|
||||
sequence(:hostname) { |n| "hostname-#{n}"}
|
||||
sequence(:server_id) { |n| "test-server-#{n}"}
|
||||
sequence(:hostname) { |n| "hostname-#{n}" }
|
||||
sequence(:server_id) { |n| "test-server-#{n}" }
|
||||
|
||||
factory :icecast_server_minimal do
|
||||
association :template, :factory => :icecast_template_minimal
|
||||
|
|
@ -561,7 +561,7 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
factory :icecast_mount_template, :class => JamRuby::IcecastMountTemplate do
|
||||
sequence(:name) { |n| "name-#{n}"}
|
||||
sequence(:name) { |n| "name-#{n}" }
|
||||
source_username Faker::Lorem.characters(10)
|
||||
source_pass Faker::Lorem.characters(10)
|
||||
max_listeners 100
|
||||
|
|
@ -580,8 +580,8 @@ FactoryGirl.define do
|
|||
|
||||
factory :icecast_template, :class => JamRuby::IcecastTemplate do
|
||||
|
||||
sequence(:name) { |n| "name-#{n}"}
|
||||
sequence(:location) { |n| "location-#{n}"}
|
||||
sequence(:name) { |n| "name-#{n}" }
|
||||
sequence(:location) { |n| "location-#{n}" }
|
||||
|
||||
factory :icecast_template_minimal do
|
||||
association :limit, :factory => :icecast_limit
|
||||
|
|
@ -597,13 +597,13 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
factory :facebook_signup, :class => JamRuby::FacebookSignup do
|
||||
sequence(:lookup_id) { |n| "lookup-#{n}"}
|
||||
sequence(:first_name) { |n| "first-#{n}"}
|
||||
sequence(:last_name) { |n| "last-#{n}"}
|
||||
sequence(:lookup_id) { |n| "lookup-#{n}" }
|
||||
sequence(:first_name) { |n| "first-#{n}" }
|
||||
sequence(:last_name) { |n| "last-#{n}" }
|
||||
gender 'M'
|
||||
sequence(:email) { |n| "jammin-#{n}@jamkazam.com"}
|
||||
sequence(:uid) { |n| "uid-#{n}"}
|
||||
sequence(:token) { |n| "token-#{n}"}
|
||||
sequence(:email) { |n| "jammin-#{n}@jamkazam.com" }
|
||||
sequence(:uid) { |n| "uid-#{n}" }
|
||||
sequence(:token) { |n| "token-#{n}" }
|
||||
token_expires_at Time.now
|
||||
end
|
||||
|
||||
|
|
@ -676,7 +676,7 @@ FactoryGirl.define do
|
|||
|
||||
after(:create) do |rsvp_slot, evaluator|
|
||||
rsvp_request = FactoryGirl.create(:rsvp_request, user: evaluator.user)
|
||||
rsvp_request_rsvp_slot = FactoryGirl.create(:rsvp_request_rsvp_slot, chosen:true, rsvp_request: rsvp_request, rsvp_slot:rsvp_slot)
|
||||
rsvp_request_rsvp_slot = FactoryGirl.create(:rsvp_request_rsvp_slot, chosen: true, rsvp_request: rsvp_request, rsvp_slot: rsvp_slot)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -694,10 +694,10 @@ FactoryGirl.define do
|
|||
chosen nil
|
||||
end
|
||||
|
||||
after(:create) { |rsvp_request, evaluator |
|
||||
after(:create) { |rsvp_request, evaluator|
|
||||
evaluator.number.times do |i|
|
||||
slot = FactoryGirl.create(:rsvp_slot, music_session: evaluator.music_session, instrument: Instrument.order(:id).limit(1).offset(i).first, proficiency_level: 1)
|
||||
FactoryGirl.create(:rsvp_request_rsvp_slot, chosen: evaluator.chosen, rsvp_request: rsvp_request, rsvp_slot:slot)
|
||||
FactoryGirl.create(:rsvp_request_rsvp_slot, chosen: evaluator.chosen, rsvp_request: rsvp_request, rsvp_slot: slot)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
|
@ -709,9 +709,9 @@ FactoryGirl.define do
|
|||
chosen nil
|
||||
end
|
||||
|
||||
after(:create) { |rsvp_request, evaluator |
|
||||
after(:create) { |rsvp_request, evaluator|
|
||||
evaluator.slots.each do |slot|
|
||||
FactoryGirl.create(:rsvp_request_rsvp_slot, chosen:evaluator.chosen, rsvp_request: rsvp_request, rsvp_slot:slot)
|
||||
FactoryGirl.create(:rsvp_request_rsvp_slot, chosen: evaluator.chosen, rsvp_request: rsvp_request, rsvp_slot: slot)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
|
@ -757,7 +757,7 @@ FactoryGirl.define do
|
|||
factory :jam_track_mixdown, :class => JamRuby::JamTrackMixdown do
|
||||
association :user, factory: :user
|
||||
association :jam_track, factory: :jam_track
|
||||
sequence(:name) { |n| "mixdown-#{n}"}
|
||||
sequence(:name) { |n| "mixdown-#{n}" }
|
||||
settings '{"speed":5}'
|
||||
end
|
||||
|
||||
|
|
@ -830,16 +830,16 @@ FactoryGirl.define do
|
|||
|
||||
factory :sale, :class => JamRuby::Sale do
|
||||
order_total 0
|
||||
association :user, factory:user
|
||||
association :user, factory: user
|
||||
end
|
||||
|
||||
factory :recurly_transaction_web_hook, :class => JamRuby::RecurlyTransactionWebHook do
|
||||
|
||||
transaction_type JamRuby::RecurlyTransactionWebHook::SUCCESSFUL_PAYMENT
|
||||
sequence(:recurly_transaction_id ) { |n| "recurly-transaction-id-#{n}" }
|
||||
sequence(:subscription_id ) { |n| "subscription-id-#{n}" }
|
||||
sequence(:invoice_id ) { |n| "invoice-id-#{n}" }
|
||||
sequence(:invoice_number ) { |n| 1000 + n }
|
||||
sequence(:recurly_transaction_id) { |n| "recurly-transaction-id-#{n}" }
|
||||
sequence(:subscription_id) { |n| "subscription-id-#{n}" }
|
||||
sequence(:invoice_id) { |n| "invoice-id-#{n}" }
|
||||
sequence(:invoice_number) { |n| 1000 + n }
|
||||
invoice_number_prefix nil
|
||||
action 'purchase'
|
||||
status 'success'
|
||||
|
|
@ -890,7 +890,7 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
factory :gift_card, class: 'JamRuby::GiftCard' do
|
||||
sequence(:code) {n.to_s}
|
||||
sequence(:code) { n.to_s }
|
||||
card_type JamRuby::GiftCardType::JAM_TRACKS_5
|
||||
end
|
||||
|
||||
|
|
@ -907,8 +907,8 @@ FactoryGirl.define do
|
|||
|
||||
association :user, factory: :user
|
||||
|
||||
sequence(:serial_no ) { |n| "serial_no#{n}" }
|
||||
sequence(:client_id ) { |n| "client_id#{n}" }
|
||||
sequence(:serial_no) { |n| "serial_no#{n}" }
|
||||
sequence(:client_id) { |n| "client_id#{n}" }
|
||||
end
|
||||
|
||||
factory :jamblaster_pairing_request, class: 'JamRuby::JamblasterPairingRequest' do
|
||||
|
|
@ -916,13 +916,13 @@ FactoryGirl.define do
|
|||
association :user, factory: :user
|
||||
association :jamblaster, factory: :jamblaster
|
||||
|
||||
sequence(:jamblaster_client_id ) { |n| "jamblaster_client_id#{n}" }
|
||||
sequence(:sibling_key ) { |n| "sibling_key#{n}" }
|
||||
sequence(:jamblaster_client_id) { |n| "jamblaster_client_id#{n}" }
|
||||
sequence(:sibling_key) { |n| "sibling_key#{n}" }
|
||||
end
|
||||
|
||||
factory :school, class: 'JamRuby::School' do
|
||||
association :user, factory: :user
|
||||
sequence(:name) {|n| "Dat Music School"}
|
||||
sequence(:name) { |n| "Dat Music School" }
|
||||
enabled true
|
||||
scheduling_communication 'teacher'
|
||||
end
|
||||
|
|
@ -931,16 +931,16 @@ FactoryGirl.define do
|
|||
association :school, factory: :school
|
||||
note "hey come in in"
|
||||
as_teacher true
|
||||
sequence(:email) {|n| "school_person#{n}@example.com"}
|
||||
sequence(:first_name) {|n| "FirstName"}
|
||||
sequence(:last_name) {|n| "LastName"}
|
||||
sequence(:email) { |n| "school_person#{n}@example.com" }
|
||||
sequence(:first_name) { |n| "FirstName" }
|
||||
sequence(:last_name) { |n| "LastName" }
|
||||
accepted false
|
||||
end
|
||||
|
||||
factory :lesson_booking_slot, class: 'JamRuby::LessonBookingSlot' do
|
||||
factory :lesson_booking_slot_single do
|
||||
slot_type 'single'
|
||||
preferred_day {Date.today + 3}
|
||||
preferred_day { Date.today + 3 }
|
||||
day_of_week nil
|
||||
hour 12
|
||||
minute 30
|
||||
|
|
@ -994,8 +994,8 @@ FactoryGirl.define do
|
|||
student nil
|
||||
end
|
||||
|
||||
music_session {FactoryGirl.create(:music_session, creator: student)}
|
||||
lesson_booking {FactoryGirl.create(:lesson_booking, user: student, teacher: teacher)}
|
||||
music_session { FactoryGirl.create(:music_session, creator: student) }
|
||||
lesson_booking { FactoryGirl.create(:lesson_booking, user: student, teacher: teacher) }
|
||||
association :teacher, factory: :teacher_user
|
||||
lesson_type JamRuby::LessonSession::LESSON_TYPE_SINGLE
|
||||
duration 30
|
||||
|
|
@ -1055,15 +1055,63 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
factory :email_blacklist, class: "JamRuby::EmailBlacklist" do
|
||||
sequence(:email) { |n| "person_#{n}@example.com"}
|
||||
sequence(:email) { |n| "person_#{n}@example.com" }
|
||||
end
|
||||
|
||||
factory :music_notation, class: "JamRuby::MusicNotation" do
|
||||
attachment_type {JamRuby::MusicNotation::TYPE_NOTATION}
|
||||
attachment_type { JamRuby::MusicNotation::TYPE_NOTATION }
|
||||
association :user, factory: :user
|
||||
file_url 'abc'
|
||||
size 100
|
||||
file_name 'some_file.jpg'
|
||||
end
|
||||
|
||||
factory :test_drive_package, class: "JamRuby::TestDrivePackage" do
|
||||
|
||||
sequence(:name) { |n| "package-#{n}" }
|
||||
|
||||
trait :one_pack do
|
||||
package_type 1
|
||||
after(:create) do |package, evaluator|
|
||||
1.times.each do
|
||||
FactoryGirl.create(:test_drive_package_teachers, test_drive_package: package)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
trait :two_pack do
|
||||
package_type 2
|
||||
after(:create) do |package, evaluator|
|
||||
2.times.each do
|
||||
FactoryGirl.create(:test_drive_package_teachers, test_drive_package: package)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
trait :four_pack do
|
||||
package_type 4
|
||||
after(:create) do |package, evaluator|
|
||||
4.times.each do
|
||||
FactoryGirl.create(:test_drive_package_teachers, test_drive_package: package)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
factory :test_drive_package_teachers, class: "JamRuby::TestDrivePackageTeacher" do
|
||||
association :user, factory: :teacher_user
|
||||
association :test_drive_package, factory: [:test_drive_package, :four_pack]
|
||||
end
|
||||
|
||||
factory :test_drive_package_choice, class: "JamRuby::TestDrivePackageChoice" do
|
||||
association :user, factory: :user
|
||||
association :test_drive_package, factory: [:test_drive_package, :four_pack]
|
||||
end
|
||||
|
||||
factory :test_drive_package_choice_teacher, class: "JamRuby::TestDrivePackageChoiceTeacher" do
|
||||
association :teacher, factory: :teacher_user
|
||||
association :test_drive_package_choice, factory: :test_drive_package_choice
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe TestDrivePackageChoice do
|
||||
|
||||
it "works" do
|
||||
|
||||
choice = FactoryGirl.create(:test_drive_package_choice)
|
||||
choice.test_drive_package.package_type.should eql 4
|
||||
choice.test_drive_package.test_drive_package_teachers.count.should eql 4
|
||||
|
||||
teacher_choice = FactoryGirl.create(:test_drive_package_choice_teacher, test_drive_package_choice: choice)
|
||||
teacher_choice.test_drive_package_choice.should eql choice
|
||||
end
|
||||
end
|
||||
|
|
@ -38,7 +38,7 @@ require 'timecop'
|
|||
require 'resque_spec/scheduler'
|
||||
|
||||
# uncomment this to see active record logs
|
||||
ActiveRecord::Base.logger = Logger.new(STDOUT) if defined?(ActiveRecord::Base)
|
||||
# ActiveRecord::Base.logger = Logger.new(STDOUT) if defined?(ActiveRecord::Base)
|
||||
|
||||
include JamRuby
|
||||
|
||||
|
|
|
|||
|
|
@ -305,6 +305,9 @@ def app_config
|
|||
:ach_pct => 0.008
|
||||
}
|
||||
end
|
||||
def musician_count
|
||||
'40,000+'
|
||||
end
|
||||
private
|
||||
|
||||
def audiomixer_workspace_path
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@
|
|||
}
|
||||
|
||||
function handleGettingStarted(app) {
|
||||
/**
|
||||
var user = app.user()
|
||||
if(user) {
|
||||
user.done(function(userProfile) {
|
||||
|
|
@ -226,7 +227,7 @@
|
|||
app.layout.showDialog('getting-started');
|
||||
}
|
||||
})
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
function initShoppingCart(app) {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,10 @@
|
|||
callback(container.find('.note').val(), container.find('.email').val(), container.find('.phonenumber').val())
|
||||
return false;
|
||||
})
|
||||
console.log("hehelllo!")
|
||||
}})
|
||||
}
|
||||
|
||||
helpBubble.testDrivePackageGo = function($element, $offsetParent, package_type) {
|
||||
return context.JK.prodBubble($element, 'test-drive-package-go', {plural: package_type != '1'}, bigHelpDarkOptions({offsetParent:$offsetParent, width:260, positions:['bottom']}))
|
||||
}
|
||||
})(window, jQuery);
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
context = window
|
||||
@TestDrivePackageDialog = React.createClass({
|
||||
|
||||
mixins: [Reflux.listenTo(@AppStore, "onAppInit")]
|
||||
teacher: null
|
||||
|
||||
beforeShow: (args) ->
|
||||
# d1 should be a teacher ID (vs a user ID that happens to be a teacher)
|
||||
logger.debug("TestDrivePackageDialog.beforeShow", args.d1)
|
||||
@setState({target: args.d1, page_data: window.page_data})
|
||||
|
||||
|
||||
afterHide: () ->
|
||||
|
||||
onAppInit: (@app) ->
|
||||
dialogBindings = {
|
||||
'beforeShow': @beforeShow,
|
||||
'afterHide': @afterHide
|
||||
};
|
||||
|
||||
@app.bindDialog('test-drive-package-dialog', dialogBindings);
|
||||
|
||||
getInitialState: () ->
|
||||
{
|
||||
target: null,
|
||||
page_data: null
|
||||
}
|
||||
|
||||
|
||||
componentDidMount: () ->
|
||||
@root = $(@getDOMNode())
|
||||
|
||||
doCancel: (e) ->
|
||||
e.preventDefault()
|
||||
@app.layout.closeDialog('test-drive-package-dialog', true);
|
||||
|
||||
selectTeachers: (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
# validate
|
||||
|
||||
if @state.target == '2'
|
||||
checked = @root.find('input[type="checkbox"]:checked')
|
||||
|
||||
if checked.length != 2
|
||||
context.JK.Banner.showNotice('hold on there', 'Please select 2 teachers.')
|
||||
return
|
||||
|
||||
if @state.target == '1'
|
||||
checked = @root.find('input[type="checkbox"]:checked')
|
||||
|
||||
if checked.length != 1
|
||||
context.JK.Banner.showNotice('hold on there', 'Please select a teacher.')
|
||||
return
|
||||
|
||||
teachers = []
|
||||
$.each(checked, (i, node) => (
|
||||
$node = $(node)
|
||||
teachers.push($node.data('teacher'))
|
||||
))
|
||||
@root.data('result', { package_type: @state.target, teachers: teachers })
|
||||
render: () ->
|
||||
|
||||
if @state.target == '2'
|
||||
help =
|
||||
`<p>
|
||||
Check the boxes under the 2 instructors you want to select for your TestDrive package. Then click the Select button below.
|
||||
</p>`
|
||||
else
|
||||
help =
|
||||
`<p>
|
||||
Check the box under the instructor you want to select for your TestDrive package. Then click the Select button below.
|
||||
</p>`
|
||||
|
||||
teachers = []
|
||||
|
||||
|
||||
`<div>
|
||||
<div className="content-head">
|
||||
<img className="content-icon" src="/assets/content/icon_add.png" height={19} width={19}/>
|
||||
|
||||
<h1>select instructors</h1>
|
||||
</div>
|
||||
<div className="dialog-inner">
|
||||
|
||||
{help}
|
||||
|
||||
{teachers}
|
||||
|
||||
<div className="actions">
|
||||
<a onClick={this.doCancel} className="button-grey">CANCEL</a>
|
||||
<a onClick={this.selectTeachers} className="button-orange select-teachers">SELECT</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
})
|
||||
|
|
@ -72,7 +72,7 @@ rest = context.JK.Rest()
|
|||
|
||||
JamKazam has developed incredibly unique and engaging digital music technologies, content,
|
||||
|
||||
and marketplaces used by our rapidly growing community of 30,000+ musicians. Now we’ve
|
||||
and marketplaces used by our rapidly growing community of {gon.global.musician_count} musicians. Now we’ve
|
||||
|
||||
crafted an affiliate program specifically for music stores and music schools to increase your
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
@JamClassStudentLandingMiddlePage = React.createClass({
|
||||
|
||||
avatar: (name = 'your choice', photo_url = '/assets/shared/avatar_generic.png') ->
|
||||
`<div className="avatar-header">
|
||||
<div className="avatar">
|
||||
<img src={photo_url}/>
|
||||
</div>
|
||||
<div className="username">
|
||||
{name}
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
getInitialState: () ->
|
||||
{
|
||||
modified: false
|
||||
package_type: null
|
||||
teachers: null
|
||||
}
|
||||
|
||||
selector: (count, e) ->
|
||||
e.preventDefault()
|
||||
|
||||
context.JK.app.layout.showDialog('test-drive-package-dialog').one(contexnt.JK.EVENTS.DIALOG_CLOSED, (e, data) =>
|
||||
#... code
|
||||
if !data.canceled
|
||||
console.log("dialog closed. result", data.result)
|
||||
# dialog wasn't cancelled, so let's check the value of our result:
|
||||
@setState(data.result)
|
||||
|
||||
|
||||
setTimeout((() => context.JK.prodBubble($('.preview-area.jam-class'), 'body', data.result.package_type)), 1500)
|
||||
)
|
||||
|
||||
componentDidMount: () ->
|
||||
@root = $(@getDOMNode())
|
||||
@root.find('.bio p').dotdotdot()
|
||||
|
||||
componentDidUpdate:( ) ->
|
||||
|
||||
@root.find('.bio p').dotdotdot()
|
||||
render: () ->
|
||||
|
||||
if this.props.package?
|
||||
|
||||
package_type = this.state.package_type || this.props.package.package_type
|
||||
|
||||
if package_type == '4'
|
||||
description =
|
||||
`<div>
|
||||
<p>The single most important factor in the success of your music lessons is your teacher. You wouldn't marry
|
||||
the first person you date, right?</p>
|
||||
|
||||
<p>Take full 30-minute lessons from each of these 4 amazing teachers for just $12.50 each - a total of
|
||||
$49.99. Then you can pick the one who is best for you to continue your musical journey, with the
|
||||
confidence that your investment in lessons will deliver maximum growth!</p>
|
||||
</div>`
|
||||
|
||||
options =
|
||||
`<div className="other-options">
|
||||
<p>Like the TestDrive concept, but 4 teachers is too many for you?</p>
|
||||
<ul>
|
||||
<li>Get a special offer of <a onClick={this.selector.bind(this, 2)}>2 of these teachers for a total of $29.99</a>.</li>
|
||||
<li>Or <a onClick={this.selector.bind(this, 1)}>1 teacher for $14.99</a>.</li>
|
||||
<li>Or you can <a href="/client#/jamclass/searchOptions">search all of our teachers</a> and then book a TestDrive package.</li>
|
||||
</ul>
|
||||
</div>`
|
||||
else if package_type == '2'
|
||||
description =
|
||||
`<div>
|
||||
<p>The single most important factor in the success of your music lessons is your teacher. You wouldn't marry
|
||||
the first person you date, right?</p>
|
||||
|
||||
<p>Take full 30-minute lessons from each of these 2 amazing teachers for just $14.99 each - a total of
|
||||
$29.99. Then you can pick the one who is best for you to continue your musical journey, with the
|
||||
confidence that your investment in lessons will deliver maximum growth!</p>
|
||||
</div>`
|
||||
|
||||
options =
|
||||
`<div className="other-options">
|
||||
<p>Like the TestDrive concept, but prefer not to try 2 different teachers?</p>
|
||||
<ul>
|
||||
<li>Get a special offer of <a onClick={this.selector.bind(this, 1)}>1 of these teachers for just $14.99</a>. </li>
|
||||
<li>Or you can <a href="/client#/jamclass/searchOptions">search all of our teachers</a> and then book a TestDrive package.</li>
|
||||
</ul>
|
||||
</div>`
|
||||
else
|
||||
description =
|
||||
`<div>
|
||||
<p>Take a full 30-minute lesson from this great teacher for just $14.99 - half the cost of a typical music
|
||||
lesson. You can make sure everything is working great, and then continue your musical journey with the
|
||||
confidence that your investment in lessons will deliver maximum growth!</p>
|
||||
</div>`
|
||||
options =
|
||||
`<div className="other-options">
|
||||
<p>You can book a TestDrive lesson with this awesome teacher now!</p>
|
||||
<p>Or you can <a href="/client#/jamclass/searchOptions">search all of our teachers</a> and then book a TestDrive package.</p>
|
||||
</div>`
|
||||
|
||||
teacherList = @state.teachers || this.props.package.teachers
|
||||
|
||||
if @state.modified
|
||||
options = null
|
||||
|
||||
teachers = []
|
||||
for teacher in teacherList
|
||||
biography = teacher.biography
|
||||
biography = biography.replace(/\n/g, "<br/>")
|
||||
teachers.push(
|
||||
`<div key={teacher.id} className="teacher-option">
|
||||
{this.avatar(teacher.name, teacher.photo_url)}
|
||||
<div className="bio">
|
||||
<p dangerouslySetInnerHTML={{__html: biography}}></p>
|
||||
</div>
|
||||
</div>`)
|
||||
|
||||
`<div className="row cta-row packaged">
|
||||
<h2>SIGN UP FOR TESTDRIVE NOW!</h2>
|
||||
{description}
|
||||
|
||||
{teachers}
|
||||
|
||||
{options}
|
||||
</div>`
|
||||
else
|
||||
`<div className="row cta-row">
|
||||
<h2>SIGN UP FOR TESTDRIVE NOW!</h2>
|
||||
|
||||
<p>The single most important factor in the success of your music lessons is your teacher. You wouldn't marry the
|
||||
first person you date, right? Our TestDrive program lets you:</p>
|
||||
<ul>
|
||||
<li>Take a full lesson from 4 different teachers for just $12.49 each, or</li>
|
||||
<li>Take a full lesson from 2 different teachers for just $14.99 each, or</li>
|
||||
<li>Take a full lesson from 1 teacher for just $14.99</li>
|
||||
</ul>
|
||||
|
||||
<p className="bump">Then continue your lessons with the best teacher for you!</p>
|
||||
|
||||
<p className="bump">Join 40,000+ other musicians in the JamKazam community. Sign up for TestDrive today, and
|
||||
you'll be eligible for any of the three special offers above!</p>
|
||||
|
||||
<p className="cta-text">Not sure if this is for you? Scroll down to learn more...</p>
|
||||
</div>`
|
||||
})
|
||||
|
|
@ -143,7 +143,7 @@ rest = context.JK.Rest()
|
|||
rest.updateUser({student: true})
|
||||
.done((response) =>
|
||||
this.setState({done: true})
|
||||
context.location = '/client#/profile/' + context.JK.currentUserId
|
||||
context.location = '/client#/jamclass/searchOptions'
|
||||
)
|
||||
.fail((jqXHR) =>
|
||||
this.setState({processing: false})
|
||||
|
|
@ -159,7 +159,7 @@ rest = context.JK.Rest()
|
|||
rest.signup({email: email, password: password, first_name: null, last_name: null, terms: terms, student: true})
|
||||
.done((response) =>
|
||||
@setState({done: true})
|
||||
context.location = '/client#/profile/' + response.id
|
||||
context.location = '/client#/jamclass/searchOptions'
|
||||
).fail((jqXHR) =>
|
||||
@setState({processing: false})
|
||||
if jqXHR.status == 422
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ context = window
|
|||
<div className="awesome-item">
|
||||
<h3>Why Did We Design and Build the JamBlaster?</h3>
|
||||
<h4>Speed</h4>
|
||||
<p>When we initially built the free JamKazam service to let musicians play together live over the Internet, we started by having musicians use the Mac and Windows computers and audio interfaces they already own. We've signed up 30,000+ musicians along the way. We've analyzed data from more than 100,000 online sessions. And we've collected audio processing latency data on thousands of combinations of computers and interfaces, as well as 10 million Internet latency measurements between unique pairs of locations and ISPs. We've learned a lot from all this data. </p>
|
||||
<p>When we initially built the free JamKazam service to let musicians play together live over the Internet, we started by having musicians use the Mac and Windows computers and audio interfaces they already own. We've signed up {gon.global.musician_count} musicians along the way. We've analyzed data from more than 100,000 online sessions. And we've collected audio processing latency data on thousands of combinations of computers and interfaces, as well as 10 million Internet latency measurements between unique pairs of locations and ISPs. We've learned a lot from all this data. </p>
|
||||
<p>Typically you need to keep total one way latency down to 30 to 35 milliseconds or less in an online session, or the session will get too sloppy and fall apart. We found that the average audio processing latency of industry standard gear is 14 milliseconds (full round trip including analog-to-digital and digital-to-analog conversions). <b>So just processing the audio eats up half of your total latency budget!</b></p>
|
||||
<p>We designed the JamBlaster from the ground up to be the fastest audio processing device possible, and we have the JamBlaster running at 2.8 milliseconds of latency full round trip - a massive latency savings. Every one millisecond saved on audio processing is worth about 100 miles of range on the Internet backbone. The JamBlaster also reduces something called audio processing jitter, which delivers additional latency savings. The result is that <b>the JamBlaster saves audio latency equivalent to about 1,500 miles of distance compared to today's standard computers and interfaces.</b></p>
|
||||
<p>Looking at it another way, using JamKazam with standard computers and interfaces, a musician in the U.S. can play effectively with about 10% of the other musicians in the U.S. <b>With the JamBlaster, that same musician can now play with about 35% of the other musicians in the U.S.</b></p>
|
||||
|
|
@ -206,7 +206,7 @@ context = window
|
|||
<div className="row awesome-thing">
|
||||
<div className="awesome-item">
|
||||
<h3>The JamBlaster Plugs Into The JamKazam Platform And Community</h3>
|
||||
<p>JamKazam has already signed up 30,000+ musicians who play in thousands of online sessions per month using their computers and audio interfaces. The JamBlaster interoperates seamlessly with other musicians who are running Mac and Windows PC setups, so you can jump right in and start playing with other musicians in the community using your JamBlaster from day one.</p>
|
||||
<p>JamKazam has already signed up {gon.global.musician_count} musicians who play in thousands of online sessions per month using their computers and audio interfaces. The JamBlaster interoperates seamlessly with other musicians who are running Mac and Windows PC setups, so you can jump right in and start playing with other musicians in the community using your JamBlaster from day one.</p>
|
||||
<img src="/assets/landing/find_musicians.png" />
|
||||
<div className="clearall"/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -82,13 +82,13 @@ ConfigureTracksActions = @ConfigureTracksActions
|
|||
this.trigger(@helper)
|
||||
|
||||
onWindowBackgrounded: () ->
|
||||
@app.user()
|
||||
.done((userProfile) =>
|
||||
if userProfile.show_whats_next &&
|
||||
window.location.pathname.indexOf(gon.client_path) == 0 &&
|
||||
!@app.layout.isDialogShowing('getting-started')
|
||||
@app.layout.showDialog('getting-started')
|
||||
)
|
||||
#@app.user()
|
||||
#.done((userProfile) =>
|
||||
#if userProfile.show_whats_next &&
|
||||
# window.location.pathname.indexOf(gon.client_path) == 0 &&
|
||||
# !@app.layout.isDialogShowing('getting-started')
|
||||
# @app.layout.showDialog('getting-started')
|
||||
#)
|
||||
|
||||
return unless @inSession()
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
//= require jquery.bt
|
||||
//= require jquery.exists
|
||||
//= require jquery.visible
|
||||
//= require jquery.lessonSessionActions
|
||||
//= require howler.core.js
|
||||
//= require AAA_Log
|
||||
//= require AAC_underscore
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -18,17 +18,17 @@ class ApplicationController < ActionController::Base
|
|||
before_filter :track_affiliate_visits
|
||||
before_filter :track_origin
|
||||
|
||||
before_filter do
|
||||
if params[AffiliatePartner::PARAM_REFERRAL].present? && current_user.nil?
|
||||
if cookies[AffiliatePartner::PARAM_COOKIE].blank?
|
||||
code = params[AffiliatePartner::PARAM_REFERRAL].downcase
|
||||
cookies[AffiliatePartner::PARAM_COOKIE] = code if AffiliatePartner.is_code?(code)
|
||||
end
|
||||
end
|
||||
end
|
||||
#before_filter do
|
||||
# if params[AffiliatePartner::PARAM_REFERRAL].present? && current_user.nil?
|
||||
# if cookies[AffiliatePartner::PARAM_COOKIE].blank?
|
||||
# code = params[AffiliatePartner::PARAM_REFERRAL].downcase
|
||||
# cookies[AffiliatePartner::PARAM_COOKIE] = code if AffiliatePartner.is_code?(code)
|
||||
# end
|
||||
# end
|
||||
#end
|
||||
|
||||
def affiliate_code
|
||||
cookies[AffiliatePartner::PARAM_COOKIE]
|
||||
#cookies[AffiliatePartner::PARAM_COOKIE]
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,28 @@ class LandingsController < ApplicationController
|
|||
@show_after_black_bar_border = true
|
||||
@free = false
|
||||
|
||||
@page_data = {free: @free}
|
||||
package_name = params['utm-teachers']
|
||||
if package_name
|
||||
package = TestDrivePackage.find_by_name(package_name)
|
||||
|
||||
if package
|
||||
package_data = {}
|
||||
package_data[:id] = package.id
|
||||
package_data[:name] = package.name
|
||||
package_data[:package_type] = package.package_type
|
||||
teachers = []
|
||||
package.test_drive_package_teachers.each do |package_teacher|
|
||||
teacher = package_teacher.user
|
||||
teachers.push({id: teacher.id, name: teacher.name, biography: teacher.teacher.biography, photo_url: teacher.photo_url})
|
||||
end
|
||||
package_data[:teachers] = teachers
|
||||
|
||||
@package_data = package_data
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@page_data = {free: @free, package: @package_data}
|
||||
|
||||
render 'jam_class_students', layout: 'web'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -465,3 +465,12 @@ script type="text/template" id="template-help-ftue-step-4-instructions"
|
|||
script type="text/template" id="template-help-ftue-step-5-instructions"
|
||||
.ftue-step-5-instructions.big-dark-help
|
||||
p Please click here for detailed instructions to successfully complete this setup step.
|
||||
|
||||
script type="text/template" id="template-help-test-drive-package-go"
|
||||
.test-drive-package-go
|
||||
p
|
||||
| {% if(data.plural) { %}
|
||||
| Enter your email and a password, and click Sign Up to pay for and book your lesson with these awesome teachers!
|
||||
| {% } else { %}
|
||||
| Enter your email and a password, and click Sign Up to pay for and book your lesson with this awesome teacher!
|
||||
| {% } %}
|
||||
|
|
@ -55,3 +55,4 @@
|
|||
= render 'dialogs/rescheduleLessonDialog'
|
||||
= render 'dialogs/rateUserDialog'
|
||||
= render 'dialogs/musicNotationUploadDialog'
|
||||
= render 'dialogs/testDrivePackageDialog'
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
.dialog.dialog-overlay-sm.top-parent layout='dialog' layout-id='test-drive-package-dialog' id='test-drive-package-dialog'
|
||||
= react_component 'TestDrivePackageDialog', {}
|
||||
|
|
@ -7,7 +7,10 @@
|
|||
- content_for :after_black_bar do
|
||||
.row.cta-row
|
||||
h2 GET YOUR GIFT CARD NOW!
|
||||
p And join 30,000+ other musicians who love our JamTracks.
|
||||
p
|
||||
| And join
|
||||
= APP_CONFIG.musician_count
|
||||
| other musicians who love our JamTracks.
|
||||
p.cta-text Not sure if JamTracks are for you? Scroll down to learn more.
|
||||
|
||||
- content_for :white_bar do
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@
|
|||
- content_for :after_black_bar do
|
||||
.row.cta-row
|
||||
h2 GET THIS JAMTRACK FREE NOW!
|
||||
p And join 30,000+ other musicians who love our JamTracks.
|
||||
p
|
||||
| And join
|
||||
= APP_CONFIG.musician_count
|
||||
| other musicians who love our JamTracks.
|
||||
p.cta-text Not sure if JamTracks are for you? Scroll down to learn more.
|
||||
|
||||
- content_for :white_bar do
|
||||
|
|
|
|||
|
|
@ -5,20 +5,7 @@
|
|||
= react_component 'JamClassStudentLandingPage', @page_data.to_json
|
||||
|
||||
- content_for :after_black_bar do
|
||||
.row.cta-row
|
||||
- if @free
|
||||
h2 SIGN UP FOR YOUR FREE LESSON NOW!
|
||||
- else
|
||||
h2 SIGN UP FOR TESTDRIVE NOW!
|
||||
p
|
||||
| The single most important factor in the success of your music lessons is your teacher. You wouldn't marry the first person you date, right? Our TestDrive program lets you:
|
||||
ul
|
||||
li Take a full lesson from 4 different teachers for just $12.49 each, or
|
||||
li Take a full lesson from 2 different teachers for just $14.99 each, or
|
||||
li Take a full lesson from 1 teacher for just $14.99
|
||||
p.bump Then continue your lessons with the best teacher for you!
|
||||
p.bump Join 40,000+ other musicians in the JamKazam community. Sign up for TestDrive today, and you'll be eligible for any of the three special offers above!
|
||||
p.cta-text Not sure if this is for you? Scroll down to learn more...
|
||||
= react_component 'JamClassStudentLandingMiddlePage', @page_data.to_json
|
||||
|
||||
- content_for :white_bar do
|
||||
= react_component 'JamClassStudentLandingBottomPage', @page_data.to_json
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@
|
|||
- content_for :after_black_bar do
|
||||
.row.cta-row
|
||||
h2 SIGN UP TO TEACH NOW, IT'S FREE!
|
||||
p And join 30,000+ other musicians in the JamKazam community.
|
||||
p
|
||||
| And join
|
||||
= APP_CONFIG.musician_count
|
||||
| other musicians in the JamKazam community.
|
||||
p.cta-text Not sure if JamClass is for you? Scroll down to learn more.
|
||||
|
||||
- content_for :white_bar do
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@
|
|||
<%= render "clients/listenBroadcast" %>
|
||||
<%= render "clients/flash" %>
|
||||
<%= render "clients/jam_track_preview" %>
|
||||
<%= render "clients/help" %>
|
||||
<%= render "clients/lessonSessionActions" %>
|
||||
<%= render 'dialogs/dialogs' %>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ if defined?(Bundler)
|
|||
config.kickbox_api_key = 'e262991e292dd5fe382c4a69f2b359f718cf267712b8684c9c28d6402ec18965'
|
||||
config.check_bounced_emails = false
|
||||
config.ban_jamtrack_downloaders = true
|
||||
config.chat_opened_by_default = true
|
||||
config.chat_opened_by_default = false
|
||||
config.chat_blast = true
|
||||
config.use_ios_sandbox = true
|
||||
config.stripe = {
|
||||
|
|
@ -439,5 +439,6 @@ if defined?(Bundler)
|
|||
config.end_of_wait_window_forgiveness_minutes = 1
|
||||
config.olark_enabled = true
|
||||
config.jamclass_enabled = false
|
||||
config.musician_count = '40,000+'
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,4 +25,5 @@ Gon.global.bugsnag_notify_release_stages = Rails.application.config.bugsnag_noti
|
|||
Gon.global.vst_enabled = Rails.application.config.vst_enabled
|
||||
Gon.global.chat_opened_by_default = Rails.application.config.chat_opened_by_default
|
||||
Gon.global.network_test_required = Rails.application.config.network_test_required
|
||||
Gon.global.musician_count = Rails.application.config.musician_count
|
||||
Gon.global.env = Rails.env
|
||||
|
|
|
|||
|
|
@ -32,8 +32,7 @@ describe "Student Landing", :js => true, :type => :feature, :capybara_feature =>
|
|||
find('.register-area ins', visible: false).trigger(:click)
|
||||
find('button.cta-button', text: 'SIGN UP').trigger(:click)
|
||||
|
||||
# this should show on the /client#/home page (WILL CHANGE)
|
||||
find('h1', text: 'musician profile')
|
||||
find('h3', text: 'Student Levels Taught:')
|
||||
|
||||
user = User.find_by_email('student_123@jamkazam.com')
|
||||
user.is_a_student.should be true
|
||||
|
|
@ -61,8 +60,7 @@ describe "Student Landing", :js => true, :type => :feature, :capybara_feature =>
|
|||
find('.register-area ins', visible: false) .trigger(:click)
|
||||
find('button.cta-button', text: 'SIGN UP').trigger(:click)
|
||||
|
||||
# this should show on the /client#/home page (WILL CHANGE)
|
||||
find('h1', text: 'musician profile')
|
||||
find('h3', text: 'Student Levels Taught:')
|
||||
|
||||
user = User.find_by_email('student_125@jamkazam.com')
|
||||
user.is_a_student.should be true
|
||||
|
|
@ -83,8 +81,7 @@ describe "Student Landing", :js => true, :type => :feature, :capybara_feature =>
|
|||
|
||||
find('button.cta-button', text: 'TRY TESTDRIVE').trigger(:click)
|
||||
|
||||
# this should show on the /client#/home page (WILL CHANGE)
|
||||
find('h1', text: 'musician profile')
|
||||
find('h3', text: 'Student Levels Taught:')
|
||||
|
||||
user.reload
|
||||
user.is_a_student.should be true
|
||||
|
|
|
|||
|
|
@ -144,6 +144,10 @@ def web_config
|
|||
}
|
||||
end
|
||||
|
||||
def musician_count
|
||||
'40,000+'
|
||||
end
|
||||
|
||||
def email_partners_alias
|
||||
"partner-dev@jamkazam.com"
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue