* VRFS-315; profile page is working except for avatar, and does not do error visualization yet
This commit is contained in:
parent
4633f0fa08
commit
fef9d3ad19
2
Gemfile
2
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'
|
||||
|
|
|
|||
|
|
@ -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></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></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($('<option></option>').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,
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
}
|
||||
|
||||
function getInstruments(options) {
|
||||
return $.ajax('/api/isps', {
|
||||
return $.ajax('/api/instruments', {
|
||||
data : { },
|
||||
dataType : 'json'
|
||||
});
|
||||
|
|
|
|||
|
|
@ -68,6 +68,11 @@
|
|||
margin-bottom:27px;
|
||||
}
|
||||
|
||||
div.profile-instrumentlist table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 6px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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],
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -33,98 +33,77 @@
|
|||
<div class="content-wrapper account-profile">
|
||||
<br />
|
||||
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<form id="account-edit-profile-form">
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
|
||||
<td valign="top" width="33%">
|
||||
<div class="right mr30"><a href="#" class="avatar_large ml10"><img src="images/shared/avatar_jonathon.png" width="246" height="246" /></a><br clear="left" />
|
||||
<a href="#" class="small">Change Avatar</a></div>
|
||||
<h2>profile:</h2>
|
||||
<td valign="top" width="33%">
|
||||
<div class="right mr30"><a href="#" class="avatar_large ml10"><img src="images/shared/avatar_jonathon.png" width="246" height="246" /></a><br clear="left" />
|
||||
<a href="#" class="small">Change Avatar</a></div>
|
||||
<h2>profile:</h2>
|
||||
|
||||
</td>
|
||||
</td>
|
||||
|
||||
|
||||
<td valign="top" width="33%">First Name:<br />
|
||||
<input type="text" value="Jonathon" class="w80"><br />
|
||||
</td>
|
||||
<td valign="top" width="33%">Last Name:<br />
|
||||
<input type="text" value="Wilson" class="w80"></td>
|
||||
</tr>
|
||||
<td valign="top" width="33%">First Name:<br />
|
||||
<input type="text" name="first_name" value="{first_name}" class="w80"><br />
|
||||
</td>
|
||||
<td valign="top" width="33%">Last Name:<br />
|
||||
<input type="text" name="last_name" value="{last_name}" class="w80"></td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td valign="top">Country:<br />
|
||||
<select class="w80"><option>United States</option></select><br /><br />
|
||||
<tr>
|
||||
<td valign="top">Country:<br />
|
||||
<select name='country' class="w80"><option value='US'>United States</option></select><br /><br />
|
||||
|
||||
</td>
|
||||
<td valign="top">Gender:<br />
|
||||
<select class="w80"><option>Male</option></select><br />
|
||||
<br />
|
||||
</td>
|
||||
<td valign="top">Birth Date:<br />
|
||||
<select><option>Feb</option></select> <select><option>15</option></select> <select><option>1970</option></select>
|
||||
</td>
|
||||
</td>
|
||||
<td valign="top">Gender:<br />
|
||||
<select name="gender" data-value="{gender}" class="w80"><option value='M'>Male</option><option value='F'>Female</option><option value="">-</option></select><br />
|
||||
<br />
|
||||
</td>
|
||||
<td valign="top">Birth Date:<br />
|
||||
<%= date_select("user", "birth_date", :use_short_month => true, :start_year => 1900, :end_year => Time.now.year - 18, :order => [:month, :day, :year], :default => -25.years.from_now ) %>
|
||||
</td>
|
||||
|
||||
|
||||
</tr>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top">State/Province:<br />
|
||||
<select class="w80"><option>Texas</option></select><br /><br />
|
||||
<tr>
|
||||
<td valign="top">State/Province:<br />
|
||||
<select name='region' class="w80" disabled='disabled'><option>loading...</option></select><br /><br />
|
||||
|
||||
<td rowspan=3 colspan=2 valign="top"> What instruments can you play?
|
||||
<td rowspan=3 colspan=2 valign="top"> What instruments can you play?
|
||||
|
||||
<div class="profile-instrumentlist w90">
|
||||
<table width="100%" cellpadding="0" cellspacing="6">
|
||||
<tr>
|
||||
<td><input type="checkbox" checked="checked" /> Acoustic Guitar</td>
|
||||
<td align="right" width="50%"><select><option>Beginner</option><option>Intermediate</option><option>Expert</option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" /> Bass Guitar</td>
|
||||
<td align="right" width="50%"><select disabled="disabled"><option>Beginner</option><option>Intermediate</option><option>Expert</option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" checked="checked" /> Electric Guitar</td>
|
||||
<td align="right" width="50%"><select><option>Beginner</option><option selected="selected">Intermediate</option><option>Expert</option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" /> Drums/Percussion</td>
|
||||
<td align="right" width="50%"><select disabled="disabled"><option>Beginner</option><option>Intermediate</option><option>Expert</option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" /> Computer</td>
|
||||
<td align="right" width="50%"><select disabled="disabled"><option>Beginner</option><option>Intermediate</option><option>Expert</option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" checked="checked" /> Keyboard/Piano</td>
|
||||
<td align="right" width="50%"><select><option>Beginner</option><option>Intermediate</option><option selected="selected">Expert</option></select></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" /> Violin</td>
|
||||
<td align="right" width="50%"><select disabled="disabled"><option>Beginner</option><option>Intermediate</option><option>Expert</option></select></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div></td>
|
||||
</tr>
|
||||
<div class="profile-instrumentlist w90">
|
||||
<table class="instrument_selector" width="100%" cellpadding="0" cellspacing="6">
|
||||
|
||||
<tr>
|
||||
<td valign="top">City:<br />
|
||||
<select class="w80"><option>Austin</option></select><br /><br />
|
||||
</table>
|
||||
</div></td>
|
||||
</tr>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">City:<br />
|
||||
<select name='city' class="w80" disabled='disabled'><option>loading...</option></select><br /><br />
|
||||
|
||||
<tr>
|
||||
<td valign="top">Internet Provider:<br />
|
||||
<select class="w80"><option>AT&T Uverse</option></select></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
<br clear="all" />
|
||||
<div class="right"><a href="account.shtml" class="button-grey">CANCEL</a> <a href="account.shtml" class="button-orange">UPDATE PROFILE</a></div>
|
||||
<div class="right"><a id="account-edit-profile-cancel" href="#" class="button-grey">CANCEL</a> <a id="account-edit-profile-submit" href="#" class="button-orange">UPDATE PROFILE</a></div>
|
||||
</div>
|
||||
<!-- end content wrapper -->
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="account-profile-instrument">
|
||||
<tr data-instrument-id='{id}'>
|
||||
<td><input type="checkbox" {checked} />{description}</td>
|
||||
<td align="right" width="50%"><select name="proficiency" class='proficiency_selector'><option value="1">Beginner</option><option value="2">Intermediate</option><option value="3">Expert</option></select></td>
|
||||
</tr>
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
<select id="country_select" name="jam_ruby_user[country]" autocomplete="off">
|
||||
<option value="">Select Country</option>
|
||||
<% @countries.each do |country| %>
|
||||
<option value="<%= country %>" <%= @location[:country] == "United States" ? "selected" : "" %>><%= country %></option>
|
||||
<option value="<%= country %>" <%= @location[:country] == "US" ? "selected" : "" %>><%= country %></option>
|
||||
<% end %>
|
||||
|
||||
</select>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
<%= f.text_field :email, :disabled => true %></td>
|
||||
|
||||
<td>Country:<br />
|
||||
<select id="jam_ruby_user_country" name="jam_ruby_user_country"><option value="United States">United States</option></select>
|
||||
<select id="jam_ruby_user_country" name="jam_ruby_user_country"><option value="US">United States</option></select>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class MaxMindManager < BaseManager
|
|||
ActiveRecord::Base.connection_pool.with_connection do |connection|
|
||||
pg_conn = connection.instance_variable_get("@connection")
|
||||
pg_conn.exec("SELECT DISTINCT isp FROM max_mind_isp WHERE country = $1 ORDER BY isp ASC", [country]).map do |tuple|
|
||||
tuple["country"]
|
||||
tuple["isp"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue