From 561b7c45ac01f5cbee0d84f5309ff0ae8b06393e Mon Sep 17 00:00:00 2001 From: Skud Date: Mon, 11 Aug 2014 14:42:00 +1000 Subject: [PATCH] b3ify and improve design of edit profile page --- Gemfile | 2 +- Gemfile.lock | 14 +-- app/controllers/registrations_controller.rb | 27 ++-- .../devise/registrations/_edit_apps.html.haml | 26 ++++ .../registrations/_edit_email.html.haml | 31 +++++ .../registrations/_edit_password.html.haml | 22 ++++ .../registrations/_edit_profile.html.haml | 30 +++++ app/views/devise/registrations/edit.html.haml | 117 ++++-------------- config/initializers/devise.rb | 2 + spec/views/devise/registrations/edit_spec.rb | 17 --- 10 files changed, 160 insertions(+), 128 deletions(-) create mode 100644 app/views/devise/registrations/_edit_apps.html.haml create mode 100644 app/views/devise/registrations/_edit_email.html.haml create mode 100644 app/views/devise/registrations/_edit_password.html.haml create mode 100644 app/views/devise/registrations/_edit_profile.html.haml diff --git a/Gemfile b/Gemfile index 3c41ee688..20fd19aab 100644 --- a/Gemfile +++ b/Gemfile @@ -93,7 +93,7 @@ gem 'bluecloth' gem 'will_paginate', '~> 3.0' # user signup/login/etc -gem 'devise', '~> 3.0.0' +gem 'devise', '~> 3.2.0' # nicely formatted URLs gem 'friendly_id', '~> 4.0.10' diff --git a/Gemfile.lock b/Gemfile.lock index 2921a230f..5fa52738a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,8 +50,6 @@ GEM addressable (2.3.6) arel (3.0.3) bcrypt (3.1.7) - bcrypt-ruby (3.1.5) - bcrypt (>= 3.1.3) better_errors (1.1.0) coderay (>= 1.0.0) erubis (>= 2.6.6) @@ -95,10 +93,11 @@ GEM debugger-ruby_core_source (~> 1.3.2) debugger-linecache (1.2.0) debugger-ruby_core_source (1.3.2) - devise (3.0.4) - bcrypt-ruby (~> 3.0) + devise (3.2.4) + bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 3.2.6, < 5) + thread_safe (~> 0.1) warden (~> 1.2.3) diff-lcs (1.1.3) docile (1.1.3) @@ -162,7 +161,7 @@ GEM memcachier (0.0.2) mime-types (1.25.1) mini_portile (0.5.3) - multi_json (1.9.3) + multi_json (1.10.1) multi_xml (0.5.5) newrelic_rpm (3.8.0.218) nokogiri (1.6.1) @@ -210,7 +209,7 @@ GEM rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) raindrops (0.13.0) - rake (10.3.1) + rake (10.3.2) rdoc (3.12.2) json (~> 1.4) ref (1.0.5) @@ -248,6 +247,7 @@ GEM libv8 (~> 3.16.14.0) ref thor (0.19.1) + thread_safe (0.3.3) tilt (1.4.1) tins (1.1.0) treetop (1.4.15) @@ -287,7 +287,7 @@ DEPENDENCIES csv_shaper dalli debugger - devise (~> 3.0.0) + devise (~> 3.2.0) factory_girl_rails (~> 4.0) figaro flickraw diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 815457201..cbb300496 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -10,26 +10,37 @@ class RegistrationsController < Devise::RegistrationsController # we need this subclassed method so that Devise doesn't force people to # change their password every time they want to edit their settings. +# we also check that they give their current password to chang their password. # Code copied from # https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-account-without-providing-a-password def update - # required for settings form to submit when password is left blank - if params[:member][:password].blank? - params[:member].delete("password") - params[:member].delete("password_confirmation") - params[:member].delete("current_password") - end @member = Member.find(current_member.id) - if @member.update_attributes(params[:member]) + successfully_updated = if needs_password?(@member, params) + @member.update_with_password(devise_parameter_sanitizer.sanitize(:account_update)) + else + # remove the virtual current_password attribute + # update_without_password doesn't know how to ignore it + params[:member].delete(:current_password) + @member.update_without_password(devise_parameter_sanitizer.sanitize(:account_update)) + end + + if successfully_updated set_flash_message :notice, :updated - # Sign in the member bypassing validation in case his password changed + # Sign in the member bypassing validation in case their password changed sign_in @member, :bypass => true redirect_to edit_member_registration_path else render "edit" end + end end + +# check if we need the current password to update fields +def needs_password?(member, params) + params[:member][:password].present? || + params[:member][:password_confirmation].present? +end diff --git a/app/views/devise/registrations/_edit_apps.html.haml b/app/views/devise/registrations/_edit_apps.html.haml new file mode 100644 index 000000000..df5d17c88 --- /dev/null +++ b/app/views/devise/registrations/_edit_apps.html.haml @@ -0,0 +1,26 @@ += form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :class => 'form-horizontal' }) do |f| + = devise_error_messages! + + .row + .col-md-12 + %p + = image_tag "twitter_32.png", :size => "32x32", :alt => 'Twitter logo' + - if @twitter_auth + You are connected to Twitter as + = succeed "." do + =link_to @twitter_auth.name, "http://twitter.com/#{@twitter_auth.name}" + = link_to "Disconnect", @twitter_auth, :confirm => "Are you sure you want to remove this connection?", :method => :delete, :class => "remove" + - else + =link_to 'Connect to Twitter', '/auth/twitter' + + .row + .col-md-12 + %p + = image_tag "flickr_32.png", :size => "32x32", :alt => 'Flickr logo' + - if @flickr_auth + You are connected to Flickr as + = succeed "." do + =link_to @flickr_auth.name, "http://flickr.com/photos/#{@flickr_auth.uid}" + = link_to "Disconnect", @flickr_auth, :confirm => "Are you sure you want to remove this connection?", :method => :delete, :class => "remove" + - else + =link_to 'Connect to Flickr', '/auth/flickr' diff --git a/app/views/devise/registrations/_edit_email.html.haml b/app/views/devise/registrations/_edit_email.html.haml new file mode 100644 index 000000000..61df13f91 --- /dev/null +++ b/app/views/devise/registrations/_edit_email.html.haml @@ -0,0 +1,31 @@ += form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :class => 'form-horizontal' }) do |f| + = devise_error_messages! + + .form-group + = f.label :email, :class => 'control-label col-md-2' + .col-md-8 + = f.email_field :email, :class => 'form-control' + %span.help-block If you change your email address you will have to reconfirm. + + .form-group + .col-md-offset-2.col-md-8 + = f.check_box :show_email + Show email publicly on your profile page + + .form-group + .col-md-offset-2.col-md-8 + = f.check_box :send_notification_email + Receive emailed copies of Inbox notifications. + + .form-group + .col-md-offset-2.col-md-8 + = f.check_box :newsletter + Subscribe to the #{ENV['GROWSTUFF_SITE_NAME']} newsletter + .help-block + = render :partial => 'newsletter_blurb' + + .form-group + .form-actions.col-md-offset-2.col-md-8 + = f.submit "Save", :class => 'btn btn-primary' + + =f.hidden_field(:tos_agreement, :value => true) diff --git a/app/views/devise/registrations/_edit_password.html.haml b/app/views/devise/registrations/_edit_password.html.haml new file mode 100644 index 000000000..c70edc96f --- /dev/null +++ b/app/views/devise/registrations/_edit_password.html.haml @@ -0,0 +1,22 @@ += form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :class => 'form-horizontal' }) do |f| + = devise_error_messages! + + .form-group + = f.label :current_password, :class => 'control-label col-md-2' + .col-md-4 + = f.password_field :current_password, :class => 'form-control' + + .form-group + = f.label :password, "New password", :class => 'control-label col-md-2' + .col-md-4 + = f.password_field :password, :autocomplete => "off", :class => 'form-control' + + .form-group + = f.label :password_confirmation, :class => 'control-label col-md-2' + .col-md-4= f.password_field :password_confirmation, :class => 'form-control' + + .form-group + .form-actions.col-md-offset-2.col-md-8 + = f.submit "Save", :class => 'btn btn-primary' + + =f.hidden_field(:tos_agreement, :value => true) diff --git a/app/views/devise/registrations/_edit_profile.html.haml b/app/views/devise/registrations/_edit_profile.html.haml new file mode 100644 index 000000000..fe33c6fdf --- /dev/null +++ b/app/views/devise/registrations/_edit_profile.html.haml @@ -0,0 +1,30 @@ += form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :class => 'form-horizontal' }) do |f| + = devise_error_messages! + + .form-group + =f.label :location, 'Your location', :class => 'control-label col-md-2' + .col-md-8 + =f.text_field :location, :autocomplete => "off", :class => 'form-control' + %span.help-block This will be displayed on a map. You can be as detailed or vague as you like. + + .form-group + =f.label :bio, :class => 'control-label col-md-2' + .col-md-8 + =f.text_area :bio, :rows => 6, :class => 'form-control' + + .form-group + %label.control-label.col-md-2 + Profile picture + .col-md-8 + = render :partial => "members/avatar", :locals => { :member => @member } + %p + %br/ + To change your profile picture, visit + = succeed "." do + = link_to 'gravatar.com', "http://gravatar.com/" + + .form-group + .form-actions.col-md-offset-2.col-md-8 + = f.submit "Save", :class => 'btn btn-primary' + + =f.hidden_field(:tos_agreement, :value => true) diff --git a/app/views/devise/registrations/edit.html.haml b/app/views/devise/registrations/edit.html.haml index cb77568f4..85ba205d9 100644 --- a/app/views/devise/registrations/edit.html.haml +++ b/app/views/devise/registrations/edit.html.haml @@ -1,98 +1,25 @@ - content_for :title, "Settings for #{current_member.login_name}" -= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :class => 'form-horizontal' }) do |f| - = devise_error_messages! +%ul.nav.nav-tabs{:role => 'tablist'} + %li.active + %a{:href => '#profile', :role => 'tab', 'data-toggle' => 'tab'} + Profile + %li + %a{:href => '#email', :role => 'tab', 'data-toggle' => 'tab'} + Email + %li + %a{:href => '#apps', :role => 'tab', 'data-toggle' => 'tab'} + Apps + %li + %a{:href => '#password', :role => 'tab', 'data-toggle' => 'tab'} + Password - %h2 Email settings - - .form-group - = f.label :email, :class => 'control-label' - .controls - = f.email_field :email - %span.help-inline If you change your email address you will have to reconfirm. - - .form-group - .controls - = f.check_box :show_email - Show email publicly on your profile page - - .form-group - .controls - = f.check_box :send_notification_email - Receive emailed copies of Inbox notifications. - - .form-group - .controls - = f.check_box :newsletter - Subscribe to the #{ENV['GROWSTUFF_SITE_NAME']} newsletter - .help-inline - = render :partial => 'newsletter_blurb' - - %h2 Profile details - .form-group - %label.control-label - Profile picture - .controls - = render :partial => "members/avatar", :locals => { :member => @member } - %p - %br/ - To change your profile picture, visit - = succeed "." do - = link_to 'gravatar.com', "http://gravatar.com/" - - .form-group - =f.label :location, 'Your location', :class => 'control-label' - .controls - =f.text_field :location, :autocomplete => "off" - %span.help-inline This will be displayed on a map. You can be as detailed or vague as you like. - - .form-group - =f.label :bio, :class => 'control-label' - .controls - =f.text_area :bio, :rows => 6, :class => 'form-control' - - %h2 Linked accounts - - .form-group - .controls - %p - = image_tag "twitter_32.png", :size => "32x32", :alt => 'Twitter logo' - - if @twitter_auth - You are connected to Twitter as - = succeed "." do - =link_to @twitter_auth.name, "http://twitter.com/#{@twitter_auth.name}" - = link_to "Disconnect", @twitter_auth, :confirm => "Are you sure you want to remove this connection?", :method => :delete, :class => "remove" - - else - =link_to 'Connect to Twitter', '/auth/twitter' - %p - = image_tag "flickr_32.png", :size => "32x32", :alt => 'Flickr logo' - - if @flickr_auth - You are connected to Flickr as - = succeed "." do - =link_to @flickr_auth.name, "http://flickr.com/photos/#{@flickr_auth.uid}" - = link_to "Disconnect", @flickr_auth, :confirm => "Are you sure you want to remove this connection?", :method => :delete, :class => "remove" - - else - =link_to 'Connect to Flickr', '/auth/flickr' - - %h2 Change password - %p - %span.help-block Leave blank if you don't want to change your password. - - .form-group - = f.label :current_password, :class => 'control-label' - .controls - = f.password_field :current_password - - .form-group - = f.label :password, "New password", :class => 'control-label' - .controls - = f.password_field :password, :autocomplete => "off" - - .form-group - = f.label :password_confirmation, :class => 'control-label' - .controls= f.password_field :password_confirmation - - .form-actions - = f.submit "Save", :class => 'btn btn-primary' - - =f.hidden_field(:tos_agreement, :value => true) +.tab-content + .tab-pane.active#profile + = render :partial => 'edit_profile' + .tab-pane#email + = render :partial => 'edit_email' + .tab-pane#apps + = render :partial => 'edit_apps' + .tab-pane#password + = render :partial => 'edit_password' diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 0e332098c..eb51fab96 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -6,6 +6,8 @@ Devise.setup do |config| # note that it will be overwritten if you use your own mailer class with default "from" parameter. config.mailer_sender = "Growstuff " + config.secret_key = ENV['RAILS_SECRET_TOKEN'] + # Configure the class responsible to send e-mails. # config.mailer = "Devise::Mailer" diff --git a/spec/views/devise/registrations/edit_spec.rb b/spec/views/devise/registrations/edit_spec.rb index cfd18c6de..f9c48ec1a 100644 --- a/spec/views/devise/registrations/edit_spec.rb +++ b/spec/views/devise/registrations/edit_spec.rb @@ -23,10 +23,6 @@ describe 'devise/registrations/edit.html.haml', :type => "view" do render end - it 'has a heading' do - assert_select "h2", "Email settings" - end - it 'has a checkbox for email notifications' do assert_select "input[id=member_send_notification_email][type=checkbox]" end @@ -41,10 +37,6 @@ describe 'devise/registrations/edit.html.haml', :type => "view" do render end - it 'has a heading' do - assert_select "h2", "Profile details" - end - it 'shows show_email checkbox' do assert_select "input[id=member_show_email][type=checkbox]" end @@ -67,10 +59,6 @@ describe 'devise/registrations/edit.html.haml', :type => "view" do end context 'other sites section' do - it 'has a heading' do - render - assert_select "h2", "Linked accounts" - end context 'not connected to twitter' do it 'has a link to connect' do @@ -114,11 +102,6 @@ describe 'devise/registrations/edit.html.haml', :type => "view" do end - it 'should have a password section' do - render - assert_select "h2", "Change password" - end - end end