Add progress indicator to sign-up flow (#24545)
This commit is contained in:
parent
955ec252a4
commit
e5c0b16735
76 changed files with 157 additions and 105 deletions
|
@ -10,15 +10,7 @@ class Auth::SetupController < ApplicationController
|
|||
|
||||
skip_before_action :require_functional!
|
||||
|
||||
def show
|
||||
flash.now[:notice] = begin
|
||||
if @user.pending?
|
||||
I18n.t('devise.registrations.signed_up_but_pending')
|
||||
else
|
||||
I18n.t('devise.registrations.signed_up_but_unconfirmed')
|
||||
end
|
||||
end
|
||||
end
|
||||
def show; end
|
||||
|
||||
def update
|
||||
# This allows updating the e-mail without entering a password as is required
|
||||
|
@ -26,14 +18,13 @@ class Auth::SetupController < ApplicationController
|
|||
# that were not confirmed yet
|
||||
|
||||
if @user.update(user_params)
|
||||
redirect_to auth_setup_path, notice: I18n.t('devise.confirmations.send_instructions')
|
||||
@user.resend_confirmation_instructions unless @user.confirmed?
|
||||
redirect_to auth_setup_path, notice: I18n.t('auth.setup.new_confirmation_instructions_sent')
|
||||
else
|
||||
render :show
|
||||
end
|
||||
end
|
||||
|
||||
helper_method :missing_email?
|
||||
|
||||
private
|
||||
|
||||
def require_unconfirmed_or_pending!
|
||||
|
@ -51,8 +42,4 @@ class Auth::SetupController < ApplicationController
|
|||
def user_params
|
||||
params.require(:user).permit(:email)
|
||||
end
|
||||
|
||||
def missing_email?
|
||||
truthy_param?(:missing_email)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -117,6 +117,10 @@ module ApplicationHelper
|
|||
content_tag(:i, nil, attributes.merge(class: class_names.join(' ')))
|
||||
end
|
||||
|
||||
def check_icon
|
||||
content_tag(:svg, tag(:path, 'fill-rule': 'evenodd', 'clip-rule': 'evenodd', d: 'M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z'), xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 20 20', fill: 'currentColor')
|
||||
end
|
||||
|
||||
def visibility_icon(status)
|
||||
if status.public_visibility?
|
||||
fa_icon('globe', title: I18n.t('statuses.visibilities.public'))
|
||||
|
|
|
@ -1112,3 +1112,89 @@ code {
|
|||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.progress-tracker {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 30px;
|
||||
margin-bottom: 30px;
|
||||
|
||||
li {
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.separator {
|
||||
height: 2px;
|
||||
background: $ui-base-lighter-color;
|
||||
flex: 1 1 auto;
|
||||
|
||||
&.completed {
|
||||
background: $highlight-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.circle {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid $ui-base-lighter-color;
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
svg {
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
position: absolute;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: $secondary-text-color;
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
width: 100px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
li:first-child .label {
|
||||
left: auto;
|
||||
inset-inline-start: 0;
|
||||
text-align: start;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
li:last-child .label {
|
||||
left: auto;
|
||||
inset-inline-end: 0;
|
||||
text-align: end;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.active .circle {
|
||||
border-color: $highlight-text-color;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: $highlight-text-color;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.completed .circle {
|
||||
border-color: $highlight-text-color;
|
||||
background: $highlight-text-color;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
= render partial: 'shared/og', locals: { description: description_for_sign_up }
|
||||
|
||||
= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { novalidate: false }) do |f|
|
||||
= render 'auth/shared/progress', stage: 'details'
|
||||
|
||||
%h1.title= t('auth.sign_up.title', domain: site_hostname)
|
||||
%p.lead= t('auth.sign_up.preamble')
|
||||
|
||||
|
@ -18,7 +20,7 @@
|
|||
.fields-group
|
||||
= f.simple_fields_for :account do |ff|
|
||||
= ff.input :display_name, wrapper: :with_label, label: false, required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.display_name'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.display_name') }
|
||||
= ff.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.username'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}", hint: false
|
||||
= ff.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.username'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}"
|
||||
= f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'username' }, hint: false
|
||||
= f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, hint: false
|
||||
= f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_password'), autocomplete: 'new-password' }, hint: false
|
||||
|
@ -26,9 +28,11 @@
|
|||
= f.input :website, as: :url, wrapper: :with_label, label: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: 'Website'), autocomplete: 'off' }
|
||||
|
||||
- if approved_registrations? && !@invite.present?
|
||||
%p.lead= t('auth.sign_up.manual_review', domain: site_hostname)
|
||||
|
||||
.fields-group
|
||||
= f.simple_fields_for :invite_request, resource.invite_request || resource.build_invite_request do |invite_request_fields|
|
||||
= invite_request_fields.input :text, as: :text, wrapper: :with_block_label, required: Setting.require_invite_text
|
||||
= invite_request_fields.input :text, as: :text, wrapper: :with_block_label, required: Setting.require_invite_text, label: false, hint: false
|
||||
|
||||
|
||||
= hidden_field_tag :accept, params[:accept]
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
= render partial: 'shared/og', locals: { description: description_for_sign_up }
|
||||
|
||||
.simple_form
|
||||
= render 'auth/shared/progress', stage: 'rules'
|
||||
|
||||
%h1.title= t('auth.rules.title')
|
||||
%p.lead= t('auth.rules.preamble', domain: site_hostname)
|
||||
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
- content_for :page_title do
|
||||
= t('auth.setup.title')
|
||||
|
||||
- if missing_email?
|
||||
= simple_form_for(@user, url: auth_setup_path) do |f|
|
||||
= render 'shared/error_messages', object: @user
|
||||
= simple_form_for(@user, url: auth_setup_path) do |f|
|
||||
= render 'auth/shared/progress', stage: 'confirm'
|
||||
|
||||
.fields-group
|
||||
%p.hint= t('auth.setup.email_below_hint_html')
|
||||
%h1.title= t('auth.setup.title')
|
||||
%p.lead= t('auth.setup.email_settings_hint_html', email: content_tag(:strong, @user.email))
|
||||
|
||||
.fields-group
|
||||
= f.input :email, required: true, hint: false, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'off' }
|
||||
= render 'shared/error_messages', object: @user
|
||||
|
||||
.actions
|
||||
= f.submit t('admin.accounts.change_email.label'), class: 'button'
|
||||
- else
|
||||
.simple_form
|
||||
%p.hint= t('auth.setup.email_settings_hint_html', email: content_tag(:strong, @user.email))
|
||||
%p.lead
|
||||
%strong= t('auth.setup.link_not_received')
|
||||
%p.lead= t('auth.setup.email_below_hint_html')
|
||||
|
||||
.fields-group
|
||||
= f.input :email, required: true, hint: false, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'off' }
|
||||
|
||||
.actions
|
||||
= f.submit t('auth.resend_confirmation'), class: 'button'
|
||||
|
||||
.form-footer= render 'auth/shared/links'
|
||||
|
|
|
@ -14,5 +14,5 @@
|
|||
- if controller_name != 'confirmations' && (!user_signed_in? || !current_user.confirmed? || current_user.unconfirmed_email.present?)
|
||||
%li= link_to t('auth.didnt_get_confirmation'), new_user_confirmation_path
|
||||
|
||||
- if user_signed_in? && controller_name != 'setup'
|
||||
- if user_signed_in?
|
||||
%li= link_to t('auth.logout'), destroy_user_session_path, data: { method: :delete }
|
||||
|
|
25
app/views/auth/shared/_progress.html.haml
Normal file
25
app/views/auth/shared/_progress.html.haml
Normal file
|
@ -0,0 +1,25 @@
|
|||
- progress_index = { rules: 0, details: 1, confirm: 2 }[stage.to_sym]
|
||||
|
||||
%ol.progress-tracker
|
||||
%li{ class: progress_index.positive? ? 'completed' : 'active' }
|
||||
.circle
|
||||
- if progress_index.positive?
|
||||
= check_icon
|
||||
.label= t('auth.progress.rules')
|
||||
%li.separator{ class: progress_index.positive? ? 'completed' : nil }
|
||||
%li{ class: [progress_index > 1 && 'completed', progress_index == 1 && 'active'] }
|
||||
.circle
|
||||
- if progress_index > 1
|
||||
= check_icon
|
||||
.label= t('auth.progress.details')
|
||||
%li.separator{ class: progress_index > 1 ? 'completed' : nil }
|
||||
%li{ class: [progress_index > 2 && 'completed', progress_index == 2 && 'active'] }
|
||||
.circle
|
||||
- if progress_index > 2
|
||||
= check_icon
|
||||
.label= t('auth.progress.confirm')
|
||||
- if approved_registrations?
|
||||
%li.separator{ class: progress_index > 2 ? 'completed' : nil }
|
||||
%li
|
||||
.circle
|
||||
.label= t('auth.progress.review')
|
Loading…
Add table
Add a link
Reference in a new issue