diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2023-04-16 07:01:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-16 07:01:24 +0200 |
commit | e5c0b1673587885e5bbffbb376b16d773fb68193 (patch) | |
tree | 73dfe93b684454024b2de62ecdf0c6f30201f7fb /app | |
parent | 955ec252a421a5060345815bac0c63e8718bc3d8 (diff) |
Add progress indicator to sign-up flow (#24545)
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/auth/setup_controller.rb | 19 | ||||
-rw-r--r-- | app/helpers/application_helper.rb | 4 | ||||
-rw-r--r-- | app/javascript/styles/mastodon/forms.scss | 86 | ||||
-rw-r--r-- | app/views/auth/registrations/new.html.haml | 8 | ||||
-rw-r--r-- | app/views/auth/registrations/rules.html.haml | 2 | ||||
-rw-r--r-- | app/views/auth/setup/show.html.haml | 26 | ||||
-rw-r--r-- | app/views/auth/shared/_links.html.haml | 2 | ||||
-rw-r--r-- | app/views/auth/shared/_progress.html.haml | 25 |
8 files changed, 141 insertions, 31 deletions
diff --git a/app/controllers/auth/setup_controller.rb b/app/controllers/auth/setup_controller.rb index 46c5f2958..40916d288 100644 --- a/app/controllers/auth/setup_controller.rb +++ b/app/controllers/auth/setup_controller.rb @@ -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 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9dc8bba2d..828688b04 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -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')) diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index 7d4bde5e9..dc52bcd87 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -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; + } +} diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml index 0d8fd800f..4df0f95d5 100644 --- a/app/views/auth/registrations/new.html.haml +++ b/app/views/auth/registrations/new.html.haml @@ -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] diff --git a/app/views/auth/registrations/rules.html.haml b/app/views/auth/registrations/rules.html.haml index 8e7a90cbe..aa16ab957 100644 --- a/app/views/auth/registrations/rules.html.haml +++ b/app/views/auth/registrations/rules.html.haml @@ -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) diff --git a/app/views/auth/setup/show.html.haml b/app/views/auth/setup/show.html.haml index 1a6611ceb..913b0c913 100644 --- a/app/views/auth/setup/show.html.haml +++ b/app/views/auth/setup/show.html.haml @@ -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' diff --git a/app/views/auth/shared/_links.html.haml b/app/views/auth/shared/_links.html.haml index f078e2f7e..757ef0a09 100644 --- a/app/views/auth/shared/_links.html.haml +++ b/app/views/auth/shared/_links.html.haml @@ -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 } diff --git a/app/views/auth/shared/_progress.html.haml b/app/views/auth/shared/_progress.html.haml new file mode 100644 index 000000000..578f62fa9 --- /dev/null +++ b/app/views/auth/shared/_progress.html.haml @@ -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') |