Refactor login screen

This commit is contained in:
Simon Prévost 2023-03-06 09:02:15 -05:00
parent 999521bcec
commit ab3fd89ae9
19 changed files with 274 additions and 240 deletions

View File

@ -15,7 +15,7 @@ defmodule AccentTest.Lint do
end
test "lint placeholder simple" do
entry = %Entry{key: "a", value: "nothing", master_value: "{{bar}}", value_type: "string"}
entry = %Entry{key: "a", value: "nothing", is_master: false, master_value: "{{bar}}", value_type: "string"}
[{_, messages}] = Lint.lint([entry])
assert messages === [%Accent.Lint.Message{check: :placeholder_count, replacement: nil, text: "nothing"}]

View File

@ -42,12 +42,12 @@
"title": "Notify on new messages"
},
"login_header": {
"text": "Login with any service below,",
"subtext": "Your email address will be used to identify you uniquely through all services."
},
"login_footer": {
"text": "Nothing to hide, check the source code:",
"link": "mirego/accent"
"text": "Login",
"subtext": "Only your email address, fullname and profile picture will be used for your Accent profile.",
"subtitle": "Your reliable, <em>simple</em>, developer-oriented translation tool",
"footer_open_source_link": "100% open-source",
"footer_mirego_link": "Mirego",
"footer": ", made with ♥ by"
},
"login_forms": {
"auth0": "Login with Auth0 →",

View File

@ -44,12 +44,12 @@
"title": "Notifier les nouveaux messages"
},
"login_header": {
"text": "Connectez-vous avec nimporte quel service ci-dessous,",
"subtext": "Votre adresse e-mail sera utilisée pour vous identifier de manière unique à travers tous les services."
},
"login_footer": {
"text": "Rien à cacher, vérifiez le code source :",
"link": "mirego/accent"
"text": "Se connecter",
"subtext": "Seules votre adresse e-mail, votre nom complet et votre photo de profil seront utilisés pour votre profil Accent.",
"subtitle": "Votre outil de traduction fiable, <em>simple</em> et axé sur le développeur",
"footer_open_source_link": "100% open-source",
"footer_mirego_link": "Mirego",
"footer": ", fait avec ♥ par"
},
"login_forms": {
"github": "Connectez-vous avec GitHub →",

View File

@ -8,9 +8,6 @@ export default class ApplicationFooter extends Component {
@service('intl')
intl: IntlService;
// The version is replaced at runtime when served by the API.
// If the webapp is not served by the API (like in development),
// the version tag will show up as 'dev'.
get version() {
return config.version === '__VERSION__' ? 'dev' : config.version;
}

View File

@ -56,11 +56,14 @@
}
}
.item {
padding: 8px 10px;
}
.language {
display: flex;
align-items: flex-end;
justify-content: space-between;
padding: 8px 10px;
color: var(--color-grey);
}
@ -125,8 +128,7 @@
}
.actions {
margin: 0;
padding: 8px;
margin: 10px 0 0;
display: flex;
flex-direction: column;
gap: 4px;

View File

@ -4,7 +4,7 @@
"high-percentage"
}}'
>
<div local-class='slaveRevisions-item'>
<div local-class='item'>
<span role='button' local-class='actionsButton' {{on 'click' (fn this.toggleShowActions)}}>
{{inline-svg 'assets/gear.svg' local-class='actionsButton-icon'}}
</span>

View File

@ -1,3 +0,0 @@
import Component from '@glimmer/component';
export default class LoginFooter extends Component {}

View File

@ -1,27 +0,0 @@
.login-footer {
max-width: 500px;
margin: 30px auto 60px;
border-top: 1px solid var(--background-light-highlight);
padding: 14px 10px 0;
}
.text {
font-size: 12px;
color: var(--color-grey);
}
.link {
color: var(--color-green);
text-decoration: none;
&:focus,
&:hover {
text-decoration: underline;
}
}
@media (max-width: 440px) {
.login-footer {
margin-top: 30px;
}
}

View File

@ -1,9 +0,0 @@
<div local-class='login-footer'>
<p local-class='text'>
{{t 'components.login_footer.text'}}
<a local-class='link' href='https://github.com/mirego/accent' target='_blank' rel='noopener noreferrer'>
{{t 'components.login_footer.link'}}
</a>
</p>
</div>

View File

@ -22,12 +22,15 @@ export default class LoginForms extends Component<Args> {
microsoftUrl = `${config.API.AUTHENTICATION_PATH}/microsoft`;
auth0Url = `${config.API.AUTHENTICATION_PATH}/auth0`;
get version() {
return config.version === '__VERSION__' ? 'dev' : config.version;
}
get providerIds() {
return this.args.providers.map(({id}: {id: string}) => id);
}
get authZeroLoginEnabled() {
console.log(this.providerIds);
return this.providerIds.includes('auth0');
}

View File

@ -1,7 +1,87 @@
.login-forms {
display: flex;
flex-direction: column;
align-items: center;
max-width: 500px;
margin: 0 auto 30px;
margin: 0 0 0 50px;
padding: 30px 30px 20px 30px;
border-radius: 6px;
background: var(--body-background);
box-shadow: 0 1px 4px var(--shadow-color), 0 7px 12px var(--shadow-color);
.text {
max-width: 300px;
margin-bottom: 20px;
font-size: 12px;
text-align: center;
color: var(--text-color-normal);
strong {
display: block;
font-size: 25px;
font-weight: 900;
margin-bottom: 10px;
}
p {
opacity: 0.6;
}
}
}
.loading {
padding: 0;
margin: 0;
svg {
width: 20px;
}
}
.version {
font-family: var(--font-monospace);
margin-left: 10px;
opacity: 0.4;
}
.login-header {
max-width: 570px;
margin: -60px 50px 0 auto;
padding: 0 10px;
.title {
font-weight: 900;
display: flex;
gap: 10px;
align-items: center;
font-size: 20px;
margin-bottom: 20px;
letter-spacing: 0;
}
.subtitle {
line-height: 1.1;
font-size: 55px;
font-weight: 900;
letter-spacing: -1px;
em {
font-style: normal;
position: relative;
}
}
.footer {
opacity: 0.5;
font-size: 12px;
margin-top: 20px;
a {
color: inherit;
text-decoration: none;
}
}
.logo {
width: 25px;
}
}
.input {
@ -10,14 +90,39 @@
padding: 10px;
width: 100%;
font-size: 13px;
border-color: var(--color-green) !important;
border-bottom-width: 0 !important;
&:focus {
border-color: var(--color-green);
}
}
.container {
display: flex;
width: 100%;
height: 100vh;
}
.container-left {
background: linear-gradient(
0deg,
var(--background-light-highlight) 0%,
var(--background-light) 100%
);
}
.container-right {
background: var(--background-light);
}
.container-right,
.container-left {
display: flex;
justify-content: flex-start;
align-items: center;
width: 50%;
padding: 30px;
}
a.loginButton {
max-width: 300px;
position: relative;
@ -28,6 +133,7 @@ a.loginButton {
margin-bottom: 15px;
text-align: center;
background: var(--input-background);
border-radius: 5px;
border: 1px solid #888;
font-size: 13px;
@ -35,22 +141,18 @@ a.loginButton {
border-color: darken(#4d90fe, 5%);
text-shadow: none;
color: #4d90fe;
--shadow-color: #d1e2fc;
&:focus,
&:hover {
background: lighten(#4d90fe, 30%);
}
background: lighten(#4d90fe, 30%);
}
&.loginButton--dummy {
border: 1px solid var(--color-green);
background: var(--color-green);
color: #111;
border: 1px solid var(--body-background-border);
color: var(--input-color);
text-shadow: none;
border-radius: 0 0 4px 4px;
margin-top: -3px;
--shadow-color: #bafbe0;
border-radius: 4px;
margin-top: 5px;
margin-bottom: 25px;
padding-top: 7px;
padding-bottom: 7px;
&[disabled] {
pointer-events: none;
@ -58,7 +160,7 @@ a.loginButton {
.loginButton-logo {
left: 15px;
top: 14px;
top: 8px;
width: 16px;
opacity: 0.9;
}
@ -66,10 +168,7 @@ a.loginButton {
&:hover[disabled],
&:focus,
&:hover {
margin-top: -3px;
border-color: var(--color-green);
background: var(--color-green);
color: #111;
background: var(--background-light);
}
}
@ -77,77 +176,79 @@ a.loginButton {
text-shadow: none;
color: #000;
background: #fff;
&:focus,
&:hover {
background: #eee;
}
background: #eee;
}
&.loginButton--auth0 {
border-color: #eb5424;
text-shadow: none;
color: #eb5424;
--shadow-color: #fcd6ca;
&:focus,
&:hover {
background: lighten(#eb5424, 40%);
}
background: lighten(#eb5424, 43%);
}
&.loginButton--gitlab {
border-color: #fc6d26;
text-shadow: none;
color: #fc6d26;
&:focus,
&:hover {
background: lighten(#fc6d26, 40%);
}
background: lighten(#fc6d26, 40%);
}
&.loginButton--slack {
border-color: #913d91;
text-shadow: none;
color: #913d91;
&:focus,
&:hover {
background: lighten(#913d91, 79%);
}
background: lighten(#913d91, 53%);
}
&.loginButton--discord {
border-color: #7289da;
text-shadow: none;
color: #7289da;
&:focus,
&:hover {
background: lighten(#7289da, 30%);
}
background: lighten(#7289da, 30%);
}
&.loginButton--microsoft {
border-color: #03a5f0;
text-shadow: none;
color: #03a5f0;
&:focus,
&:hover {
background: lighten(#03a5f0, 48%);
}
background: lighten(#03a5f0, 48%);
}
}
.loginButton-logo {
position: absolute;
left: 10px;
top: 9px;
width: 26px;
left: 14px;
top: 12px;
width: 20px;
margin-right: 10px;
color: #fff;
font-size: 26px;
line-height: 1;
}
@media (max-width: 900px) {
.container {
flex-direction: column;
}
.container-left,
.container-right {
justify-content: center;
width: 100%;
padding: 20px;
background: transparent;
}
.login-header {
margin: 0;
padding: 0;
.subtitle {
font-size: 30px;
}
}
.login-forms {
margin: 0;
}
}

View File

@ -1,60 +1,98 @@
<div local-class='login-forms'>
{{#if @providers}}
{{#if this.dummyLoginEnabled}}
<input value={{this.username}} local-class='input' {{did-insert this.focusInput}} {{on 'keyup' (fn this.setUsername)}} />
<a href={{this.dummyUrl}} class='button button--filled' local-class='loginButton loginButton--dummy' disabled={{this.emptyUsername}}>
<img src='assets/auth_providers/dummy.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.dummy'}}
</a>
{{/if}}
<div local-class='container'>
<div local-class='container-left'>
<header local-class='login-header'>
<h1 local-class='title'>
{{inline-svg 'assets/logo.svg' local-class='logo'}}
{{t 'general.application_name'}}
</h1>
{{#if this.googleLoginEnabled}}
<a href={{this.googleUrl}} class='button button--filled' local-class='loginButton loginButton--google'>
<img src='assets/auth_providers/google.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.google'}}
</a>
{{/if}}
<p local-class='subtitle'>
{{{t 'components.login_header.subtitle'}}}
</p>
{{#if this.githubLoginEnabled}}
<a href={{this.githubUrl}} class='button button--filled' local-class='loginButton loginButton--github'>
<img src='assets/auth_providers/github.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.github'}}
</a>
{{/if}}
<p local-class='footer'>
<a href='https://github.com/mirego/accent'>{{t 'components.login_header.footer_open_source_link'}}</a>
{{t 'components.login_header.footer'}}
<a href='https://www.mirego.com'>{{t 'components.login_header.footer_mirego_link'}}</a>
<span local-class='version'>{{this.version}}</span>
</p>
</header>
</div>
{{#if this.gitlabLoginEnabled}}
<a href={{this.gitlabUrl}} class='button button--filled' local-class='loginButton loginButton--gitlab'>
<img src='assets/auth_providers/gitlab.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.gitlab'}}
</a>
{{/if}}
<div local-class='container-right'>
<div local-class='login-forms'>
{{#if this.slackLoginEnabled}}
<a href={{this.slackUrl}} class='button button--filled' local-class='loginButton loginButton--slack'>
<img src='assets/auth_providers/slack.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.slack'}}
</a>
{{/if}}
<h2 local-class='text'>
<strong>
{{t 'components.login_header.text'}}
</strong>
{{#if this.discordLoginEnabled}}
<a href={{this.discordUrl}} class='button button--filled' local-class='loginButton loginButton--discord'>
<img src='assets/auth_providers/discord.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.discord'}}
</a>
{{/if}}
<p>
{{t 'components.login_header.subtext'}}
</p>
</h2>
{{#if this.microsoftLoginEnabled}}
<a href={{this.microsoftUrl}} class='button button--filled' local-class='loginButton loginButton--microsoft'>
<img src='assets/auth_providers/microsoft.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.microsoft'}}
</a>
{{/if}}
{{#if @showLoading}}
<LoadingContent local-class='loading' />
{{/if}}
{{#if this.authZeroLoginEnabled}}
<a href={{this.auth0Url}} class='button button--filled' local-class='loginButton loginButton--auth0'>
<img src='assets/auth_providers/auth0.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.auth0'}}
</a>
{{/if}}
{{/if}}
{{#if @providers}}
{{#if this.dummyLoginEnabled}}
<input value={{this.username}} local-class='input' {{did-insert this.focusInput}} {{on 'keyup' (fn this.setUsername)}} />
<a href={{this.dummyUrl}} class='button button--filled' local-class='loginButton loginButton--dummy' disabled={{this.emptyUsername}}>
{{t 'components.login_forms.dummy'}}
</a>
{{/if}}
{{#if this.googleLoginEnabled}}
<a href={{this.googleUrl}} class='button button--filled' local-class='loginButton loginButton--google'>
<img src='assets/auth_providers/google.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.google'}}
</a>
{{/if}}
{{#if this.githubLoginEnabled}}
<a href={{this.githubUrl}} class='button button--filled' local-class='loginButton loginButton--github'>
<img src='assets/auth_providers/github.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.github'}}
</a>
{{/if}}
{{#if this.gitlabLoginEnabled}}
<a href={{this.gitlabUrl}} class='button button--filled' local-class='loginButton loginButton--gitlab'>
<img src='assets/auth_providers/gitlab.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.gitlab'}}
</a>
{{/if}}
{{#if this.slackLoginEnabled}}
<a href={{this.slackUrl}} class='button button--filled' local-class='loginButton loginButton--slack'>
<img src='assets/auth_providers/slack.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.slack'}}
</a>
{{/if}}
{{#if this.discordLoginEnabled}}
<a href={{this.discordUrl}} class='button button--filled' local-class='loginButton loginButton--discord'>
<img src='assets/auth_providers/discord.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.discord'}}
</a>
{{/if}}
{{#if this.microsoftLoginEnabled}}
<a href={{this.microsoftUrl}} class='button button--filled' local-class='loginButton loginButton--microsoft'>
<img src='assets/auth_providers/microsoft.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.microsoft'}}
</a>
{{/if}}
{{#if this.authZeroLoginEnabled}}
<a href={{this.auth0Url}} class='button button--filled' local-class='loginButton loginButton--auth0'>
<img src='assets/auth_providers/auth0.svg' local-class='loginButton-logo' />
{{t 'components.login_forms.auth0'}}
</a>
{{/if}}
{{/if}}
</div>
</div>
</div>

View File

@ -1,3 +0,0 @@
import Component from '@glimmer/component';
export default class LoginHeader extends Component {}

View File

@ -1,45 +0,0 @@
.login-header {
max-width: 500px;
margin: 100px auto 40px;
padding: 0 10px;
}
.title {
display: flex;
align-items: center;
margin-bottom: 45px;
}
.title-name {
margin-left: 15px;
text-decoration: none;
font-size: 25px;
font-weight: 700;
color: var(--color-black);
}
.text {
font-size: 17px;
line-height: 1.3;
color: var(--color-grey);
}
.text-emphasis {
display: block;
margin-bottom: 10px;
font-weight: bold;
font-size: 22px;
font-style: normal;
color: var(--color-black);
}
.logo {
width: 30px;
height: 30px;
}
@media (max-width: 440px) {
.login-header {
margin-top: 30px;
}
}

View File

@ -1,15 +0,0 @@
<header local-class='login-header'>
<h1 local-class='title'>
{{inline-svg 'assets/logo.svg' local-class='logo'}}
<span local-class='title-name'>
{{t 'general.application_name'}}
</span>
</h1>
<h2 local-class='text'>
<em local-class='text-emphasis'>
{{t 'components.login_header.text'}}
</em>
{{t 'components.login_header.subtext'}}
</h2>
</header>

View File

@ -33,13 +33,11 @@
transition: 0.2s ease-in-out;
transition-property: box-shadow;
border-radius: 3px;
box-shadow: 0 1px 4px var(--shadow-color), 0 4px 15px var(--shadow-color);
border: 1px solid var(--background-light-highlight);
color: var(--color-black);
&:focus,
&:hover {
box-shadow: 0 1px 6px var(--shadow-color), 0 5px 18px var(--shadow-color);
.projectName {
color: var(--color-primary);
}

View File

@ -3,7 +3,6 @@
height: 5px;
background: var(--background-light);
border-radius: 1px;
box-shadow: 0 1px 8px var(--shadow-color);
}
.progress {

View File

@ -1,4 +1,5 @@
import {inject as service} from '@ember/service';
import {readOnly} from '@ember/object/computed';
import Controller from '@ember/controller';
import JIPT from 'accent-webapp/services/jipt';
@ -6,6 +7,9 @@ export default class LoginController extends Controller {
@service('jipt')
jipt: JIPT;
@readOnly('model.loading')
showLoading: boolean;
constructor(...args: any) {
super(...args);

View File

@ -1,7 +1 @@
<div>
<LoginHeader />
<LoginForms @providers={{this.model.authenticationProviders}} />
<LoginFooter />
</div>
<ApplicationFooter />
<LoginForms @showLoading={{this.showLoading}} @providers={{this.model.authenticationProviders}} />