Skip to content

Commit

Permalink
Refactor user forms to FrontDoorForm
Browse files Browse the repository at this point in the history
Use form_with for reg edit view

form_with was added to replace form_for

rails/rails#26976

Extract helpers for front door form

Extract FormDoorForm component for registration

Refactor user forms to FrontDoorForm
  • Loading branch information
rossta committed Jun 13, 2024
1 parent c667a70 commit d8fb985
Show file tree
Hide file tree
Showing 13 changed files with 227 additions and 355 deletions.
2 changes: 1 addition & 1 deletion app/controllers/concerns/authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def warden

def authenticate_user!
store_location
redirect_to new_users_session_path, alert: "You need to login to access that page" unless user_signed_in?
redirect_to new_users_session_path, alert: "You need to sign in to access that page" unless user_signed_in?
end

def redirect_admin_if_authenticated
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/users/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def new
def create
@user = warden.authenticate!(:password, scope: :user)

redirect_to login_success_path, notice: "Signed in"
redirect_to login_success_path, notice: "Signed in successfully"
end

def destroy
Expand Down
78 changes: 78 additions & 0 deletions app/views/components/layouts/front_door_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
class Layouts::FrontDoorForm < Phlex::HTML
include Phlex::Rails::Helpers::FormWith
include Phlex::Rails::Helpers::FieldsFor
include Phlex::Rails::Helpers::Label
include Phlex::Rails::Helpers::Object
include Phlex::Rails::Helpers::Routes
include InlineSvg::ActionView::Helpers

def initialize(title:)
@title = title
end

def view_template(&)
form_layout(&)
end

def form_layout(&block)
div(class: "flex min-h-full flex-col justify-center px-6 py-12 lg:px-8") do
div(class: "sm:mx-auto sm:w-full sm:max-w-sm text-joy-title") do
plain inline_svg_tag "joy-logo.svg",
class: "fill-current mx-auto",
style: "max-width: 64px;",
alt: "Joy of Rails"
h2(
class: "mt-4 text-center text-2xl font-bold leading-9 tracking-tight"
) { @title }
end
div(class: "mt-10 sm:mx-auto sm:w-full sm:max-w-sm", &block)
end
end

def form_with(**opts, &block)
super(
class: "space-y-6",
**opts,
&block
)
end

def form_header(&block)
div(class: "sm:mx-auto sm:w-full sm:max-w-sm text-joy-title") do
plain inline_svg_tag "joy-logo.svg",
class: "fill-current mx-auto",
style: "max-width: 64px;",
alt: "Joy of Rails"
h2(
class: "mt-4 text-center text-2xl font-bold leading-9 tracking-tight",
&block
)
end
end

def form_label(form, *args, **opts)
div(class: "flex items-center justify-between") do
plain form.label(*args, class: "block text-sm font-medium leading-6", **opts)
end
end

def form_field(form, method, *args, **opts)
div(class: "mt-2") do
plain form.send(
method,
*args,
class: "block w-full rounded-md border-0 py-1.5 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6",
**opts
)
end
end

def form_button(form, text)
div(class: "pt-6") do
plain form.button text,
type: :submit,
class:
"flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
end
end
end
19 changes: 4 additions & 15 deletions app/views/users/confirmations/edit_view.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
class Users::Confirmations::EditView < ApplicationView
include Phlex::Rails::Helpers::FormWith
include Phlex::Rails::Helpers::Object
include Phlex::Rails::Helpers::Routes
include InlineSvg::ActionView::Helpers

def initialize(user:, confirmation_token:)
@user = user
@confirmation_token = confirmation_token
end

def view_template
render Layouts::FrontDoor.new(title: "One-click confirm") do
form_with model: @user,
url: users_confirmation_path(@confirmation_token),
class: "space-y-6" do |form|
div(class: "pt-6") do
plain form.button "Confirm email: #{@user.email}",
type: :submit,
class:
"flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
end
render Layouts::FrontDoorForm.new(title: "One-click confirm") do |layout|
layout.form_with model: @user,
url: users_confirmation_path(@confirmation_token) do |form|
layout.form_button form, "Confirm email: #{@user.email}"
end
end
end
Expand Down
58 changes: 14 additions & 44 deletions app/views/users/confirmations/new_view.rb
Original file line number Diff line number Diff line change
@@ -1,56 +1,26 @@
class Users::Confirmations::NewView < ApplicationView
include Phlex::Rails::Helpers::EmailField
include Phlex::Rails::Helpers::FormWith
include Phlex::Rails::Helpers::Label
include Phlex::Rails::Helpers::Object
include Phlex::Rails::Helpers::Routes
include InlineSvg::ActionView::Helpers

def initialize(user:)
@user = user
end

def view_template
div(class: "flex min-h-full flex-col justify-center px-6 py-12 lg:px-8") do
div(class: "sm:mx-auto sm:w-full sm:max-w-sm text-joy-title") do
plain inline_svg_tag "joy-logo.svg",
class: "fill-current mx-auto",
style: "max-width: 64px;",
alt: "Joy of Rails"
h2(
class: "mt-4 text-center text-2xl font-bold leading-9 tracking-tight"
) { "Resend confirmation instructions" }
end
div(class: "mt-10 sm:mx-auto sm:w-full sm:max-w-sm") do
form_with model: @user,
url: users_confirmations_path,
class: "space-y-6" do |form|
if form.object.errors.any?
ul do
form.object.errors.full_messages.each do |message|
li { message }
end
end
end
div do
plain form.label :email,
"Email address",
class: "block text-sm font-medium leading-6"
div(class: "mt-2") do
plain form.email_field :email,
autocomplete: "email",
required: true,
class:
"block w-full rounded-md border-0 py-1.5 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
render Layouts::FrontDoorForm.new(title: "Resend confirmation instructions") do |layout|
layout.form_with model: @user,
url: users_confirmations_path do |form|
if form.object.errors.any?
ul do
form.object.errors.full_messages.each do |message|
li { message }
end
end
div(class: "pt-6") do
plain form.button "Send me confirmation instructions",
type: :submit,
class:
"flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
end
end
fieldset do
layout.form_label form, :email, "Email address"
layout.form_field form, :email_field, :email,
autocomplete: "email",
required: true
end
layout.form_button form, "Send me confirmation instructions"
end
end
end
Expand Down
62 changes: 16 additions & 46 deletions app/views/users/passwords/edit_view.rb
Original file line number Diff line number Diff line change
@@ -1,60 +1,30 @@
# frozen_string_literal: true

class Users::Passwords::EditView < Phlex::HTML
include Phlex::Rails::Helpers::FormWith
include Phlex::Rails::Helpers::Object
include Phlex::Rails::Helpers::Routes
include InlineSvg::ActionView::Helpers

class Users::Passwords::EditView < ApplicationView
def initialize(user:, password_reset_token:)
@user = user
@password_reset_token = password_reset_token
end

def view_template
render Layouts::FrontDoor.new(title: "Reset your password") do
form_with model: @user,
url: users_password_path(@password_reset_token),
class: "space-y-6" do |form|
div do
div(class: "flex items-center justify-between") do
form_label form, :password
end
div(class: "mt-2") do
form_field form, :password_field, :password,
type: "password",
autocomplete: "current-password",
required: true
end
end
div do
div(class: "flex items-center justify-between") do
form_label form, :password_confirmation
end
div(class: "mt-2") do
form_field form, :password_field, :password_confirmation,
type: "password",
autocomplete: "current-password",
required: true
end
render Layouts::FrontDoorForm.new(title: "Reset your password") do |layout|
layout.form_with model: @user, url: users_password_path(@password_reset_token) do |form|
fieldset do
layout.form_label form, :password
layout.form_field form, :password_field, :password,
type: "password",
autocomplete: "current-password",
required: true
end
div(class: "pt-6") do
plain form.button "Update password",
type: :submit,
class:
"flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
fieldset do
layout.form_label form, :password_confirmation
layout.form_field form, :password_field, :password_confirmation,
type: "password",
autocomplete: "current-password",
required: true
end
layout.form_button form, "Update password"
end
end
end

private

def form_label(form, *, **)
plain form.label(*, class: "block text-sm font-medium leading-6", **)
end

def form_field(form, method, *, **)
plain form.send(method, *, class: "block w-full rounded-md border-0 py-1.5 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6", **)
end
end
29 changes: 8 additions & 21 deletions app/views/users/passwords/new_view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,15 @@ def initialize(user:)
end

def view_template
render Layouts::FrontDoor.new(title: "Forgot your password?") do
form_with model: @user,
url: users_passwords_path,
class: "space-y-6" do |form|
div do
plain form.label :email,
"Email address",
class: "block text-sm font-medium leading-6"
div(class: "mt-2") do
plain form.email_field :email,
autocomplete: "email",
required: true,
class:
"block w-full rounded-md border-0 py-1.5 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
end
end
div(class: "pt-6") do
plain form.button "Send me password reset instructions",
type: :submit,
class:
"flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
render Layouts::FrontDoorForm.new(title: "Forgot your password?") do |layout|
layout.form_with model: @user, url: users_passwords_path do |form|
fieldset do
layout.form_label form, :email, "Email address"
layout.form_field form, :email_field, :email,
autocomplete: "email",
required: true
end
layout.form_button form, "Send me password reset instructions"
end
end
end
Expand Down
13 changes: 0 additions & 13 deletions app/views/users/registrations/edit.html.erb

This file was deleted.

Loading

0 comments on commit d8fb985

Please sign in to comment.