Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline /account forms #226

Merged
merged 15 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 [email protected](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 [email protected](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