mirror of
https://github.com/discourse/discourse.git
synced 2025-01-31 00:29:30 +08:00
UX: Add progress bar to the registration flow (#27694)
This commit is contained in:
parent
3a04443632
commit
b092ccbdc5
|
@ -21,16 +21,17 @@
|
||||||
this.model.authOptions.auth_provider
|
this.model.authOptions.auth_provider
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="login-welcome-header" id="create-account-title">
|
<SignupProgressBar @step="signup" />
|
||||||
<h1 class="login-title">{{i18n "create_account.header_title"}}</h1>
|
<WelcomeHeader
|
||||||
<img src={{this.wavingHandURL}} alt="" class="waving-hand" />
|
id="create-account-title"
|
||||||
<p class="login-subheader">{{i18n "create_account.subheader_title"}}</p>
|
@header={{i18n "create_account.header_title"}}
|
||||||
|
@subheader={{i18n "create_account.subheader_title"}}
|
||||||
|
>
|
||||||
<PluginOutlet
|
<PluginOutlet
|
||||||
@name="create-account-header-bottom"
|
@name="create-account-header-bottom"
|
||||||
@outletArgs={{hash showLogin=(route-action "showLogin")}}
|
@outletArgs={{hash showLogin=(route-action "showLogin")}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</WelcomeHeader>
|
||||||
|
|
||||||
{{#if this.showCreateForm}}
|
{{#if this.showCreateForm}}
|
||||||
<form id="login-form">
|
<form id="login-form">
|
||||||
{{#if this.associateHtml}}
|
{{#if this.associateHtml}}
|
||||||
|
@ -86,7 +87,6 @@
|
||||||
id="username-validation"
|
id="username-validation"
|
||||||
/>
|
/>
|
||||||
{{#unless this.usernameValidation.reason}}
|
{{#unless this.usernameValidation.reason}}
|
||||||
|
|
||||||
<span class="more-info" id="username-validation-more-info">
|
<span class="more-info" id="username-validation-more-info">
|
||||||
{{i18n "user.username.instructions"}}
|
{{i18n "user.username.instructions"}}
|
||||||
</span>
|
</span>
|
||||||
|
@ -307,9 +307,11 @@
|
||||||
|
|
||||||
<:footer>
|
<:footer>
|
||||||
{{#if (and this.showCreateForm this.site.mobileView)}}
|
{{#if (and this.showCreateForm this.site.mobileView)}}
|
||||||
<div class="disclaimer">
|
{{#if this.disclaimerHtml}}
|
||||||
{{html-safe this.disclaimerHtml}}
|
<div class="disclaimer">
|
||||||
</div>
|
{{html-safe this.disclaimerHtml}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
<div class="d-modal__footer-buttons">
|
<div class="d-modal__footer-buttons">
|
||||||
<DButton
|
<DButton
|
||||||
@action={{this.createAccount}}
|
@action={{this.createAccount}}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import { setting } from "discourse/lib/computed";
|
||||||
import cookie, { removeCookie } from "discourse/lib/cookie";
|
import cookie, { removeCookie } from "discourse/lib/cookie";
|
||||||
import { userPath } from "discourse/lib/url";
|
import { userPath } from "discourse/lib/url";
|
||||||
import { emailValid } from "discourse/lib/utilities";
|
import { emailValid } from "discourse/lib/utilities";
|
||||||
import { wavingHandURL } from "discourse/lib/waving-hand-url";
|
|
||||||
import NameValidation from "discourse/mixins/name-validation";
|
import NameValidation from "discourse/mixins/name-validation";
|
||||||
import PasswordValidation from "discourse/mixins/password-validation";
|
import PasswordValidation from "discourse/mixins/password-validation";
|
||||||
import UserFieldsValidation from "discourse/mixins/user-fields-validation";
|
import UserFieldsValidation from "discourse/mixins/user-fields-validation";
|
||||||
|
@ -106,11 +105,6 @@ export default class CreateAccount extends Component.extend(
|
||||||
return this.formSubmitted;
|
return this.formSubmitted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed()
|
|
||||||
wavingHandURL() {
|
|
||||||
return wavingHandURL();
|
|
||||||
}
|
|
||||||
|
|
||||||
@discourseComputed("userFields", "hasAtLeastOneLoginButton", "hasAuthOptions")
|
@discourseComputed("userFields", "hasAtLeastOneLoginButton", "hasAuthOptions")
|
||||||
modalBodyClasses(userFields, hasAtLeastOneLoginButton, hasAuthOptions) {
|
modalBodyClasses(userFields, hasAtLeastOneLoginButton, hasAuthOptions) {
|
||||||
const classes = [];
|
const classes = [];
|
||||||
|
|
|
@ -27,10 +27,15 @@
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if this.site.mobileView}}
|
{{#if this.site.mobileView}}
|
||||||
<Modal::Login::WelcomeHeader
|
<WelcomeHeader
|
||||||
@wavingHandURL={{this.wavingHandURL}}
|
@header={{i18n "login.header_title"}}
|
||||||
@createAccount={{this.createAccount}}
|
@subheader={{i18n "login.subheader_title"}}
|
||||||
/>
|
>
|
||||||
|
<PluginOutlet
|
||||||
|
@name="login-header-bottom"
|
||||||
|
@outletArgs={{hash createAccount=this.createAccount}}
|
||||||
|
/>
|
||||||
|
</WelcomeHeader>
|
||||||
{{#if this.showLoginButtons}}
|
{{#if this.showLoginButtons}}
|
||||||
<LoginButtons
|
<LoginButtons
|
||||||
@externalLogin={{this.externalLoginAction}}
|
@externalLogin={{this.externalLoginAction}}
|
||||||
|
@ -43,10 +48,15 @@
|
||||||
{{#if this.canLoginLocal}}
|
{{#if this.canLoginLocal}}
|
||||||
<div class={{if this.site.desktopView "login-left-side"}}>
|
<div class={{if this.site.desktopView "login-left-side"}}>
|
||||||
{{#if this.site.desktopView}}
|
{{#if this.site.desktopView}}
|
||||||
<Modal::Login::WelcomeHeader
|
<WelcomeHeader
|
||||||
@wavingHandURL={{this.wavingHandURL}}
|
@header={{i18n "login.header_title"}}
|
||||||
@createAccount={{this.createAccount}}
|
@subheader={{i18n "login.subheader_title"}}
|
||||||
/>
|
>
|
||||||
|
<PluginOutlet
|
||||||
|
@name="login-header-bottom"
|
||||||
|
@outletArgs={{hash createAccount=this.createAccount}}
|
||||||
|
/>
|
||||||
|
</WelcomeHeader>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<Modal::Login::LocalLoginForm
|
<Modal::Login::LocalLoginForm
|
||||||
@loginName={{this.loginName}}
|
@loginName={{this.loginName}}
|
||||||
|
@ -91,8 +101,9 @@
|
||||||
{{#if (and this.showLoginButtons this.site.desktopView)}}
|
{{#if (and this.showLoginButtons this.site.desktopView)}}
|
||||||
{{#unless this.canLoginLocal}}
|
{{#unless this.canLoginLocal}}
|
||||||
<div class="login-left-side">
|
<div class="login-left-side">
|
||||||
<Modal::Login::WelcomeHeader
|
<WelcomeHeader
|
||||||
@wavingHandURL={{this.wavingHandURL}}
|
@header={{i18n "login.header_title"}}
|
||||||
|
@subheader={{i18n "login.subheader_title"}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import cookie, { removeCookie } from "discourse/lib/cookie";
|
import cookie, { removeCookie } from "discourse/lib/cookie";
|
||||||
import { wantsNewWindow } from "discourse/lib/intercept-click";
|
import { wantsNewWindow } from "discourse/lib/intercept-click";
|
||||||
import { areCookiesEnabled } from "discourse/lib/utilities";
|
import { areCookiesEnabled } from "discourse/lib/utilities";
|
||||||
import { wavingHandURL } from "discourse/lib/waving-hand-url";
|
|
||||||
import {
|
import {
|
||||||
getPasskeyCredential,
|
getPasskeyCredential,
|
||||||
isWebauthnSupported,
|
isWebauthnSupported,
|
||||||
|
@ -64,10 +63,6 @@ export default class Login extends Component {
|
||||||
return this.loggingIn || this.loggedIn;
|
return this.loggingIn || this.loggedIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
get wavingHandURL() {
|
|
||||||
return wavingHandURL();
|
|
||||||
}
|
|
||||||
|
|
||||||
get modalBodyClasses() {
|
get modalBodyClasses() {
|
||||||
const classes = ["login-modal-body"];
|
const classes = ["login-modal-body"];
|
||||||
if (this.awaitingApproval) {
|
if (this.awaitingApproval) {
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
<div class="login-welcome-header">
|
|
||||||
<h1 class="login-title">{{i18n "login.header_title"}}</h1>
|
|
||||||
<img src={{@wavingHandURL}} alt="" class="waving-hand" />
|
|
||||||
<p class="login-subheader">{{i18n "login.subheader_title"}}</p>
|
|
||||||
<PluginOutlet
|
|
||||||
@name="login-header-bottom"
|
|
||||||
@outletArgs={{hash createAccount=@createAccount}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import { concat } from "@ember/helper";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
|
import { eq } from "truth-helpers";
|
||||||
|
import concatClass from "discourse/helpers/concat-class";
|
||||||
|
import dIcon from "discourse-common/helpers/d-icon";
|
||||||
|
import I18n from "discourse-i18n";
|
||||||
|
|
||||||
|
export default class SignupProgressBar extends Component {
|
||||||
|
@service siteSettings;
|
||||||
|
@tracked steps = [];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
if (this.siteSettings.must_approve_users) {
|
||||||
|
this.steps = ["signup", "activate", "approve", "login"];
|
||||||
|
} else {
|
||||||
|
this.steps = ["signup", "activate", "login"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stepText(step) {
|
||||||
|
return I18n.t(`create_account.progress_bar.${step}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentStepIndex() {
|
||||||
|
return this.steps.findIndex((step) => step === this.args.step);
|
||||||
|
}
|
||||||
|
|
||||||
|
get lastStepIndex() {
|
||||||
|
return this.steps.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
getStepState(index) {
|
||||||
|
if (index === this.currentStepIndex) {
|
||||||
|
return "active";
|
||||||
|
} else if (index < this.currentStepIndex) {
|
||||||
|
return "completed";
|
||||||
|
} else if (index > this.currentStepIndex) {
|
||||||
|
return "incomplete";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
{{#if @step}}
|
||||||
|
<div class="signup-progress-bar">
|
||||||
|
{{#each this.steps as |step index|}}
|
||||||
|
<div class="signup-progress-bar__segment">
|
||||||
|
<div
|
||||||
|
class={{concatClass
|
||||||
|
"signup-progress-bar__step"
|
||||||
|
(concat "--" (this.getStepState index))
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div class="signup-progress-bar__circle">
|
||||||
|
{{#if (eq (this.getStepState index) "completed")}}
|
||||||
|
{{dIcon "check"}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{#unless (eq index this.lastStepIndex)}}
|
||||||
|
<span
|
||||||
|
class={{concatClass
|
||||||
|
"signup-progress-bar__line"
|
||||||
|
(concat "--" (this.getStepState index))
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
|
{{/unless}}
|
||||||
|
</div>
|
||||||
|
<span class="signup-progress-bar__step-text">
|
||||||
|
{{this.stepText step}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</template>
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { wavingHandURL } from "discourse/lib/waving-hand-url";
|
||||||
|
|
||||||
|
const WelcomeHeader = <template>
|
||||||
|
<div class="login-welcome-header" ...attributes>
|
||||||
|
<h1 class="login-title">{{@header}}</h1>
|
||||||
|
<img src={{(wavingHandURL)}} alt="" class="waving-hand" />
|
||||||
|
{{#if @subheader}}
|
||||||
|
<p class="login-subheader">{{@subheader}}</p>
|
||||||
|
{{/if}}
|
||||||
|
{{yield}}
|
||||||
|
</div>
|
||||||
|
</template>;
|
||||||
|
|
||||||
|
export default WelcomeHeader;
|
|
@ -2,16 +2,12 @@ import Controller from "@ember/controller";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { service } from "@ember/service";
|
import { service } from "@ember/service";
|
||||||
import { resendActivationEmail } from "discourse/lib/user-activation";
|
import { resendActivationEmail } from "discourse/lib/user-activation";
|
||||||
import { wavingHandURL } from "discourse/lib/waving-hand-url";
|
|
||||||
import getUrl from "discourse-common/lib/get-url";
|
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
import I18n from "discourse-i18n";
|
import I18n from "discourse-i18n";
|
||||||
|
|
||||||
export default class AccountCreatedIndexController extends Controller {
|
export default class AccountCreatedIndexController extends Controller {
|
||||||
@service router;
|
@service router;
|
||||||
|
|
||||||
envelopeImageUrl = getUrl("/images/envelope.svg");
|
|
||||||
|
|
||||||
@discourseComputed
|
@discourseComputed
|
||||||
welcomeTitle() {
|
welcomeTitle() {
|
||||||
return I18n.t("invites.welcome_to", {
|
return I18n.t("invites.welcome_to", {
|
||||||
|
@ -19,11 +15,6 @@ export default class AccountCreatedIndexController extends Controller {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed
|
|
||||||
wavingHandURL() {
|
|
||||||
return wavingHandURL();
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
sendActivationEmail() {
|
sendActivationEmail() {
|
||||||
resendActivationEmail(this.get("accountCreated.username")).then(() => {
|
resendActivationEmail(this.get("accountCreated.username")).then(() => {
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { ajax } from "discourse/lib/ajax";
|
||||||
import { extractError } from "discourse/lib/ajax-error";
|
import { extractError } from "discourse/lib/ajax-error";
|
||||||
import DiscourseURL from "discourse/lib/url";
|
import DiscourseURL from "discourse/lib/url";
|
||||||
import { emailValid } from "discourse/lib/utilities";
|
import { emailValid } from "discourse/lib/utilities";
|
||||||
import { wavingHandURL } from "discourse/lib/waving-hand-url";
|
|
||||||
import NameValidation from "discourse/mixins/name-validation";
|
import NameValidation from "discourse/mixins/name-validation";
|
||||||
import PasswordValidation from "discourse/mixins/password-validation";
|
import PasswordValidation from "discourse/mixins/password-validation";
|
||||||
import UserFieldsValidation from "discourse/mixins/user-fields-validation";
|
import UserFieldsValidation from "discourse/mixins/user-fields-validation";
|
||||||
|
@ -42,7 +41,6 @@ export default class InvitesShowController extends Controller.extend(
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
userFields = null;
|
userFields = null;
|
||||||
authOptions = null;
|
authOptions = null;
|
||||||
inviteImageUrl = getUrl("/images/envelope.svg");
|
|
||||||
rejectedEmails = [];
|
rejectedEmails = [];
|
||||||
maskPassword = true;
|
maskPassword = true;
|
||||||
|
|
||||||
|
@ -261,11 +259,6 @@ export default class InvitesShowController extends Controller.extend(
|
||||||
return matchingProvider ? matchingProvider.get("prettyName") : providerName;
|
return matchingProvider ? matchingProvider.get("prettyName") : providerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@discourseComputed
|
|
||||||
wavingHandURL() {
|
|
||||||
return wavingHandURL();
|
|
||||||
}
|
|
||||||
|
|
||||||
@discourseComputed
|
@discourseComputed
|
||||||
ssoPath() {
|
ssoPath() {
|
||||||
return getUrl("/session/sso");
|
return getUrl("/session/sso");
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
|
import { service } from "@ember/service";
|
||||||
import PreloadStore from "discourse/lib/preload-store";
|
import PreloadStore from "discourse/lib/preload-store";
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import { deepMerge } from "discourse-common/lib/object";
|
import { deepMerge } from "discourse-common/lib/object";
|
||||||
import I18n from "discourse-i18n";
|
import I18n from "discourse-i18n";
|
||||||
|
|
||||||
export default class InvitesShow extends DiscourseRoute {
|
export default class InvitesShow extends DiscourseRoute {
|
||||||
|
@service siteSettings;
|
||||||
|
|
||||||
titleToken() {
|
titleToken() {
|
||||||
return I18n.t("invites.accept_title");
|
return I18n.t("invites.accept_title");
|
||||||
}
|
}
|
||||||
|
@ -21,17 +24,21 @@ export default class InvitesShow extends DiscourseRoute {
|
||||||
activate() {
|
activate() {
|
||||||
super.activate(...arguments);
|
super.activate(...arguments);
|
||||||
|
|
||||||
this.controllerFor("application").setProperties({
|
if (this.siteSettings.login_required) {
|
||||||
showSiteHeader: false,
|
this.controllerFor("application").setProperties({
|
||||||
});
|
showSiteHeader: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deactivate() {
|
deactivate() {
|
||||||
super.deactivate(...arguments);
|
super.deactivate(...arguments);
|
||||||
|
|
||||||
this.controllerFor("application").setProperties({
|
if (this.siteSettings.login_required) {
|
||||||
showSiteHeader: true,
|
this.controllerFor("application").setProperties({
|
||||||
});
|
showSiteHeader: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setupController(controller, model) {
|
setupController(controller, model) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<div id="simple-container">
|
{{body-class "account-created-page"}}
|
||||||
<div class="account-created">
|
{{hide-application-header-buttons "search" "login" "signup"}}
|
||||||
{{outlet}}
|
{{hide-application-sidebar}}
|
||||||
</div>
|
<div class="account-created">
|
||||||
|
{{outlet}}
|
||||||
</div>
|
</div>
|
|
@ -1,10 +1,10 @@
|
||||||
|
<SignupProgressBar @step="activate" />
|
||||||
<div class="ac-message">
|
<div class="ac-message">
|
||||||
<ActivationEmailForm
|
<ActivationEmailForm
|
||||||
@email={{this.newEmail}}
|
@email={{this.newEmail}}
|
||||||
@updateNewEmail={{this.updateNewEmail}}
|
@updateNewEmail={{this.updateNewEmail}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="activation-controls">
|
<div class="activation-controls">
|
||||||
<DButton
|
<DButton
|
||||||
@action={{this.changeEmail}}
|
@action={{this.changeEmail}}
|
||||||
|
|
|
@ -1,26 +1,11 @@
|
||||||
{{body-class "account-activation-page"}}
|
<SignupProgressBar @step="activate" />
|
||||||
<div class="container invites-show">
|
<WelcomeHeader @header={{this.welcomeTitle}} />
|
||||||
<div class="login-welcome-header">
|
<div class="success-info">
|
||||||
<h1 class="login-title">{{this.welcomeTitle}}</h1>
|
{{html-safe this.accountCreated.message}}
|
||||||
<img src={{this.wavingHandURL}} alt="" class="waving-hand" />
|
</div>
|
||||||
</div>
|
{{#if this.accountCreated.show_controls}}
|
||||||
|
<ActivationControls
|
||||||
<div class="ac-page">
|
@sendActivationEmail={{action "sendActivationEmail"}}
|
||||||
<div class="two-col">
|
@editActivationEmail={{action "editActivationEmail"}}
|
||||||
<div class="col-image">
|
/>
|
||||||
<img src={{this.envelopeImageUrl}} alt="" />
|
{{/if}}
|
||||||
</div>
|
|
||||||
<div class="col-form">
|
|
||||||
<div class="success-info">
|
|
||||||
{{html-safe this.accountCreated.message}}
|
|
||||||
</div>
|
|
||||||
{{#if this.accountCreated.show_controls}}
|
|
||||||
<ActivationControls
|
|
||||||
@sendActivationEmail={{action "sendActivationEmail"}}
|
|
||||||
@editActivationEmail={{action "editActivationEmail"}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<SignupProgressBar @step="activate" />
|
||||||
<div class="ac-message">
|
<div class="ac-message">
|
||||||
{{#if this.email}}
|
{{#if this.email}}
|
||||||
{{html-safe
|
{{html-safe
|
||||||
|
|
|
@ -4,11 +4,13 @@ import { action } from "@ember/object";
|
||||||
import { service } from "@ember/service";
|
import { service } from "@ember/service";
|
||||||
import RouteTemplate from "ember-route-template";
|
import RouteTemplate from "ember-route-template";
|
||||||
import DButton from "discourse/components/d-button";
|
import DButton from "discourse/components/d-button";
|
||||||
|
import SignupProgressBar from "discourse/components/signup-progress-bar";
|
||||||
|
import WelcomeHeader from "discourse/components/welcome-header";
|
||||||
|
import bodyClass from "discourse/helpers/body-class";
|
||||||
import hideApplicationHeaderButtons from "discourse/helpers/hide-application-header-buttons";
|
import hideApplicationHeaderButtons from "discourse/helpers/hide-application-header-buttons";
|
||||||
import hideApplicationSidebar from "discourse/helpers/hide-application-sidebar";
|
import hideApplicationSidebar from "discourse/helpers/hide-application-sidebar";
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import { wavingHandURL } from "discourse/lib/waving-hand-url";
|
|
||||||
import i18n from "discourse-common/helpers/i18n";
|
import i18n from "discourse-common/helpers/i18n";
|
||||||
import getURL from "discourse-common/lib/get-url";
|
import getURL from "discourse-common/lib/get-url";
|
||||||
|
|
||||||
|
@ -21,6 +23,16 @@ export default RouteTemplate(
|
||||||
@tracked needsApproval = false;
|
@tracked needsApproval = false;
|
||||||
@tracked errorMessage = null;
|
@tracked errorMessage = null;
|
||||||
|
|
||||||
|
get signupStep() {
|
||||||
|
if (this.needsApproval) {
|
||||||
|
return "approve";
|
||||||
|
} else if (this.accountActivated) {
|
||||||
|
return "login";
|
||||||
|
} else {
|
||||||
|
return "activate";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async activate() {
|
async activate() {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
@ -71,59 +83,52 @@ export default RouteTemplate(
|
||||||
}
|
}
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
{{hideApplicationSidebar}}
|
{{bodyClass "activate-account-page"}}
|
||||||
{{hideApplicationHeaderButtons "search" "login" "signup"}}
|
{{hideApplicationHeaderButtons "search" "login" "signup"}}
|
||||||
<div id="simple-container">
|
{{hideApplicationSidebar}}
|
||||||
{{#if this.errorMessage}}
|
{{#if this.errorMessage}}
|
||||||
<div class="alert alert-error">
|
<div class="alert alert-error">
|
||||||
{{this.errorMessage}}
|
{{this.errorMessage}}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="activate-account">
|
<div class="activate-account">
|
||||||
<h1 class="activate-title">{{i18n
|
<SignupProgressBar @step={{this.signupStep}} />
|
||||||
"user.activate_account.welcome_to"
|
<WelcomeHeader
|
||||||
site_name=this.siteSettings.title
|
@header={{i18n
|
||||||
}}
|
"user.activate_account.welcome_to"
|
||||||
<img src={{(wavingHandURL)}} alt="" class="waving-hand" />
|
site_name=this.siteSettings.title
|
||||||
</h1>
|
}}
|
||||||
<br />
|
/>
|
||||||
{{#if this.accountActivated}}
|
<br />
|
||||||
<div class="perform-activation">
|
{{#if this.accountActivated}}
|
||||||
<div class="image">
|
<div class="account-activated">
|
||||||
<img
|
<div class="tada-image">
|
||||||
src="/images/wizard/tada.svg"
|
<img src="/images/wizard/tada.svg" alt="tada emoji" />
|
||||||
class="waving-hand"
|
|
||||||
alt="tada emoji"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{{#if this.needsApproval}}
|
|
||||||
<p>{{i18n "user.activate_account.approval_required"}}</p>
|
|
||||||
{{else}}
|
|
||||||
<p>{{i18n "user.activate_account.please_continue"}}</p>
|
|
||||||
<p>
|
|
||||||
<DButton
|
|
||||||
class="continue-button"
|
|
||||||
@translatedLabel={{i18n
|
|
||||||
"user.activate_account.continue_button"
|
|
||||||
site_name=this.siteSettings.title
|
|
||||||
}}
|
|
||||||
@action={{this.loadHomepage}}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{#if this.needsApproval}}
|
||||||
<DButton
|
<p>{{i18n "user.activate_account.approval_required"}}</p>
|
||||||
id="activate-account-button"
|
{{else}}
|
||||||
class="btn-primary"
|
<p>{{i18n "user.activate_account.please_continue"}}</p>
|
||||||
@action={{this.activate}}
|
<DButton
|
||||||
@label="user.activate_account.action"
|
class="continue-button"
|
||||||
@disabled={{this.isLoading}}
|
@translatedLabel={{i18n
|
||||||
/>
|
"user.activate_account.continue_button"
|
||||||
{{/if}}
|
site_name=this.siteSettings.title
|
||||||
</div>
|
}}
|
||||||
{{/if}}
|
@action={{this.loadHomepage}}
|
||||||
</div>
|
/>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<DButton
|
||||||
|
class="activate-account-button btn-primary"
|
||||||
|
@action={{this.activate}}
|
||||||
|
@label="user.activate_account.action"
|
||||||
|
@disabled={{this.isLoading}}
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</template>
|
</template>
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,240 +1,241 @@
|
||||||
{{body-class "invite-page"}}
|
{{body-class "invite-page"}}
|
||||||
|
{{hide-application-header-buttons "search" "login" "signup"}}
|
||||||
{{hide-application-sidebar}}
|
{{hide-application-sidebar}}
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div class="container invites-show clearfix">
|
<div class="container invites-show clearfix">
|
||||||
<div class="login-welcome-header">
|
{{#unless this.externalAuthsOnly}}
|
||||||
<h1 class="login-title">{{this.welcomeTitle}}</h1>
|
<SignupProgressBar @step={{if this.successMessage "activate" "signup"}} />
|
||||||
<img src={{this.wavingHandURL}} alt="" class="waving-hand" />
|
{{/unless}}
|
||||||
{{#unless this.successMessage}}
|
<WelcomeHeader
|
||||||
<p class="login-subheader">{{this.subheaderMessage}}</p>
|
@header={{this.welcomeTitle}}
|
||||||
{{/unless}}
|
@subheader={{unless this.successMessage this.subheaderMessage}}
|
||||||
</div>
|
/>
|
||||||
|
|
||||||
<div class={{if this.successMessage "invite-success" "invite-form"}}>
|
<div class={{if this.successMessage "invite-success" "invite-form"}}>
|
||||||
<div class="two-col">
|
<div class="col-form">
|
||||||
<div class="col-image">
|
{{#if this.successMessage}}
|
||||||
<img src={{this.inviteImageUrl}} alt="" />
|
<div class="success-info">
|
||||||
</div>
|
<p>{{html-safe this.successMessage}}</p>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<p>{{i18n "invites.invited_by"}}</p>
|
||||||
|
<p><UserInfo @user={{this.invitedBy}} /></p>
|
||||||
|
|
||||||
<div class="col-form">
|
{{#if this.associateHtml}}
|
||||||
{{#if this.successMessage}}
|
<p class="create-account-associate-link">
|
||||||
<div class="success-info">
|
{{html-safe this.associateHtml}}
|
||||||
<p>{{html-safe this.successMessage}}</p>
|
</p>
|
||||||
</div>
|
{{/if}}
|
||||||
{{else}}
|
|
||||||
<p>{{i18n "invites.invited_by"}}</p>
|
|
||||||
<p><UserInfo @user={{this.invitedBy}} /></p>
|
|
||||||
|
|
||||||
{{#if this.associateHtml}}
|
{{#unless this.isInviteLink}}
|
||||||
<p class="create-account-associate-link">
|
<p class="email-message">
|
||||||
{{html-safe this.associateHtml}}
|
{{html-safe this.yourEmailMessage}}
|
||||||
</p>
|
{{#if this.showSocialLoginAvailable}}
|
||||||
|
{{i18n "invites.social_login_available"}}
|
||||||
|
{{/if}}
|
||||||
|
</p>
|
||||||
|
{{/unless}}
|
||||||
|
|
||||||
|
{{#if this.externalAuthsOnly}}
|
||||||
|
{{! authOptions are present once the user has followed the OmniAuth flow (e.g. twitter/google/etc) }}
|
||||||
|
{{#if this.authOptions}}
|
||||||
|
{{#unless this.isInviteLink}}
|
||||||
|
<InputTip
|
||||||
|
@validation={{this.emailValidation}}
|
||||||
|
id="account-email-validation"
|
||||||
|
/>
|
||||||
|
{{/unless}}
|
||||||
|
{{else}}
|
||||||
|
<LoginButtons
|
||||||
|
@externalLogin={{action "externalLogin"}}
|
||||||
|
@context="invite"
|
||||||
|
/>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#unless this.isInviteLink}}
|
{{#if this.discourseConnectEnabled}}
|
||||||
<p class="email-message">
|
<a
|
||||||
{{html-safe this.yourEmailMessage}}
|
class="btn btn-primary discourse-connect raw-link"
|
||||||
{{#if this.showSocialLoginAvailable}}
|
href={{this.ssoPath}}
|
||||||
{{i18n "invites.social_login_available"}}
|
>
|
||||||
{{/if}}
|
{{i18n "continue"}}
|
||||||
</p>
|
</a>
|
||||||
{{/unless}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if this.externalAuthsOnly}}
|
{{#if this.shouldDisplayForm}}
|
||||||
{{! authOptions are present once the user has followed the OmniAuth flow (e.g. twitter/google/etc) }}
|
<form>
|
||||||
{{#if this.authOptions}}
|
{{#if this.isInviteLink}}
|
||||||
{{#unless this.isInviteLink}}
|
<div class="input email-input input-group">
|
||||||
|
<Input
|
||||||
|
@type="email"
|
||||||
|
@value={{this.email}}
|
||||||
|
id="new-account-email"
|
||||||
|
name="email"
|
||||||
|
class={{value-entered this.email}}
|
||||||
|
autofocus="autofocus"
|
||||||
|
disabled={{this.externalAuthsOnly}}
|
||||||
|
/>
|
||||||
|
<label class="alt-placeholder" for="new-account-email">
|
||||||
|
{{i18n "user.email.title"}}
|
||||||
|
</label>
|
||||||
<InputTip
|
<InputTip
|
||||||
@validation={{this.emailValidation}}
|
@validation={{this.emailValidation}}
|
||||||
id="account-email-validation"
|
id="account-email-validation"
|
||||||
/>
|
/>
|
||||||
{{/unless}}
|
{{#unless this.emailValidation.reason}}
|
||||||
{{else}}
|
|
||||||
<LoginButtons
|
|
||||||
@externalLogin={{action "externalLogin"}}
|
|
||||||
@context="invite"
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if this.discourseConnectEnabled}}
|
|
||||||
<a
|
|
||||||
class="btn btn-primary discourse-connect raw-link"
|
|
||||||
href={{this.ssoPath}}
|
|
||||||
>
|
|
||||||
{{i18n "continue"}}
|
|
||||||
</a>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if this.shouldDisplayForm}}
|
|
||||||
<form>
|
|
||||||
{{#if this.isInviteLink}}
|
|
||||||
<div class="input email-input input-group">
|
|
||||||
<Input
|
|
||||||
@type="email"
|
|
||||||
@value={{this.email}}
|
|
||||||
id="new-account-email"
|
|
||||||
name="email"
|
|
||||||
class={{value-entered this.email}}
|
|
||||||
autofocus="autofocus"
|
|
||||||
disabled={{this.externalAuthsOnly}}
|
|
||||||
/>
|
|
||||||
<label class="alt-placeholder" for="new-account-email">
|
|
||||||
{{i18n "user.email.title"}}
|
|
||||||
<span class="required">*</span>
|
|
||||||
</label>
|
|
||||||
<InputTip
|
|
||||||
@validation={{this.emailValidation}}
|
|
||||||
id="account-email-validation"
|
|
||||||
/>
|
|
||||||
<div class="instructions">{{i18n
|
<div class="instructions">{{i18n
|
||||||
"user.email.instructions"
|
"user.email.instructions"
|
||||||
}}</div>
|
}}</div>
|
||||||
</div>
|
{{/unless}}
|
||||||
{{/if}}
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<div class="input username-input input-group">
|
<div class="input username-input input-group">
|
||||||
<Input
|
<Input
|
||||||
@value={{this.accountUsername}}
|
@value={{this.accountUsername}}
|
||||||
class={{value-entered this.accountUsername}}
|
class={{value-entered this.accountUsername}}
|
||||||
id="new-account-username"
|
id="new-account-username"
|
||||||
name="username"
|
name="username"
|
||||||
maxlength={{this.maxUsernameLength}}
|
maxlength={{this.maxUsernameLength}}
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
/>
|
/>
|
||||||
<label class="alt-placeholder" for="new-account-username">
|
<label class="alt-placeholder" for="new-account-username">
|
||||||
{{i18n "user.username.title"}}
|
{{i18n "user.username.title"}}
|
||||||
<span class="required">*</span>
|
</label>
|
||||||
</label>
|
<InputTip
|
||||||
<InputTip
|
@validation={{this.usernameValidation}}
|
||||||
@validation={{this.usernameValidation}}
|
id="username-validation"
|
||||||
id="username-validation"
|
/>
|
||||||
/>
|
{{#unless this.usernameValidation.reason}}
|
||||||
<div class="instructions">{{i18n
|
<div class="instructions">{{i18n
|
||||||
"user.username.instructions"
|
"user.username.instructions"
|
||||||
}}</div>
|
}}</div>
|
||||||
</div>
|
{{/unless}}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{#if this.fullnameRequired}}
|
{{#unless this.externalAuthsOnly}}
|
||||||
<div class="input name-input input-group">
|
<div class="input password-input input-group">
|
||||||
<Input
|
<PasswordField
|
||||||
@value={{this.accountName}}
|
@value={{this.accountPassword}}
|
||||||
class={{value-entered this.accountName}}
|
@capsLockOn={{this.capsLockOn}}
|
||||||
id="new-account-name"
|
type={{if this.maskPassword "password" "text"}}
|
||||||
name="name"
|
autocomplete="new-password"
|
||||||
/>
|
id="new-account-password"
|
||||||
<label class="alt-placeholder" for="new-account-name">
|
class={{value-entered this.accountPassword}}
|
||||||
{{i18n "invites.name_label"}}
|
/>
|
||||||
{{#if this.siteSettings.full_name_required}}
|
<label class="alt-placeholder" for="new-account-password">
|
||||||
<span class="required">*</span>
|
{{i18n "invites.password_label"}}
|
||||||
{{/if}}
|
</label>
|
||||||
</label>
|
<div class="create-account__password-info">
|
||||||
<div class="instructions">{{this.nameInstructions}}</div>
|
<div class="create-account__password-tip-validation">
|
||||||
</div>
|
<InputTip
|
||||||
{{/if}}
|
@validation={{this.passwordValidation}}
|
||||||
|
id="password-validation"
|
||||||
{{#unless this.externalAuthsOnly}}
|
/>
|
||||||
<div class="input password-input input-group">
|
{{#unless this.passwordValidation.reason}}
|
||||||
<PasswordField
|
|
||||||
@value={{this.accountPassword}}
|
|
||||||
@capsLockOn={{this.capsLockOn}}
|
|
||||||
type={{if this.maskPassword "password" "text"}}
|
|
||||||
autocomplete="new-password"
|
|
||||||
id="new-account-password"
|
|
||||||
class={{value-entered this.accountPassword}}
|
|
||||||
/>
|
|
||||||
<label class="alt-placeholder" for="new-account-password">
|
|
||||||
{{i18n "invites.password_label"}}
|
|
||||||
<span class="required">*</span>
|
|
||||||
</label>
|
|
||||||
<div class="create-account__password-info">
|
|
||||||
<div class="create-account__password-tip-validation">
|
|
||||||
<InputTip
|
|
||||||
@validation={{this.passwordValidation}}
|
|
||||||
id="password-validation"
|
|
||||||
/>
|
|
||||||
<span
|
<span
|
||||||
class="more-info"
|
class="more-info"
|
||||||
>{{this.passwordInstructions}}</span>
|
>{{this.passwordInstructions}}</span>
|
||||||
<div
|
{{/unless}}
|
||||||
class="caps-lock-warning
|
<div
|
||||||
{{unless this.capsLockOn 'hidden'}}"
|
class="caps-lock-warning
|
||||||
>
|
{{unless this.capsLockOn 'hidden'}}"
|
||||||
{{d-icon "exclamation-triangle"}}
|
>
|
||||||
{{i18n "login.caps_lock_warning"}}
|
{{d-icon "exclamation-triangle"}}
|
||||||
</div>
|
{{i18n "login.caps_lock_warning"}}
|
||||||
</div>
|
</div>
|
||||||
<TogglePasswordMask
|
|
||||||
@maskPassword={{this.maskPassword}}
|
|
||||||
@togglePasswordMask={{this.togglePasswordMask}}
|
|
||||||
@parentController="invites-show"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<TogglePasswordMask
|
||||||
{{/unless}}
|
@maskPassword={{this.maskPassword}}
|
||||||
|
@togglePasswordMask={{this.togglePasswordMask}}
|
||||||
{{#if this.userFields}}
|
@parentController="invites-show"
|
||||||
<div class="user-fields">
|
|
||||||
{{#each this.userFields as |f|}}
|
|
||||||
<div class="input-group">
|
|
||||||
<UserField
|
|
||||||
@field={{f.field}}
|
|
||||||
@value={{f.value}}
|
|
||||||
class={{value-entered f.value}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<div class="invitation-cta">
|
|
||||||
<DButton
|
|
||||||
@action={{action "submit"}}
|
|
||||||
@disabled={{this.submitDisabled}}
|
|
||||||
@label="invites.accept_invite"
|
|
||||||
type="submit"
|
|
||||||
class="btn-primary invitation-cta__accept"
|
|
||||||
/>
|
|
||||||
<div class="invitation-cta__info">
|
|
||||||
<span class="invitation-cta__signed-up">{{i18n
|
|
||||||
"login.previous_sign_up"
|
|
||||||
}}</span>
|
|
||||||
<DButton
|
|
||||||
@action={{route-action "showLogin"}}
|
|
||||||
@label="log_in"
|
|
||||||
class="btn-flat invitation-cta__sign-in"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{/unless}}
|
||||||
|
|
||||||
<div class="disclaimer">
|
{{#if this.fullnameRequired}}
|
||||||
{{html-safe this.disclaimerHtml}}
|
<div
|
||||||
|
class={{concat-class
|
||||||
|
"input"
|
||||||
|
"name-input"
|
||||||
|
"input-group"
|
||||||
|
(if this.siteSettings.full_name_required "name-required")
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
@value={{this.accountName}}
|
||||||
|
class={{value-entered this.accountName}}
|
||||||
|
id="new-account-name"
|
||||||
|
name="name"
|
||||||
|
/>
|
||||||
|
<label class="alt-placeholder" for="new-account-name">
|
||||||
|
{{i18n "invites.name_label"}}
|
||||||
|
</label>
|
||||||
|
<div class="instructions">{{this.nameInstructions}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#if this.errorMessage}}
|
{{#if this.userFields}}
|
||||||
<br /><br />
|
<div class="user-fields">
|
||||||
<div class="alert alert-error">{{this.errorMessage}}</div>
|
{{#each this.userFields as |f|}}
|
||||||
{{/if}}
|
<div class="input-group">
|
||||||
</form>
|
<UserField
|
||||||
{{/if}}
|
@field={{f.field}}
|
||||||
{{#if this.existingUserRedeeming}}
|
@value={{f.value}}
|
||||||
{{#if this.existingUserCanRedeem}}
|
class={{value-entered f.value}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="invitation-cta">
|
||||||
<DButton
|
<DButton
|
||||||
@action={{action "submit"}}
|
@action={{action "submit"}}
|
||||||
@disabled={{this.submitDisabled}}
|
@disabled={{this.submitDisabled}}
|
||||||
@label="invites.accept_invite"
|
@label="invites.accept_invite"
|
||||||
type="submit"
|
type="submit"
|
||||||
class="btn-primary"
|
class="btn-primary invitation-cta__accept"
|
||||||
/>
|
/>
|
||||||
{{else}}
|
<div class="invitation-cta__info">
|
||||||
<div
|
<span class="invitation-cta__signed-up">{{i18n
|
||||||
class="alert alert-error"
|
"login.previous_sign_up"
|
||||||
>{{this.existingUserCanRedeemError}}</div>
|
}}</span>
|
||||||
|
<DButton
|
||||||
|
@action={{route-action "showLogin"}}
|
||||||
|
@label="log_in"
|
||||||
|
class="btn-flat invitation-cta__sign-in"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="disclaimer">
|
||||||
|
{{html-safe this.disclaimerHtml}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if this.errorMessage}}
|
||||||
|
<br /><br />
|
||||||
|
<div class="alert alert-error">{{this.errorMessage}}</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
</form>
|
||||||
|
{{/if}}
|
||||||
|
{{#if this.existingUserRedeeming}}
|
||||||
|
{{#if this.existingUserCanRedeem}}
|
||||||
|
<DButton
|
||||||
|
@action={{action "submit"}}
|
||||||
|
@disabled={{this.submitDisabled}}
|
||||||
|
@label="invites.accept_invite"
|
||||||
|
type="submit"
|
||||||
|
class="btn-primary"
|
||||||
|
/>
|
||||||
|
{{else}}
|
||||||
|
<div
|
||||||
|
class="alert alert-error"
|
||||||
|
>{{this.existingUserCanRedeemError}}</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -80,6 +80,7 @@ acceptance("Invite accept", function (needs) {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("invite link", async function (assert) {
|
test("invite link", async function (assert) {
|
||||||
|
this.siteSettings.login_required = true;
|
||||||
PreloadStore.store("invite_info", {
|
PreloadStore.store("invite_info", {
|
||||||
invited_by: {
|
invited_by: {
|
||||||
id: 123,
|
id: 123,
|
||||||
|
@ -166,7 +167,9 @@ acceptance("Invite accept", function (needs) {
|
||||||
test("invite name is required only if full name is required", async function (assert) {
|
test("invite name is required only if full name is required", async function (assert) {
|
||||||
preloadInvite();
|
preloadInvite();
|
||||||
await visit("/invites/my-valid-invite-token");
|
await visit("/invites/my-valid-invite-token");
|
||||||
assert.dom(".name-input .required").exists("Full name is required");
|
assert
|
||||||
|
.dom(".name-input .required")
|
||||||
|
.doesNotExist("Full name is implicitly required");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,73 +1,70 @@
|
||||||
// Styles used before the user is logged into discourse. For example, activating their
|
// Styles used before the user is logged into discourse. For example, activating their
|
||||||
// account or changing their email.
|
// account or changing their email.
|
||||||
|
|
||||||
.account-activation-page {
|
.account-created-page,
|
||||||
.desktop-view & {
|
.activate-account-page {
|
||||||
background: var(--primary-very-low);
|
background: var(--secondary);
|
||||||
}
|
|
||||||
#main-outlet-wrapper {
|
|
||||||
display: block;
|
|
||||||
.sidebar-wrapper {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.header-sidebar-toggle {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#main-outlet {
|
#main-outlet {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
#simple-container {
|
}
|
||||||
|
|
||||||
|
.activate-account-page .alert-error {
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-created,
|
||||||
|
.activate-account {
|
||||||
|
max-width: 500px;
|
||||||
|
padding: 2rem 3rem;
|
||||||
|
background: var(--secondary);
|
||||||
|
box-shadow: var(--shadow-menu-panel);
|
||||||
|
margin: 10vh auto 1em auto;
|
||||||
|
@media screen and (max-height: 700px) {
|
||||||
|
margin: 1em auto 1em auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-created {
|
||||||
|
.ac-message {
|
||||||
|
font-size: var(--font-up-1);
|
||||||
|
line-height: var(--line-height-large);
|
||||||
|
}
|
||||||
|
.activation-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-wrap: wrap;
|
||||||
box-sizing: border-box;
|
gap: 0.5em;
|
||||||
border-radius: 10px;
|
margin-top: 1em;
|
||||||
width: 100%;
|
}
|
||||||
padding: 20px;
|
|
||||||
justify-content: center;
|
.edit-cancel {
|
||||||
margin-top: var(--header-offset);
|
text-transform: capitalize;
|
||||||
.account-created {
|
}
|
||||||
.ac-message {
|
|
||||||
font-size: var(--font-up-1);
|
.success-info p:last-child {
|
||||||
line-height: var(--line-height-large);
|
margin-bottom: 0;
|
||||||
}
|
|
||||||
.activation-controls {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 0.5em;
|
|
||||||
}
|
|
||||||
.ac-page {
|
|
||||||
border-radius: 10px;
|
|
||||||
margin-top: 25px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.activate-account {
|
.activate-account {
|
||||||
.activate-title {
|
.activate-account-button,
|
||||||
text-align: center;
|
.continue-button {
|
||||||
.waving-hand {
|
margin-top: 1em;
|
||||||
height: 32px;
|
margin-inline: auto;
|
||||||
margin-bottom: 13px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#activate-account-button {
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
display: block;
|
display: block;
|
||||||
|
width: fit-content;
|
||||||
}
|
}
|
||||||
.perform-activation {
|
|
||||||
border-top: 6px solid var(--tertiary);
|
.login-welcome-header {
|
||||||
box-shadow: 0 1px 10px 1px rgba(var(--primary-low-rgb), 1.25);
|
margin-inline: auto;
|
||||||
border-radius: 10px;
|
width: fit-content;
|
||||||
padding: 1em 2.5em 1em 2.5em;
|
}
|
||||||
.image {
|
|
||||||
width: 150px;
|
.tada-image {
|
||||||
margin: auto;
|
width: 150px;
|
||||||
padding-bottom: 1em;
|
margin: auto;
|
||||||
}
|
padding-bottom: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,16 +97,6 @@ body.invite-page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.invite-error {
|
|
||||||
box-shadow: 0 1px 10px 1px rgba(var(--primary-low-rgb), 1.25);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 1em 2.5em 1em 2.5em;
|
|
||||||
.error-image {
|
|
||||||
text-align: center;
|
|
||||||
padding-bottom: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.email-login {
|
.email-login {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background-color: var(--secondary);
|
background-color: var(--secondary);
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
@import "sidebar/edit-navigation-menu/categories-modal";
|
@import "sidebar/edit-navigation-menu/categories-modal";
|
||||||
@import "sidebar/edit-navigation-menu/modal";
|
@import "sidebar/edit-navigation-menu/modal";
|
||||||
@import "sidebar/edit-navigation-menu/tags-modal";
|
@import "sidebar/edit-navigation-menu/tags-modal";
|
||||||
|
@import "signup-progress-bar";
|
||||||
@import "svg";
|
@import "svg";
|
||||||
@import "tap-tile";
|
@import "tap-tile";
|
||||||
@import "time-input";
|
@import "time-input";
|
||||||
|
@ -51,3 +52,4 @@
|
||||||
@import "user-stream";
|
@import "user-stream";
|
||||||
@import "widget-dropdown";
|
@import "widget-dropdown";
|
||||||
@import "dropdown-menu";
|
@import "dropdown-menu";
|
||||||
|
@import "welcome-header";
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
.has-full-page-chat &,
|
.has-full-page-chat &,
|
||||||
.static-login &,
|
.static-login &,
|
||||||
.invite-page &,
|
.invite-page &,
|
||||||
.account-activation-page & {
|
.account-created-page &,
|
||||||
|
.activate-account-page & {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
grid-area: below-content;
|
grid-area: below-content;
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
$progress-bar-line-width: 2px;
|
||||||
|
$progress-bar-circle-size: 1.2rem;
|
||||||
|
$progress-bar-icon-size: 0.8rem;
|
||||||
|
|
||||||
|
.signup-progress-bar {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
color: var(--primary-low-mid);
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 1.2em;
|
||||||
|
|
||||||
|
&__segment {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
&:first-child .signup-progress-bar__circle {
|
||||||
|
transform: translateX(50%);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
width: $progress-bar-circle-size;
|
||||||
|
.signup-progress-bar__circle {
|
||||||
|
transform: translateX(-50%);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__step-text {
|
||||||
|
white-space: nowrap;
|
||||||
|
width: fit-content;
|
||||||
|
transform: translateX(calc(calc($progress-bar-circle-size / 2) - 50%));
|
||||||
|
|
||||||
|
.signup-progress-bar__segment:first-child & {
|
||||||
|
transform: translateX(0%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.signup-progress-bar__segment:last-child & {
|
||||||
|
transform: translateX(
|
||||||
|
calc(calc($progress-bar-circle-size + $progress-bar-line-width) - 100%)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__step {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__line {
|
||||||
|
transform: translateY(
|
||||||
|
calc(calc($progress-bar-circle-size + $progress-bar-line-width) / 2)
|
||||||
|
);
|
||||||
|
height: $progress-bar-line-width;
|
||||||
|
width: 100%;
|
||||||
|
background-color: var(--primary-low-mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__circle {
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: $progress-bar-icon-size;
|
||||||
|
color: var(--secondary);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: $progress-bar-circle-size;
|
||||||
|
width: $progress-bar-circle-size;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: $progress-bar-line-width solid var(--primary-low-mid);
|
||||||
|
background-color: var(--secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__step.--completed {
|
||||||
|
color: var(--primary);
|
||||||
|
|
||||||
|
.signup-progress-bar__circle {
|
||||||
|
background-color: var(--success);
|
||||||
|
border: $progress-bar-line-width solid var(--success);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__line.--completed {
|
||||||
|
background-color: var(--success);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__step.--active {
|
||||||
|
.signup-progress-bar__circle {
|
||||||
|
border: $progress-bar-line-width solid var(--success);
|
||||||
|
}
|
||||||
|
+ .signup-progress-bar__step-text {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
app/assets/stylesheets/common/components/welcome-header.scss
Normal file
24
app/assets/stylesheets/common/components/welcome-header.scss
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
.login-welcome-header {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
grid-template-rows: auto 1fr;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
|
||||||
|
.login-title {
|
||||||
|
font-size: var(--font-up-6);
|
||||||
|
margin: 0;
|
||||||
|
line-height: var(--line-height-medium);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-subheader {
|
||||||
|
font-size: var(--font-up-1);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.waving-hand {
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,28 +2,8 @@
|
||||||
padding: 2rem 3rem;
|
padding: 2rem 3rem;
|
||||||
background: var(--secondary);
|
background: var(--secondary);
|
||||||
|
|
||||||
.login-welcome-header {
|
.success-info p:last-child {
|
||||||
display: grid;
|
margin-bottom: 0;
|
||||||
grid-template-columns: auto 1fr;
|
|
||||||
grid-template-rows: auto 1fr;
|
|
||||||
overflow-wrap: anywhere;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-title {
|
|
||||||
font-size: var(--font-up-6);
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.waving-hand {
|
|
||||||
width: 35px;
|
|
||||||
height: 35px;
|
|
||||||
margin-left: 0.5em;
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-subheader {
|
|
||||||
font-size: var(--font-up-1);
|
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-info {
|
.user-info {
|
||||||
|
@ -36,10 +16,6 @@
|
||||||
height: 30px;
|
height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-image {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.create-account__password {
|
.create-account__password {
|
||||||
&-info {
|
&-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -65,4 +41,17 @@
|
||||||
color: var(--primary-medium);
|
color: var(--primary-medium);
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.invite-form form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
&.email-input,
|
||||||
|
&.username-input,
|
||||||
|
&.name-input.name-required {
|
||||||
|
order: -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,11 +36,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-subheader {
|
|
||||||
font-size: var(--font-up-1);
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-left-side {
|
.login-left-side {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -48,25 +43,6 @@
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-welcome-header {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: auto 1fr;
|
|
||||||
grid-template-rows: auto 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-title {
|
|
||||||
font-size: var(--font-up-6);
|
|
||||||
margin: 0;
|
|
||||||
line-height: var(--line-height-medium);
|
|
||||||
}
|
|
||||||
|
|
||||||
.waving-hand {
|
|
||||||
width: 35px;
|
|
||||||
height: 35px;
|
|
||||||
margin-left: 0.5em;
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-right-side {
|
.login-right-side {
|
||||||
background: var(--tertiary-or-tertiary-low);
|
background: var(--tertiary-or-tertiary-low);
|
||||||
padding: 3.5rem 3rem;
|
padding: 3.5rem 3rem;
|
||||||
|
@ -151,13 +127,12 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
.login-welcome-header,
|
|
||||||
.d-modal__footer {
|
.d-modal__footer {
|
||||||
font-size: var(--font-down-1);
|
font-size: var(--font-down-1);
|
||||||
}
|
}
|
||||||
.login-left-side {
|
.login-left-side {
|
||||||
overflow: unset;
|
overflow: unset;
|
||||||
padding: 1em 2.75em 1em 1em;
|
padding: 1em;
|
||||||
}
|
}
|
||||||
.login-right-side {
|
.login-right-side {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
|
@ -166,6 +141,9 @@
|
||||||
#login-form {
|
#login-form {
|
||||||
margin: 1.5em 0;
|
margin: 1.5em 0;
|
||||||
}
|
}
|
||||||
|
.signup-progress-bar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +151,14 @@
|
||||||
/* end shared styles */
|
/* end shared styles */
|
||||||
|
|
||||||
.d-modal.create-account {
|
.d-modal.create-account {
|
||||||
|
&:not(:has(.has-alt-auth)) .d-modal__container {
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
.d-modal {
|
.d-modal {
|
||||||
|
&__container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
&__footer {
|
&__footer {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
.invite-page {
|
.invite-page {
|
||||||
background: var(--primary-50);
|
background: var(--secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.invites-show {
|
.invites-show,
|
||||||
|
#simple-container .invite-error {
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
padding: 2rem 3rem;
|
padding: 2rem 3rem;
|
||||||
background: var(--secondary);
|
background: var(--secondary);
|
||||||
|
@ -12,3 +13,14 @@
|
||||||
margin: 1em auto 1em auto;
|
margin: 1em auto 1em auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#simple-container .invite-error {
|
||||||
|
.error-info {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-image {
|
||||||
|
text-align: center;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,3 +4,4 @@
|
||||||
@import "topic-map";
|
@import "topic-map";
|
||||||
@import "user-card";
|
@import "user-card";
|
||||||
@import "user-stream-item";
|
@import "user-stream-item";
|
||||||
|
@import "welcome-header";
|
||||||
|
|
14
app/assets/stylesheets/mobile/components/welcome-header.scss
Normal file
14
app/assets/stylesheets/mobile/components/welcome-header.scss
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
.login-welcome-header {
|
||||||
|
.login-title {
|
||||||
|
font-size: var(--font-up-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-subheader {
|
||||||
|
font-size: var(--font-0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.waving-hand {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -97,3 +97,21 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.d-modal.create-account {
|
||||||
|
.d-modal__footer-buttons {
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 8px;
|
||||||
|
button {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-welcome-header {
|
||||||
|
padding-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signup-progress-bar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2336,6 +2336,11 @@ en:
|
||||||
associate: "Already have an account? <a href='%{associate_link}'>Log In</a> to link your %{provider} account."
|
associate: "Already have an account? <a href='%{associate_link}'>Log In</a> to link your %{provider} account."
|
||||||
activation_title: "Activate your account"
|
activation_title: "Activate your account"
|
||||||
already_have_account: "Already have an account?"
|
already_have_account: "Already have an account?"
|
||||||
|
progress_bar:
|
||||||
|
signup: "Sign Up"
|
||||||
|
activate: "Activate"
|
||||||
|
approve: "Approve"
|
||||||
|
login: "Log In"
|
||||||
|
|
||||||
forgot_password:
|
forgot_password:
|
||||||
title: "Password Reset"
|
title: "Password Reset"
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 47.5 47.5" style="enable-background:new 0 0 47.5 47.5;" xml:space="preserve" version="1.1" id="svg2"><metadata id="metadata8"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata><defs id="defs6"><clipPath id="clipPath16" clipPathUnits="userSpaceOnUse"><path id="path18" d="M 0,38 38,38 38,0 0,0 0,38 Z"/></clipPath></defs><g transform="matrix(1.25,0,0,-1.25,0,47.5)" id="g10"><g id="g12"><g clip-path="url(#clipPath16)" id="g14"><g transform="translate(37,10)" id="g20"><path id="path22" style="fill:#ccd6dd;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 0,0 c 0,-2.209 -1.791,-4 -4,-4 l -28,0 c -2.209,0 -4,1.791 -4,4 l 0,18 c 0,2.209 1.791,4 4,4 l 28,0 c 2.209,0 4,-1.791 4,-4 L 0,0 Z"/></g><g transform="translate(12.9497,19.3643)" id="g24"><path id="path26" style="fill:#99aab5;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 0,0 -11.313,-11.313 c -0.027,-0.028 -0.037,-0.063 -0.06,-0.091 0.34,-0.571 0.814,-1.043 1.384,-1.384 0.029,0.023 0.063,0.033 0.09,0.059 L 1.415,-1.414 c 0.39,0.391 0.39,1.022 0,1.414 C 1.023,0.391 0.391,0.391 0,0"/></g><g transform="translate(36.4229,7.96)" id="g28"><path id="path30" style="fill:#99aab5;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 0,0 c -0.021,0.028 -0.033,0.063 -0.06,0.09 l -11.312,11.314 c -0.392,0.391 -1.024,0.391 -1.415,0 -0.391,-0.391 -0.391,-1.023 0,-1.414 L -1.474,-1.324 c 0.027,-0.027 0.062,-0.037 0.09,-0.06 C -0.812,-1.044 -0.34,-0.57 0,0"/></g><g transform="translate(33,32)" id="g32"><path id="path34" style="fill:#99aab5;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 0,0 -28,0 c -2.209,0 -4,-1.791 -4,-4 l 0,-1.03 14.528,-14.495 c 1.894,-1.894 4.988,-1.894 6.884,0 L 4,-5.009 4,-4 C 4,-1.791 2.209,0 0,0"/></g><g transform="translate(33,32)" id="g36"><path id="path38" style="fill:#e1e8ed;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 0,0 -28,0 c -1.588,0 -2.949,-0.934 -3.595,-2.275 l 14.766,-14.767 c 1.562,-1.562 4.096,-1.562 5.657,0 L 3.595,-2.275 C 2.949,-0.934 1.589,0 0,0"/></g></g></g></g></svg>
|
|
Before Width: | Height: | Size: 2.3 KiB |
|
@ -4,15 +4,15 @@ module PageObjects
|
||||||
module Pages
|
module Pages
|
||||||
class ActivateAccount < PageObjects::Pages::Base
|
class ActivateAccount < PageObjects::Pages::Base
|
||||||
def click_activate_account
|
def click_activate_account
|
||||||
find("#activate-account-button").click
|
find(".activate-account-button").click
|
||||||
end
|
end
|
||||||
|
|
||||||
def click_continue
|
def click_continue
|
||||||
find(".perform-activation .continue-button").click
|
find(".account-activated .continue-button").click
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_error?
|
def has_error?
|
||||||
has_css?("#simple-container .alert-error")
|
has_css?(".alert-error")
|
||||||
has_content?(I18n.t("js.user.activate_account.already_done"))
|
has_content?(I18n.t("js.user.activate_account.already_done"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,7 +30,7 @@ describe "Account activation", type: :system do
|
||||||
|
|
||||||
expect(user.reload.active).to eq(false)
|
expect(user.reload.active).to eq(false)
|
||||||
|
|
||||||
find("#activate-account-button").click
|
find(".activate-account-button").click
|
||||||
|
|
||||||
wait_for(timeout: 5) { user.reload.active }
|
wait_for(timeout: 5) { user.reload.active }
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user