diff --git a/admin/app/admin/interested_retailers.rb b/admin/app/admin/interested_retailers.rb new file mode 100644 index 000000000..1d184807f --- /dev/null +++ b/admin/app/admin/interested_retailers.rb @@ -0,0 +1,20 @@ +ActiveAdmin.register JamRuby::User, :as => 'RetailerInterest' do + + menu :label => 'Interested in Retailers', :parent => 'JamClass' + + config.sort_order = 'created_at desc' + config.batch_actions = false + config.per_page = 100 + config.paginate = true + config.filters = false + + scope("All", default: true) { |scope| scope.where(retailer_interest: true) } + + index do + column "Name" do |user| + span do + link_to "#{user.name} (#{user.email})", "#{Rails.application.config.external_root_url}/client#/profile/#{user.id}" + end + end + end +end \ No newline at end of file diff --git a/admin/app/admin/sale_line_items.rb b/admin/app/admin/sale_line_items.rb index fa90ffc4e..c64862611 100644 --- a/admin/app/admin/sale_line_items.rb +++ b/admin/app/admin/sale_line_items.rb @@ -25,7 +25,9 @@ ActiveAdmin.register JamRuby::SaleLineItem, :as => 'Sale Line Items' do link_to("#{oo.affiliate_referral.display_name} #{oo.affiliate_referral_fee_in_cents ? "#{oo.affiliate_referral_fee_in_cents}\u00A2" : ''}", oo.affiliate_referral.admin_url, {:title => oo.affiliate_referral.display_name}) if oo.affiliate_referral end column 'User' do |oo| - link_to(oo.sale.user.name, admin_user_path(oo.sale.user.id), {:title => oo.sale.user.name}) + if oo.sale.user + link_to(oo.sale.user.name, admin_user_path(oo.sale.user.id), {:title => oo.sale.user.name}) + end end column 'Source' do |oo| oo.sale.source diff --git a/db/manifest b/db/manifest index eafff9a41..5a9ba3bbd 100755 --- a/db/manifest +++ b/db/manifest @@ -367,4 +367,5 @@ non_free_jamtracks.sql retailers.sql second_ed.sql second_ed_v2.sql -retailers_v2.sql \ No newline at end of file +retailers_v2.sql +retailer_interest.sql \ No newline at end of file diff --git a/db/up/retailer_interest.sql b/db/up/retailer_interest.sql new file mode 100644 index 000000000..7be2a8290 --- /dev/null +++ b/db/up/retailer_interest.sql @@ -0,0 +1,2 @@ +ALTER TABLE users ADD COLUMN retailer_interest BOOLEAN DEFAULT FALSE NOT NULL; +alter table retailers alter column slug drop not null; \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb index b8835b7bf..3969ccdb4 100644 --- a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb +++ b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb @@ -117,6 +117,23 @@ module JamRuby format.html end end + + def retailer_owner_welcome_message(user) + @user = user + @subject= "Welcome to JamKazam and JamClass online lessons!" + sendgrid_category "Welcome" + sendgrid_unique_args :type => "welcome_message" + + sendgrid_recipients([user.email]) + sendgrid_substitute('@USERID', [user.id]) + sendgrid_substitute(EmailBatchProgression::VAR_FIRST_NAME, [user.first_name]) + + mail(:to => user.email, :subject => @subject) do |format| + format.text + format.html + end + end + def education_owner_welcome_message(user) @user = user @subject= "Welcome to JamKazam and JamClass online lessons!" diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_customer_blast.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_customer_blast.html.erb index 204701323..a98071d65 100644 --- a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_customer_blast.html.erb +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_customer_blast.html.erb @@ -3,6 +3,6 @@

Click the link of each teacher's profile at <%= @retailer.name %> to find the best fit for you:

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_customer_blast.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_customer_blast.text.erb index 31f1d6f53..4c59f45a4 100644 --- a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_customer_blast.text.erb +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_customer_blast.text.erb @@ -2,5 +2,5 @@ Check out each teacher's profile at <%= @retailer.name %> to find the best fit for you: <% @retailer.teachers.each do |teacher| %> -<%= teacher.user.name %>: <%= teacher.user.teacher_profile_url%> +<%= teacher.user.name %>: <%= teacher.user.teacher_profile_url%> (<%= teacher.teaches %>) <% end %> diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_owner_welcome_message.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_owner_welcome_message.html.erb new file mode 100644 index 000000000..bd71e888a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_owner_welcome_message.html.erb @@ -0,0 +1,14 @@ +<% provide(:title, @subject) %> + + +<% if !@user.anonymous? %> +

Hello <%= EmailBatchProgression::VAR_FIRST_NAME %> -- +

+<% end %> + +

+ Thank you for expressing an interest in exploring our retailer partner program! A member of our staff will reach out to you shortly to chat with you and answer any/all questions you may have about our partner program and our technologies. +

+ +

Best Regards,
+ Team JamKazam

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_owner_welcome_message.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_owner_welcome_message.text.erb new file mode 100644 index 000000000..4a13e9d0a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/retailer_owner_welcome_message.text.erb @@ -0,0 +1,8 @@ +<% if !@user.anonymous? %> +Hello <%= EmailBatchProgression::VAR_FIRST_NAME %> +<% end %> + +Thank you for expressing an interest in exploring our retailer partner program! A member of our staff will reach out to you shortly to chat with you and answer any/all questions you may have about our partner program and our technologies. + +Best Regards, +Team JamKazam \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/posa_card.rb b/ruby/lib/jam_ruby/models/posa_card.rb index affb94efe..f099eafed 100644 --- a/ruby/lib/jam_ruby/models/posa_card.rb +++ b/ruby/lib/jam_ruby/models/posa_card.rb @@ -162,5 +162,20 @@ module JamRuby end end end + + def short_display + if card_type == JAM_TRACKS_5 + 'JT-5' + elsif card_type == JAM_TRACKS_10 + 'JT-10' + elsif card_type == JAM_CLASS_4 + 'JC-4' + else + raise "unknown card type #{card_type}" + end + end + def to_s + "POSA #{short_display} #{code}" + end end end diff --git a/ruby/lib/jam_ruby/models/retailer.rb b/ruby/lib/jam_ruby/models/retailer.rb index d5dd45e61..f6cf94d03 100644 --- a/ruby/lib/jam_ruby/models/retailer.rb +++ b/ruby/lib/jam_ruby/models/retailer.rb @@ -18,13 +18,19 @@ module JamRuby has_many :sale_line_items, class_name: 'JamRuby::SaleLineItem' validates :user, presence: true - validates :slug, presence: true + #validates :slug, presence: true validates :enabled, inclusion: {in: [true, false]} validates_length_of :password, minimum: 6, maximum: 100, :if => :should_validate_password after_create :create_affiliate + after_create :create_slug # before_save :stringify_avatar_info, :if => :updating_avatar + def create_slug + self.slug + self.save! + end + def create_affiliate AffiliatePartner.create_from_retailer(self) end diff --git a/ruby/lib/jam_ruby/models/sale_line_item.rb b/ruby/lib/jam_ruby/models/sale_line_item.rb index d4fda9cff..eb053e144 100644 --- a/ruby/lib/jam_ruby/models/sale_line_item.rb +++ b/ruby/lib/jam_ruby/models/sale_line_item.rb @@ -47,8 +47,11 @@ module JamRuby GiftCardType.find_by_id(product_id) elsif product_type == LESSON lesson_package_purchase + elsif product_type == POSACARD + PosaCard.find(product_id) else + raise 'unsupported product type' end end diff --git a/ruby/lib/jam_ruby/models/teacher.rb b/ruby/lib/jam_ruby/models/teacher.rb index 42b71a9e6..53cab0b24 100644 --- a/ruby/lib/jam_ruby/models/teacher.rb +++ b/ruby/lib/jam_ruby/models/teacher.rb @@ -462,5 +462,15 @@ module JamRuby @part_complete[:pct] = complete.round @part_complete end + + def teaches + if instruments.length == 0 + return '' + elsif instruments.length == 2 + return 'Teaches ' + instruments[0].description + ' and ' + instruments[1].description + else + return 'Teaches ' + instruments.map {|i| i.description}.join(', ') + end + end end end diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index f68cfd525..10b9407ca 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -278,6 +278,15 @@ module JamRuby school.save! end end + + if retailer_interest && !retailer_interest_was + AdminMailer.partner({body: "#{email} signed up via the https://www.jamkazam.com/landing/jamclass/retailer page.\n\nFull list is here: https://www.jamkazam.com/admin/admin/retailer_interests", subject: "#{email} is interested in retailer program"}).deliver_now + if owned_retailer.nil? + retailer = Retailer.new + retailer.user = self + retailer.save! + end + end end def update_teacher_pct if teacher @@ -1138,6 +1147,7 @@ module JamRuby school_id = options[:school_id] retailer_invitation_code = options[:retailer_invitation_code] retailer_id = options[:retailer_id] + retailer_interest = options[:retailer_interest] school_interest = options[:school_interest] education_interest = options[:education_interest] origin = options[:origin] @@ -1182,6 +1192,7 @@ module JamRuby user.has_redeemable_jamtrack = true user.is_a_student = !!student user.is_a_teacher = !!teacher + user.retailer_interest = !!retailer_interest user.school_interest = !!school_interest user.education_interest = !!education_interest if user.is_a_student || user.is_a_teacher @@ -1433,6 +1444,8 @@ module JamRuby UserMailer.education_owner_welcome_message(user).deliver_now elsif user.school_interest UserMailer.school_owner_welcome_message(user).deliver_now + elsif user.retailer_interest + UserMailer.retailer_owner_welcome_message(user).deliver_now else UserMailer.welcome_message(user).deliver_now end diff --git a/ruby/spec/jam_ruby/models/retailer_spec.rb b/ruby/spec/jam_ruby/models/retailer_spec.rb index edd56bc20..e82c741ec 100644 --- a/ruby/spec/jam_ruby/models/retailer_spec.rb +++ b/ruby/spec/jam_ruby/models/retailer_spec.rb @@ -8,6 +8,7 @@ describe Retailer do it "has correct associations" do retailer = FactoryGirl.create(:retailer) + retailer.slug.should eql retailer.id retailer.should eql retailer.user.owned_retailer diff --git a/web/app/assets/javascripts/react-components/landing/JamClassRetailerLandingPage.js.jsx.coffee b/web/app/assets/javascripts/react-components/landing/JamClassRetailerLandingPage.js.jsx.coffee index 6fb662ddc..94fef5e76 100644 --- a/web/app/assets/javascripts/react-components/landing/JamClassRetailerLandingPage.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/landing/JamClassRetailerLandingPage.js.jsx.coffee @@ -128,7 +128,7 @@ rest = context.JK.Rest() markTeacher: () -> - rest.updateUser({school_interest: true}) + rest.updateUser({retailer_interest: true}) .done((response) => this.setState({done: true}) context.location = '/client#/home' @@ -150,7 +150,7 @@ rest = context.JK.Rest() first_name: null, last_name: null, terms: terms, - school_interest: true + retailer_interest: true }) .done((response) => context.location = '/client#/home' diff --git a/web/app/assets/javascripts/react-components/landing/PosaActivationPage.js.jsx.coffee b/web/app/assets/javascripts/react-components/landing/PosaActivationPage.js.jsx.coffee index 2cfc11d6a..7fb9462ce 100644 --- a/web/app/assets/javascripts/react-components/landing/PosaActivationPage.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/landing/PosaActivationPage.js.jsx.coffee @@ -7,6 +7,10 @@ rest = context.JK.Rest() if this.props.retailer.large_photo_url? logo = `
+
+ {this.props.retailer.name} +
+
` ctaButtonText = 'ACTIVATE' @@ -30,7 +34,7 @@ rest = context.JK.Rest() ` posaErrors = context.JK.getFullFirstError(key, this.state.loginErrors, - {code: 'POSA Card', activated_at: 'POSA Card', claimed_at: 'Claimed', user: 'User', retailer: 'Retailer'}) + {code: 'This code', activated_at: 'This code', claimed_at: 'Claimed', user: 'User', retailer: 'Retailer'}) emailErrors = context.JK.getFullFirstError(errorKey, this.state.emailErrors, {email: 'Email address', retailer: 'Retailer'}) @@ -72,7 +76,6 @@ rest = context.JK.Rest()
{logo} -

ACTIVATE JAMKAZAM POSA CARD

@@ -102,7 +105,7 @@ rest = context.JK.Rest()

- If you want to send links to your store’s teachers to this customer, enter their email address below, and click the Send Links button. + If you want to send links to your store’s teachers to thfcustomer, enter their email address below, and click the Send Links button.

@@ -183,7 +186,7 @@ rest = context.JK.Rest() console.log("jqXHR.status", jqXHR.status) if jqXHR.status == 404 - @setState({loginErrors: {"code": ['is not valid']}}) + @setState({loginErrors: {"code": ['is invalid. Please try entering the code again. If it still will not work, try a different card, and please email us at support@jamkazam.com so we can resolve the problem with this card.']}}) else if jqXHR.status == 422 response = JSON.parse(jqXHR.responseText) if response.errors diff --git a/web/app/assets/javascripts/react-components/landing/RedeemGiftCardPage.js.jsx.coffee b/web/app/assets/javascripts/react-components/landing/RedeemGiftCardPage.js.jsx.coffee index 05bf6e217..ddba00fd4 100644 --- a/web/app/assets/javascripts/react-components/landing/RedeemGiftCardPage.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/landing/RedeemGiftCardPage.js.jsx.coffee @@ -14,6 +14,11 @@ badCode = 'This is not a valid code. Please carefully re-enter the code and try errorText = context.JK.getFullFirstError(key, @state.formErrors, {email: 'Email', password: 'Password', gift_card: 'Gift Card Code', 'terms_of_service' : 'The terms of service'}) + if errorText? && errorText.indexOf('does not exist') > -1 + errorText = 'This is not a valid code. Please carefully re-enter the code and try again. If it still does not work, please email us at support@jamkazam.com to report this problem.' + + if errorText? && errorText.indexOf('must already be set') > -1 + errorText = 'This card has not been activated by a retailer and cannot currently be used. If you purchased this card from a store, please return to the store and have the store activate the card. Only the store where you purchased this card can activate it.' buttonClassnames = classNames({'redeem-giftcard': true, 'button-orange': true, disabled: @state.processing || @state.done }) diff --git a/web/app/assets/stylesheets/landings/posa_activation.scss b/web/app/assets/stylesheets/landings/posa_activation.scss index 1bedcbb83..bea87bf62 100644 --- a/web/app/assets/stylesheets/landings/posa_activation.scss +++ b/web/app/assets/stylesheets/landings/posa_activation.scss @@ -10,26 +10,19 @@ body.landing_page.full.posa_activation .landing-content { font-size:1.5rem; } .column { - float:left; - width:50%; + width:100%; @include border_box_sizing; &:nth-child(1) { - width:100%; - &.has_teachers { - width:50%; - } + } &:nth-child(2) { - display:none; - &.has_teachers { - width:50%; + margin-top:20px; display:block; - } } } .explain { - margin:2rem 0; + margin:1rem 0; } label { display:inline-block; @@ -59,4 +52,20 @@ body.landing_page.full.posa_activation .landing-content { margin-top:1rem; color:red; } + + .retailer-logo { + margin-bottom:20px; + img { + float:left; + } + } + + .retailer-name { + vertical-align:middle; + line-height:200px; + height:200px; + float:left; + margin-left:20px; + font-size:1.5rem; + } } \ No newline at end of file diff --git a/web/app/controllers/api_users_controller.rb b/web/app/controllers/api_users_controller.rb index 4566b2510..385e1d575 100644 --- a/web/app/controllers/api_users_controller.rb +++ b/web/app/controllers/api_users_controller.rb @@ -92,6 +92,7 @@ class ApiUsersController < ApiController @autologin = true @user.school_interest = !!params[:school_interest] @user.education_interest = !!params[:education_interest] + @user.retailer_interest = !!params[:retailer_interest] @user.save sign_in @user new_user(@user, signup_hint) # sets a cookie used for GA analytics (one-time new user stuff in JavaScript) @@ -118,6 +119,7 @@ class ApiUsersController < ApiController retailer_invitation_code: params[:retailer_invitation_code], retailer_id: params[:retailer_id], school_interest: params[:school_interest], + retailer_interest: params[:retailer_interest], education_interest: params[:education_interest], affiliate_referral_id: cookies[:affiliate_visitor], origin: origin_cookie, @@ -207,6 +209,7 @@ class ApiUsersController < ApiController @user.is_a_teacher = params[:teacher] if params.has_key?(:teacher) @user.school_interest = !!params[:school_interest] @user.education_interest = !!params[:education_interest] + @user.retailer_interest = !!params[:retailer_interest] @user.desired_package = LessonPackageType.find_by_package_type!(params[:desired_package]) if params.has_key?(:desired_package) if @user.save diff --git a/web/app/views/clients/_account.html.erb b/web/app/views/clients/_account.html.erb index 6f0543f18..be2db2d64 100644 --- a/web/app/views/clients/_account.html.erb +++ b/web/app/views/clients/_account.html.erb @@ -204,7 +204,7 @@
- Invite teachers, students, and manage your retailer settings. + Manage your retail store partner settings.
diff --git a/web/app/views/landings/jam_class_retailers.html.slim b/web/app/views/landings/jam_class_retailers.html.slim index 46d4d0bd2..56dd0cfb9 100644 --- a/web/app/views/landings/jam_class_retailers.html.slim +++ b/web/app/views/landings/jam_class_retailers.html.slim @@ -1,4 +1,4 @@ -- provide(:page_name, 'landing_page full individual_jamtrack') +- provide(:page_name, 'landing_page full individual_jamtrack retailer') - provide(:description, @description) - provide(:title, @title) diff --git a/web/lib/user_manager.rb b/web/lib/user_manager.rb index b0b24c14d..139221801 100644 --- a/web/lib/user_manager.rb +++ b/web/lib/user_manager.rb @@ -36,6 +36,7 @@ class UserManager < BaseManager school_id = options[:school_id] retailer_invitation_code = options[:retailer_invitation_code] retailer_id = options[:retailer_id] + retailer_interest = options[:retailer_interest] school_interest = options[:school_interest] education_interest = options[:education_interest] origin = options[:origin] @@ -91,6 +92,7 @@ class UserManager < BaseManager school_id: school_id, retailer_invitation_code: retailer_invitation_code, retailer_id: retailer_id, + retailer_interest: retailer_interest, school_interest: school_interest, education_interest: education_interest, origin: origin, diff --git a/web/spec/features/retailer_landing_spec.rb b/web/spec/features/retailer_landing_spec.rb new file mode 100644 index 000000000..899dea40c --- /dev/null +++ b/web/spec/features/retailer_landing_spec.rb @@ -0,0 +1,83 @@ +require 'spec_helper' + +describe "School Landing", :js => true, :type => :feature, :capybara_feature => true do + + subject { page } + + before(:all) do + ShoppingCart.delete_all + JamTrackRight.delete_all + JamTrack.delete_all + JamTrackTrack.delete_all + JamTrackLicensor.delete_all + end + + + before(:each) do + AdminMailer.deliveries.clear + end + + let(:user) { FactoryGirl.create(:user, country: 'US') } + + + it "logged out" do + visit "/landing/jamclass/retailers" + + find('h1.jam-track-name', text: 'MANAGE A MUSIC INSTRUMENT STORE?') + find('h2.original-artist', text: 'Increase revenues without more inventory or space') + + find('button.cta-button', text: 'SIGN UP').trigger(:click) + + # should fail because we haven't filled out email/password/terms + find('.register-area .errors', text: "Email can't be blank") + + fill_in "email", with: 'retailer_interest_123@jamkazam.com' + fill_in "password", with: 'jam123' + 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('h2', text: 'sessions') + + AdminMailer.deliveries.count.should eql 3 # welcome email, partners ping about new user, and + + has_retailer_interest_email = false + AdminMailer.deliveries.each do |d| + puts d.subject + if d.subject == ('retailer_interest_123@jamkazam.com' + ' is interested in retailer program') + has_retailer_interest_email = true + break + end + end + has_retailer_interest_email.should be true + user = User.find_by_email('retailer_interest_123@jamkazam.com') + user.is_a_student.should be false + user.is_a_teacher.should be false + user.school_interest.should be false + user.retailer_interest.should be true + user.owned_retailer.should_not be_nil + user.owned_retailer.affiliate_partner.should_not be_nil + user.musician.should be true + end + + it "logged in" do + fast_signin(user,"/landing/jamclass/retailers") + + find('h1.jam-track-name', text: 'MANAGE A MUSIC INSTRUMENT STORE?') + find('h2.original-artist', text: 'Increase revenues without more inventory or space') + + + find('button.cta-button', text: 'SIGN UP').trigger(:click) + + # this should show on the /client#/home page (WILL CHANGE) + find('h2', text: 'sessions') + + user.reload + user.is_a_student.should be false + user.is_a_teacher.should be false + user.retailer_interest.should be true + user.musician.should be true + user.owned_retailer.should_not be_nil + end + +end