Skip to content

Commit

Permalink
Merge pull request #226 from freerange/inline-my-account-forms
Browse files Browse the repository at this point in the history
Inline /account forms
  • Loading branch information
chrislo authored Oct 29, 2024
2 parents 980f2e5 + 294826d commit f48d9ff
Show file tree
Hide file tree
Showing 37 changed files with 349 additions and 185 deletions.
9 changes: 9 additions & 0 deletions app/components/error_box_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

class ErrorBoxComponent < ViewComponent::Base
def initialize(title:)
@title = title

super
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div class="w-full border border-red-600 p-4 mb-3">
<h2 class="font-bold mb-3">
<%= @title %>
</h2>

<%= content %>
</div>
15 changes: 15 additions & 0 deletions app/components/model_error_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

class ModelErrorComponent < ViewComponent::Base
def initialize(model:)
@model = model

super
end

def render?
return false unless @model

@model.errors.any?
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<%= render(ErrorBoxComponent.new(
title: "#{pluralize(@model.errors.count, "error")} prohibited this #{@model.class.name.downcase} from being saved"
)) do %>
<ul>
<% @model.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
<% end %>
9 changes: 9 additions & 0 deletions app/components/sidebar_section_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

class SidebarSectionComponent < ViewComponent::Base
def initialize(title:)
@title = title

super
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<section class="flex flex-col md:flex-row py-6">
<div class="md:basis-1/4 mb-3 md:mb-0">
<h2 class="text-lg font-bold"><%= @title %></h2>
</div>
<div class="md:basis-3/4">
<%= content %>
</div>
</section>
2 changes: 1 addition & 1 deletion app/controllers/identity/email_verifications_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def set_user
token = EmailVerificationToken.find_signed!(params[:sid])
@user = token.user
rescue StandardError
redirect_to edit_identity_email_path, alert: 'That email verification link is invalid'
redirect_to root_path, alert: 'That email verification link is invalid'
end

def send_email_verification
Expand Down
17 changes: 7 additions & 10 deletions app/controllers/identity/emails_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ module Identity
class EmailsController < ApplicationController
before_action :set_user

def edit
authorize @user
end

def update
authorize @user

if !@user.authenticate(params[:current_password])
redirect_to edit_identity_email_path, alert: 'The password you entered is incorrect'
flash[:emails_update_password_incorrect] = 'The password you entered is incorrect'
redirect_to account_path
elsif @user.update(email: params[:email])
redirect_to_root
resend_verification_email_and_redirect
else
render :edit, status: :unprocessable_entity
render 'users/show', status: :unprocessable_entity
end
end

Expand All @@ -26,12 +23,12 @@ def set_user
@user = Current.user
end

def redirect_to_root
def resend_verification_email_and_redirect
if @user.email_previously_changed?
resend_email_verification
redirect_to root_path, notice: 'Your email has been changed'
redirect_to account_path, notice: 'Your email has been changed'
else
redirect_to root_path
redirect_to account_path
end
end

Expand Down
11 changes: 4 additions & 7 deletions app/controllers/passwords_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@
class PasswordsController < ApplicationController
before_action :set_user

def edit
authorize @user
end

def update
authorize @user

if !@user.authenticate(params[:current_password])
redirect_to edit_password_path, alert: 'The current password you entered is incorrect'
flash[:incorrect_password] = 'The current password you entered is incorrect'
redirect_to account_path
elsif @user.update(user_params)
redirect_to root_path, notice: 'Your password has been changed'
redirect_to account_path, notice: 'Your password has been changed'
else
render :edit, status: :unprocessable_entity
render 'users/show', status: :unprocessable_entity
end
end

Expand Down
24 changes: 7 additions & 17 deletions app/controllers/payout_details_controller.rb
Original file line number Diff line number Diff line change
@@ -1,46 +1,36 @@
# frozen_string_literal: true

class PayoutDetailsController < ApplicationController
def new
@payout_detail = PayoutDetail.new(user:)
authorize @payout_detail
end

def edit
@payout_detail = user.payout_detail
raise ActiveRecord::RecordNotFound unless @payout_detail

authorize @payout_detail
end
before_action :set_user

def create
@payout_detail = PayoutDetail.new(payout_detail_params.merge(user:))
@payout_detail = PayoutDetail.new(payout_detail_params.merge(user: @user))
authorize @payout_detail

if @payout_detail.save
redirect_to account_url, notice: 'Payout details added'
else
render :new, status: :unprocessable_entity
render 'users/show', status: :unprocessable_entity
end
end

def update
@payout_detail = user.payout_detail
@payout_detail = @user.payout_detail
raise ActiveRecord::RecordNotFound unless @payout_detail

authorize @payout_detail

if @payout_detail.update(payout_detail_params)
redirect_to account_url, notice: 'Payout details updated'
else
render :edit, status: :unprocessable_entity
render 'users/show', status: :unprocessable_entity
end
end

private

def user
Current.user
def set_user
@user = Current.user
end

def payout_detail_params
Expand Down
10 changes: 9 additions & 1 deletion app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
# frozen_string_literal: true

class UsersController < ApplicationController
before_action :set_user

def show
authorize User
authorize @user
end

private

def set_user
@user = Current.user
end
end
2 changes: 1 addition & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class User < ApplicationRecord
self.email = email.downcase.strip
end

before_validation if: :email_changed?, on: :update do
before_update if: :email_changed? do
self.verified = false
end

Expand Down
2 changes: 1 addition & 1 deletion app/views/albums/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<%= form_for([album.artist, album], builder: TailwindFormBuilder, data: { controller: 'multiple-upload', action: 'direct-upload:initialize->multiple-upload#init direct-upload:progress->multiple-upload#progress' }) do |form| %>
<%= render('shared/errors', model: album) %>
<%= render ModelErrorComponent.new(model: album) %>
<%= form.text_field :title, class: 'w-full mb-3' %>
<%= form.currency_field :price, symbol: '£', class: 'w-full mb-2' %>
<%= form.text_area :about, rows: 10, class: 'w-full mb-3' %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/artists/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<%= form_with(model: artist, class: "contents", builder: TailwindFormBuilder) do |form| %>
<%= render('shared/errors', model: artist) %>
<%= render ModelErrorComponent.new(model: artist) %>
<%= form.text_field :name, class: 'w-full mb-3' %>
<%= form.text_field :location, class: 'w-full mb-3' %>
<%= form.text_field :description, class: 'w-full mb-3' %>
Expand Down
21 changes: 0 additions & 21 deletions app/views/identity/emails/edit.html.erb

This file was deleted.

2 changes: 1 addition & 1 deletion app/views/identity/password_resets/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<%= render('shared/page_header', text: 'Reset your password') %>
<%= form_with(url: identity_password_reset_path, method: :patch, builder: TailwindFormBuilder) do |form| %>
<%= render 'shared/errors', model: @user %>
<%= render ModelErrorComponent.new(model: @user) %>
<%= form.hidden_field :sid, value: params[:sid] %>
<%= form.password_field :password, label: { text: 'New password' }, required: true, autofocus: true, autocomplete: "new-password", class: 'w-full mb-3' %>
<%= form.password_field :password_confirmation, label: { text: 'Confirm new password' }, required: true, autocomplete: "new-password", class: 'w-full mb-3' %>
Expand Down
13 changes: 0 additions & 13 deletions app/views/passwords/edit.html.erb

This file was deleted.

2 changes: 1 addition & 1 deletion app/views/payout_details/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<p class="text-slate-500 mb-6">We use <a class="underline" href="https://wise.com">Wise</a> to make payouts once a month. Wise will email you at <span class="font-bold"><%= Current.user.email %></span> to ask for your bank details. To make the payment we need the following:</p>

<%= form_with(model: payout_detail, class: "contents", builder: TailwindFormBuilder) do |form| %>
<%= render('shared/errors', model: payout_detail) %>
<%= render ModelErrorComponent.new(model: payout_detail) %>
<%= form.text_field :name, placeholder: 'Bartholomew J. Simpson', class: 'w-full' %>
<p class="text-slate-500 italic text-sm mb-3">Your full name as used on your bank account.</p>

Expand Down
4 changes: 2 additions & 2 deletions app/views/purchase_mailer/notify_artist.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
for <%= number_to_currency(@purchase.price, unit: "£") %>.</p>

<% if @user.payout_detail %>
<p>You have already provided your payout details. If you need to, you can <%= link_to 'change them', edit_payout_detail_url %>.</p>
<p>You have already provided your payout details. If you need to, you can <%= link_to 'change them', account_url %>.</p>
<% else %>
<p><b>Important:</b> we need to know <%= link_to 'some details', new_payout_detail_url %> before we can make a
<p><b>Important:</b> we need to know <%= link_to 'some details', account_url %> before we can make a
payment to you.</p>
<% end %>

Expand Down
2 changes: 1 addition & 1 deletion app/views/registrations/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<%= render 'shared/page_header', text: 'Sign up' %>
<%= form_with(url: sign_up_path, builder: TailwindFormBuilder, data: { turbo: false }) do |form| %>
<%= render('shared/errors', model: @user) %>
<%= render ModelErrorComponent.new(model: @user) %>
<%= form.email_field :email, value: @user.email, required: true, autofocus: true, autocomplete: "email", class: 'w-full mb-3' %>
<%= form.password_field :password, required: true, autocomplete: "new-password", class: 'w-full mb-3' %>
<%= form.password_field :password_confirmation, required: true, autocomplete: "new-password", class: 'w-full mb-6' %>
Expand Down
13 changes: 0 additions & 13 deletions app/views/shared/_errors.html.erb

This file was deleted.

73 changes: 63 additions & 10 deletions app/views/users/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,11 +1,64 @@
<%= render('shared/page_header', text: 'My account') %>

<ul>
<li><%= text_link_to "Change password", edit_password_path %></li>
<li><%= text_link_to "Change email address", edit_identity_email_path %></li>
<% if Current.user.payout_detail %>
<li><%= text_link_to "Edit payout details", edit_payout_detail_path %></li>
<% else %>
<li><%= text_link_to "Add payout details", new_payout_detail_path %></li>
<div class="flex flex-col divide-y divide-slate-300">
<h1 class="text-2xl font-bold mb-1">My account</h1>

<%= render(SidebarSectionComponent.new(title: 'Password')) do %>
<%= form_with(url: password_path, method: :patch, builder: TailwindFormBuilder) do |form| %>
<% if flash[:incorrect_password] %>
<%= render ErrorBoxComponent.new(title: 'Incorrect password').with_content(flash[:incorrect_password]) %>
<% end %>
<% if @user.errors.include?(:password) %>
<%= render ModelErrorComponent.new(model: @user) %>
<% end %>
<%= form.password_field :current_password, required: true, autofocus: true, autocomplete: "current-password", class: "w-full mb-3" %>
<%= form.password_field :password, label: { text: "New password"}, required: true, autocomplete: "new-password", class: "w-full mb-3" %>
<%= form.password_field :password_confirmation, label: { text: "Confirm new password"}, required: true, autocomplete: "new-password", class: "w-full mb-3" %>
<div class="flex flex-row justify-end">
<%= form.submit "Save changes", class: "mt-3" %>
</div>
<% end %>
<% end %>
<%= render(SidebarSectionComponent.new(title: 'Email address')) do %>
<% unless Current.user.verified? %>
<div class="mb-3 border border-slate-300 p-4">
<p>We sent a verification email to the address below. Check that email and follow those instructions to confirm it's your email address.</p>
<p><%= button_to "Re-send verification email", identity_email_verification_path, class: 'py-3 px-5 bg-amber-600 hover:bg-amber-500 text-white font-medium cursor-pointer my-3' %></p>
</div>
<% end %>
<%= form_with(url: identity_email_path, method: :patch, builder: TailwindFormBuilder) do |form| %>
<% if flash[:emails_update_password_incorrect] %>
<%= render ErrorBoxComponent.new(title: 'Incorrect password').with_content(flash[:emails_update_password_incorrect]) %>
<% end %>
<% if @user.errors.include?(:email) %>
<%= render ModelErrorComponent.new(model: @user) %>
<% end %>
<%= form.email_field :email, label: { text: "New email" }, required: true, autofocus: true, class: 'w-full mb-3' %>
<%= form.password_field :current_password, required: true, autocomplete: "current-password", class: 'w-full mb-3' %>
<div class="flex flex-row justify-end">
<%= form.submit "Save changes", class: 'mt-3' %>
</div>
<% end %>
<% end %>
<%= render(SidebarSectionComponent.new(title: 'Payout details')) do %>
<p class="text-slate-500 mb-6">We use <a class="underline" href="https://wise.com">Wise</a> to make payouts once a month. Wise will email you at <span class="font-bold"><%= Current.user.email %></span> to ask for your bank details. To make the payment we need the following:</p>

<% payout_detail = @user.payout_detail || PayoutDetail.new(user: @user) %>
<%= form_with(model: payout_detail, class: "contents", builder: TailwindFormBuilder) do |form| %>
<%= render ModelErrorComponent.new(model: payout_detail) %>
<%= form.text_field :name, placeholder: 'Bartholomew J. Simpson', class: 'w-full' %>
<p class="text-slate-500 italic text-sm mb-3">Your full name as used on your bank account.</p>

<%= form.select :country, options_for_payout_details_country_select, include_blank: true, label: { text: 'Country / Region' }, class: 'w-full' %>
<p class="text-slate-500 italic text-sm mb-3">We support payouts to the regions/countries <a href="https://wise.com/help/articles/2571942/what-countriesregions-can-i-send-to" class="underline">that Wise supports</a>.</p>

<div class="flex flex-row justify-end">
<% if payout_detail.persisted? %>
<%= form.submit "Save changes", class: 'mt-3'%>
<% else %>
<%= form.submit "Add payout details", class: 'mt-3'%>
<% end %>
</div>
<% end %>
<% end %>
</ul>
Loading

0 comments on commit f48d9ff

Please sign in to comment.