From 219ad2b4a7d9b14b8a2c6b30b2891b2018c75aeb Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Wed, 7 Jun 2023 01:36:47 +0300 Subject: [PATCH] add basic profile settings --- app/controllers/profile_controller.rb | 37 ++++++++++++++----- app/models/user.rb | 8 +++- app/views/devise/confirmations/new.html.erb | 14 +++++++ .../mailer/confirmation_instructions.html.erb | 3 ++ app/views/devise/shared/_links.html.erb | 14 +++---- app/views/profile/_navigation.html.erb | 36 ++++++++++++++++++ .../{index.html.erb => contact.html.erb} | 9 ++++- app/views/profile/email.html.erb | 30 +++++++++++++++ app/views/profile/password.html.erb | 25 +++++++++++++ app/views/shared/_navbar.html.erb | 2 +- app/views/shared/_settings_nav.html.erb | 2 +- app/views/storage_settings/index.html.erb | 2 +- config/routes.rb | 13 ++++++- ...0230606210549_add_confirmation_to_users.rb | 8 ++++ db/schema.rb | 6 ++- 15 files changed, 185 insertions(+), 24 deletions(-) create mode 100644 app/views/devise/confirmations/new.html.erb create mode 100644 app/views/devise/mailer/confirmation_instructions.html.erb create mode 100644 app/views/profile/_navigation.html.erb rename app/views/profile/{index.html.erb => contact.html.erb} (64%) create mode 100644 app/views/profile/email.html.erb create mode 100644 app/views/profile/password.html.erb create mode 100644 db/migrate/20230606210549_add_confirmation_to_users.rb diff --git a/app/controllers/profile_controller.rb b/app/controllers/profile_controller.rb index b7f73c50..f0807995 100644 --- a/app/controllers/profile_controller.rb +++ b/app/controllers/profile_controller.rb @@ -1,23 +1,42 @@ # frozen_string_literal: true class ProfileController < ApplicationController - def index - @user = current_user + def update_contact + if current_user.update(contact_params) + redirect_to contact_settings_profile_index_path, notice: 'Contact information successfully updated' + else + render :contact, status: :unprocessable_entity + end end - def update - @user = current_user + def update_password + if current_user.update_with_password(password_params) + bypass_sign_in(current_user) + redirect_to password_settings_profile_index_path, notice: 'Password successfully changed' + else + render :password, status: :unprocessable_entity + end + end - if @user.update(user_params) - redirect_to settings_profile_path, notice: 'Profile updated' + def update_email + if current_user.update_with_password(email_params) + redirect_to email_settings_profile_index_path, notice: 'Email successfully updated. Please check your new email for confirmation instructions.' else - render :index + render :email, status: :unprocessable_entity end end private - def user_params - params.require(:user).permit(:first_name, :last_name) + def contact_params + params.require(:user).permit(:first_name, :last_name, account_attributes: %i[name]) + end + + def password_params + params.require(:user).permit(:current_password, :password, :password_confirmation) + end + + def email_params + params.require(:user).permit(:current_password, :email) end end diff --git a/app/models/user.rb b/app/models/user.rb index 0aaf3d97..a53fe09f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,6 +5,9 @@ # Table name: users # # id :bigint not null, primary key +# confirmation_sent_at :datetime +# confirmation_token :string +# confirmed_at :datetime # current_sign_in_at :datetime # current_sign_in_ip :string # deleted_at :datetime @@ -21,6 +24,7 @@ # reset_password_token :string # role :string not null # sign_in_count :integer default(0), not null +# unconfirmed_email :string # unlock_token :string # created_at :datetime not null # updated_at :datetime not null @@ -45,13 +49,15 @@ class User < ApplicationRecord belongs_to :account - devise :database_authenticatable, :recoverable, :rememberable, :validatable, :trackable + devise :database_authenticatable, :recoverable, :rememberable, :validatable, :trackable, :confirmable devise :registerable # if ENV['APP_MULTITENANT'] attribute :role, :string, default: 'admin' scope :active, -> { where(deleted_at: nil) } + accepts_nested_attributes_for :account, update_only: true + def active_for_authentication? !deleted_at? end diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb new file mode 100644 index 00000000..e37dd597 --- /dev/null +++ b/app/views/devise/confirmations/new.html.erb @@ -0,0 +1,14 @@ +
+

Resend confirmation instructions

+ <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post, class: 'space-y-6' }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> +
+ <%= f.label :email, class: 'label' %> + <%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email), class: 'base-input' %> +
+
+ <%= f.submit "Resend confirmation instructions", class: 'base-button' %> +
+ <% end %> + <%= render "devise/shared/links" %> +
diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb new file mode 100644 index 00000000..57193aa7 --- /dev/null +++ b/app/views/devise/mailer/confirmation_instructions.html.erb @@ -0,0 +1,3 @@ +

Welcome <%= @email %>!

+

You can confirm your account email through the link below:

+

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

diff --git a/app/views/devise/shared/_links.html.erb b/app/views/devise/shared/_links.html.erb index cc73180b..d6c10878 100644 --- a/app/views/devise/shared/_links.html.erb +++ b/app/views/devise/shared/_links.html.erb @@ -1,22 +1,22 @@ -
+
<%- if controller_name != 'sessions' %> - <%= link_to 'Log in', new_session_path(resource_name), class: 'link link-hover' %> + <%= link_to 'Log in', new_session_path(resource_name), class: 'badge badge-outline my-1' %> <% end %> <%- if devise_mapping.registerable? && controller_name != 'registrations' %> - <%= link_to 'Sign up', new_registration_path, class: 'link link-hover' %> + <%= link_to 'Sign up', new_registration_path, class: 'badge badge-outline my-1' %> <% end %> <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> - <%= link_to 'Forgot your password?', new_password_path(resource_name), class: 'link link-hover' %> + <%= link_to 'Forgot your password?', new_password_path(resource_name), class: 'badge badge-outline my-1' %> <% end %> <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> - <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: 'link link-hover' %> + <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: 'badge badge-outline my-1' %> <% end %> <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> - <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name), class: 'link link-hover' %> + <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name), class: 'badge badge-outline my-1' %> <% end %> <%- if devise_mapping.omniauthable? %> <%- resource_class.omniauth_providers.each do |provider| %> - <%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), class: 'link link-hover', data: { turbo: false } %> + <%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), class: 'badge badge-outline my-1', data: { turbo: false } %> <% end %> <% end %>
diff --git a/app/views/profile/_navigation.html.erb b/app/views/profile/_navigation.html.erb new file mode 100644 index 00000000..39db35ea --- /dev/null +++ b/app/views/profile/_navigation.html.erb @@ -0,0 +1,36 @@ + + + diff --git a/app/views/profile/index.html.erb b/app/views/profile/contact.html.erb similarity index 64% rename from app/views/profile/index.html.erb rename to app/views/profile/contact.html.erb index 78538561..5c686b9c 100644 --- a/app/views/profile/index.html.erb +++ b/app/views/profile/contact.html.erb @@ -2,7 +2,8 @@ <%= render 'shared/settings_nav' %>

Profile

- <%= form_for @user, html: { autocomplete: 'off', class: 'space-y-4' } do |f| %> + <%= render 'navigation' %> + <%= form_for current_user, url: update_contact_settings_profile_index_path, method: :patch, html: { autocomplete: 'off', class: 'space-y-4' } do |f| %>
<%= f.label :first_name, class: 'label' %> @@ -13,6 +14,12 @@ <%= f.text_field :last_name, required: true, class: 'base-input' %>
+ <%= f.fields_for :account do |ff| %> +
+ <%= ff.label :name, 'Company Name', class: 'label' %> + <%= ff.text_field :name, required: true, class: 'base-input' %> +
+ <% end %>
<%= f.button button_title, class: 'base-button' %>
diff --git a/app/views/profile/email.html.erb b/app/views/profile/email.html.erb new file mode 100644 index 00000000..cb40c857 --- /dev/null +++ b/app/views/profile/email.html.erb @@ -0,0 +1,30 @@ +
+ <%= render 'shared/settings_nav' %> +
+

Profile

+ <%= render 'navigation' %> + <%= form_for current_user, url: update_email_settings_profile_index_path, method: :patch, html: { autocomplete: 'off', class: 'space-y-4' } do |f| %> + <% if current_user.pending_reconfirmation? %> +
+ +
+

Currently waiting confirmation

+
Unconfirmed email: <%= current_user.unconfirmed_email %>
+
+
+ <% end %> +
+ <%= f.label :email, 'New email', class: 'label' %> + <%= f.email_field :email, autocomplete: 'off', class: 'base-input' %> +
+
+ <%= f.label :current_password, 'Current password', class: 'label' %> + <%= f.password_field :current_password, autocomplete: 'off', class: 'base-input' %> +
+
+ <%= f.button button_title, class: 'base-button' %> +
+ <% end %> +
+
+
diff --git a/app/views/profile/password.html.erb b/app/views/profile/password.html.erb new file mode 100644 index 00000000..8a54cb03 --- /dev/null +++ b/app/views/profile/password.html.erb @@ -0,0 +1,25 @@ +
+ <%= render 'shared/settings_nav' %> +
+

Profile

+ <%= render 'navigation' %> + <%= form_for current_user, url: update_password_settings_profile_index_path, method: :patch, html: { autocomplete: 'off', class: 'space-y-4' } do |f| %> +
+ <%= f.label :current_password, 'Current password', class: 'label' %> + <%= f.password_field :current_password, autocomplete: 'off', class: 'base-input' %> +
+
+ <%= f.label :password, 'New password', class: 'label' %> + <%= f.password_field :password, autocomplete: 'off', class: 'base-input' %> +
+
+ <%= f.label :password_confirmation, 'Confirm new password', class: 'label' %> + <%= f.password_field :password_confirmation, autocomplete: 'off', class: 'base-input' %> +
+
+ <%= f.button button_title, class: 'base-button' %> +
+ <% end %> +
+
+
diff --git a/app/views/shared/_navbar.html.erb b/app/views/shared/_navbar.html.erb index 6716731e..27b8a588 100644 --- a/app/views/shared/_navbar.html.erb +++ b/app/views/shared/_navbar.html.erb @@ -12,7 +12,7 @@