diff --git a/Gemfile b/Gemfile index 204ed0717..b324a49a9 100644 --- a/Gemfile +++ b/Gemfile @@ -42,7 +42,7 @@ gem 'omniauth-facebook', '1.4.1' gem 'fb_graph', '2.5.9' gem 'sendgrid', '1.1.0' gem 'recaptcha', '0.3.4' -gem 'filepicker-rails', '0.0.2' +gem 'filepicker-rails', '0.1.0' gem 'aws-sdk', '1.8.0' gem 'aasm', '3.0.16' gem 'carrierwave' diff --git a/app/assets/javascripts/accounts_profile.js b/app/assets/javascripts/accounts_profile.js index 1c677ee4d..b691ebdba 100644 --- a/app/assets/javascripts/accounts_profile.js +++ b/app/assets/javascripts/accounts_profile.js @@ -8,6 +8,8 @@ var api = context.JK.API(app); var userId; var user = {}; + var recentUserDetail = null; + var loadingLocationData = false; function beforeShow(data) { userId = data.id; @@ -24,61 +26,139 @@ $('#account-profile-content-scroller form .error').removeClass("error") } - function getUserDetail() { - - var url = "/api/users/" + context.JK.currentUserId; - return $.ajax({ - type: "GET", - dataType: "json", - url: url, - async: true, - processData: false - }); - } - - function populateAccountProfile(userDetail, instruments, isps, regions, cities) { + function populateAccountProfile(userDetail, instruments) { var template = context.JK.fillTemplate($('#template-account-profile').html(), { country: userDetail.country, - state: userDetail.state, + region: userDetail.state, first_name: userDetail.first_name, last_name: userDetail.last_name, user_instruments: userDetail.instruments, birth_date : userDetail.birth_date, - isp : userDetail.isp, - gender: userDetail.gender, - instruments: instruments, - cities: cities["cities"], - regions: regions["regions"], - isps: isps["isps"] + gender: userDetail.gender }); - $('#account-profile-content-scroller').html(template); + var content_root = $('#account-profile-content-scroller') + content_root.html(template); + + // now use javascript to fix up values too hard to do with templating + + // set gender + $('select[name=gender]', content_root).val(userDetail.gender) + + // set birth_date + if(userDetail.birth_date) { + var birthDateFields = userDetail.birth_date.split('-') + var birthDateYear = birthDateFields[0]; + var birthDateMonth = birthDateFields[1]; + var birthDateDay = birthDateFields[2]; + + $('select#user_birth_date_1i', content_root).val(parseInt(birthDateYear)); + $('select#user_birth_date_2i', content_root).val(parseInt(birthDateMonth)); + $('select#user_birth_date_3i', content_root).val(parseInt(birthDateDay)); + } + + // update instruments + $.each(instruments, function(index, instrument) { + + var template = context.JK.fillTemplate($('#account-profile-instrument').html(), { + checked : isUserInstrument(instrument, userDetail.instruments) ? "checked=\"checked\"" :"", + description : instrument.description, + id : instrument.id + }) + $('.instrument_selector', content_root).append(template) + }) + // and fill in the proficiency for the instruments that the user can play + $.each(userDetail.instruments, function(index, userInstrument) { + $('tr[data-instrument-id="' + userInstrument.instrument_id + '"] select.proficiency_selector', content_root).val(userInstrument.proficiency_level) + }) + } + + function isUserInstrument(instrument, userInstruments) { + var isUserInstrument = false; + $.each(userInstruments, function(index, userInstrument) { + if(instrument.id == userInstrument.instrument_id) { + isUserInstrument = true; + return false; + } + }) + return isUserInstrument; + } + + function populateAccountProfileLocation(userDetail, regions, cities) { + populateRegions(regions, userDetail.state); + populateCities(cities, userDetail.city); + } + + function populateRegions(regions, userRegion) { + var regionSelect = getRegionElement() + regionSelect.children().remove() + + $.each(regions, function(index, region) { + if(!region) return; + + var option = $('') + option.text(region) + option.attr("value", region) + + regionSelect.append(option) + }) + + regionSelect.val(userRegion) + regionSelect.attr("disabled", null) + } + + function populateCities(cities, userCity) { + var citySelect = getCityElement(); + citySelect.children().remove() + + $.each(cities, function(index, city) { + if(!city) return; + + var option = $('') + option.text(city) + option.attr("value", city) + + citySelect.append(option) + }) + + citySelect.val(userCity) + citySelect.attr("disabled", null) } /****************** MAIN PORTION OF SCREEN *****************/ // events for main screen function events() { - $('#account-profile-content-scroller').on('click', '#account-edit-email-cancel', function(evt) { evt.stopPropagation(); navToAccount(); return false; } ); - $('#account-profile-content-scroller').on('click', '#account-edit-email-submit', function(evt) { evt.stopPropagation(); handleUpdateProfile(); return false; } ); + $('#account-profile-content-scroller').on('click', '#account-edit-profile-cancel', function(evt) { evt.stopPropagation(); navToAccount(); return false; } ); + $('#account-profile-content-scroller').on('click', '#account-edit-profile-submit', function(evt) { evt.stopPropagation(); handleUpdateProfile(); return false; } ); $('#account-profile-content-scroller').on('submit', '#account-edit-email-form', function(evt) { evt.stopPropagation(); handleUpdateProfile(); return false; } ); - $('#account-profile-content-scroller').on('click', '#account-edit-password-cancel', function(evt) { evt.stopPropagation(); navToAccount(); return false; } ); + $('#account-profile-content-scroller').on('change', 'select[name=region]', function(evt) { evt.stopPropagation(); handleRegionChanged(); return false; } ); } function renderAccountProfile() { $.when( api.getUserDetail(), api.getInstruments()) - .done(function(userDetail, instruments) { + .done(function(userDetailResponse, instrumentsResponse) { + var userDetail = userDetailResponse[0]; + recentUserDetail = userDetail // store userDetail for later + var instruments = instrumentsResponse[0]; + // show page; which can be done quickly at this point + populateAccountProfile(userDetail, instruments); - // now that we have the user's country and region, we can query further + loadingLocationData = true; + + // make the 3 slower requests, which only matter if the user wants to affect their ISP or location $.when( - api.getIsps( { country: userDetail.country } ), api.getRegions( { country: userDetail.country } ), api.getCities( { country: userDetail.country, region: userDetail.state })) - .done(function(isps, regions, cities) { - populateAccountProfile(userDetail, instruments, isps, regions, cities) + .done(function(regionsResponse, citiesResponse) { + var regions = regionsResponse[0]; + var cities = citiesResponse[0]; + + populateAccountProfileLocation(userDetail, regions["regions"], cities["cities"]) }) .fail(app.ajaxError) + .always(function() {loadingLocationData = false;}) }) .fail(app.ajaxError); } @@ -89,15 +169,32 @@ } function handleUpdateProfile() { + + if (loadingLocationData) return; + resetForm(); - var currentPassword = $('#account-edit-password-form input[name=current_password]').val() - var password = $('#account-edit-password-form input[name=password]').val() - var passwordConfirmation = $('#account-edit-password-form input[name=password_confirmation]').val() + var country = getCountryElement().val(); + var region = getRegionElement().val(); + var city = getCityElement().val(); + var firstName = getFirstNameElement().val(); + var lastName = getLastNameElement().val(); + var gender = getGenderElement().val() + var birthDate = getBirthDate(); + var instruments = getInstrumentsValue(); - postUpdatePassword(currentPassword, password, passwordConfirmation) - .done(postUpdatePasswordSuccess) - .fail(postUpdatePasswordFailure) + postUpdateProfile({ + country: country, + state: region, + city: city, + first_name: firstName, + last_name: lastName, + gender: gender, + birth_date: birthDate, + instruments: instruments + }) + .done(postUpdateProfileSuccess) + .fail(postUpdateProfileFailure) } function postUpdateProfile(options) { @@ -146,6 +243,91 @@ } } + + function handleRegionChanged() { + var selectedCountry = getCountryElement().val() + var selectedRegion = getRegionElement().val() + var cityElement = getCityElement(); + + // only update + if(selectedCountry && selectedRegion) { + // set city disabled while updating + cityElement.attr('disabled', true); + loadingLocationData = false; + + cityElement.children().remove() + cityElement.append($('').text('loading...')) + + api.getCities( { country: selectedCountry, region: selectedRegion }) + .done(getCitiesDone) + .fail(app.ajaxError) + .always(function() { loadingLocationData = false; }) + } + } + + function getCitiesDone(data) { + populateCities(data['cities'], recentUserDetail.city) + } + + function getCountryElement() { + return $('#account-profile-content-scroller select[name=country]') + } + + function getRegionElement() { + return $('#account-profile-content-scroller select[name=region]') + } + + function getCityElement() { + return $('#account-profile-content-scroller select[name=city]') + } + + function getFirstNameElement() { + return $('#account-profile-content-scroller input[name=first_name]') + } + + function getLastNameElement() { + return $('#account-profile-content-scroller input[name=last_name]') + } + + function getGenderElement() { + return $('#account-profile-content-scroller select[name=gender]') + } + + function getBirthDate() { + var month = $('#account-profile-content-scroller select#user_birth_date_2i').val() + var day = $('#account-profile-content-scroller select#user_birth_date_3i').val() + var year = $('#account-profile-content-scroller select#user_birth_date_1i').val() + + if(month != null && month.length > 0 && day != null && day.length > 0 && year != null && year.length > 0) { + return month + "-" + day + "-" + year; + } + else { + return null; + } + } + + // looks in instrument_selector parent element, and gathers up all + // selected elements, and the proficiency level declared + function getInstrumentsValue() { + var instrumentsParentElement = $(".instrument_selector") + + var instruments = [] + $('input[type=checkbox]:checked', instrumentsParentElement).each(function(i) { + + var instrumentElement = $(this).closest('tr'); + // traverse up to common parent of this instrument, and pick out proficiency selector + var proficiency = $('select.proficiency_selector', instrumentElement).val() + + instruments.push({ + instrument_id: instrumentElement.attr('data-instrument-id'), + proficiency_level: proficiency, + priority : i + }) + }); + + return instruments; + } + function initialize() { var screenBindings = { 'beforeShow': beforeShow, diff --git a/app/assets/javascripts/jam_rest.js b/app/assets/javascripts/jam_rest.js index e062db1a6..573587186 100644 --- a/app/assets/javascripts/jam_rest.js +++ b/app/assets/javascripts/jam_rest.js @@ -59,7 +59,7 @@ } function getInstruments(options) { - return $.ajax('/api/isps', { + return $.ajax('/api/instruments', { data : { }, dataType : 'json' }); diff --git a/app/assets/stylesheets/client/account.css.scss b/app/assets/stylesheets/client/account.css.scss index d0792210d..34c5b9599 100644 --- a/app/assets/stylesheets/client/account.css.scss +++ b/app/assets/stylesheets/client/account.css.scss @@ -68,6 +68,11 @@ margin-bottom:27px; } + div.profile-instrumentlist table { + border-collapse: separate; + border-spacing: 6px; + } + } diff --git a/app/controllers/api_users_controller.rb b/app/controllers/api_users_controller.rb index d337c3df9..379b84757 100644 --- a/app/controllers/api_users_controller.rb +++ b/app/controllers/api_users_controller.rb @@ -57,7 +57,7 @@ class ApiUsersController < ApiController current_user.id, params[:first_name], params[:last_name], - params[:email], + nil, # Don't allow changing email here, since updating email is something that must be done through it's own API nil, # Don't allow changing password here, since we want to prompt again for the old password nil, params[:musician], diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index f6838e333..df93d2cf7 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -235,7 +235,7 @@ class UsersController < ApplicationController @location = MaxMindManager.lookup(remote_ip) end - @location[:country] = "United States" if @location[:country].nil? + @location[:country] = "US" if @location[:country].nil? # right now we only accept US signups for beta @countries = MaxMindManager.countries() diff --git a/app/views/clients/_account_profile.html.erb b/app/views/clients/_account_profile.html.erb index 62af575d5..fef80e6ef 100644 --- a/app/views/clients/_account_profile.html.erb +++ b/app/views/clients/_account_profile.html.erb @@ -33,98 +33,77 @@
+ + diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index 02aa4eabf..572647764 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -52,7 +52,7 @@ diff --git a/app/views/users/signup_confirm.html.erb b/app/views/users/signup_confirm.html.erb index 8c0ef92e9..84a3116ed 100644 --- a/app/views/users/signup_confirm.html.erb +++ b/app/views/users/signup_confirm.html.erb @@ -40,7 +40,7 @@ <%= f.text_field :email, :disabled => true %>