2
0
Fork 0

MOBILE-4201 login: Login restyling

main
Pau Ferrer Ocaña 2023-09-05 17:52:11 +02:00
parent 0a3125837d
commit eead77bff9
8 changed files with 224 additions and 155 deletions

View File

@ -45,7 +45,6 @@
display: block; display: block;
img { img {
padding: 4px;
border-radius: 50%; border-radius: 50%;
} }
} }

View File

@ -1,6 +1,5 @@
<div *ngIf="loginMethods.length || identityProviders.length || showScanQR" <div *ngIf="loginMethods.length || identityProviders.length || showScanQR" class="ion-text-center ion-padding core-login-methods-separator">
class="ion-text-center ion-padding core-login-site-qrcode-separator"> <span>{{ 'core.login.or' | translate }}</span>
{{ 'core.login.or' | translate }}
</div> </div>
<div class="core-login-methods" *ngIf="loginMethods.length"> <div class="core-login-methods" *ngIf="loginMethods.length">
@ -19,12 +18,8 @@
</ng-container> </ng-container>
<!-- Identity providers. --> <!-- Identity providers. -->
<ion-list *ngIf="identityProviders.length" class="ion-padding-top core-login-identity-providers"> <ion-list *ngIf="identityProviders.length" class="core-login-identity-providers">
<ion-item class="ion-text-wrap">
<ion-label>
<h2 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h2> <h2 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h2>
</ion-label>
</ion-item>
<ion-button [fill]="'outline'" *ngFor="let provider of identityProviders" class="ion-text-wrap ion-margin core-oauth-provider" <ion-button [fill]="'outline'" *ngFor="let provider of identityProviders" class="ion-text-wrap ion-margin core-oauth-provider"
(click)="oauthClicked(provider)" [attr.aria-label]="provider.name" expand="block"> (click)="oauthClicked(provider)" [attr.aria-label]="provider.name" expand="block">
<img *ngIf="provider.iconurl" [src]="provider.iconurl" alt="" width="32" height="32" slot="start" aria-hidden="true"> <img *ngIf="provider.iconurl" [src]="provider.iconurl" alt="" width="32" height="32" slot="start" aria-hidden="true">

View File

@ -85,7 +85,7 @@
"onboardingprovidefeedback": "Provide timely feedback", "onboardingprovidefeedback": "Provide timely feedback",
"onboardingtoconnect": "To connect to the Moodle App you'll need a Moodle site", "onboardingtoconnect": "To connect to the Moodle App you'll need a Moodle site",
"onboardingwelcome": "Welcome to the Moodle App!", "onboardingwelcome": "Welcome to the Moodle App!",
"or": "OR", "or": "Or",
"password": "Password", "password": "Password",
"passwordforgotten": "Forgotten password", "passwordforgotten": "Forgotten password",
"passwordforgotteninstructions2": "To reset your password, submit your username or your email address below. If we can find you in the database, an email will be sent to your email address, with instructions how to get access again.", "passwordforgotteninstructions2": "To reset your password, submit your username or your email address below. If we can find you in the database, an email will be sent to your email address, with instructions how to get access again.",

View File

@ -16,10 +16,6 @@
} }
} }
form div {
color: var(--color);
}
ion-button.core-button-as-link { ion-button.core-button-as-link {
--color: var(--core-login-text-color); --color: var(--core-login-text-color);
text-decoration-color: var(--core-login-text-color); text-decoration-color: var(--core-login-text-color);
@ -29,6 +25,53 @@
} }
} }
.core-login-reconnect-warning {
margin: 0px 0px 32px 0px;
}
.core-login-info-box {
margin-bottom: 32px;
.core-login-site {
.core-login-site-logo {
width: 90%;
max-width: 300px;
margin: 0px auto;
img {
max-width: 100%;
max-height: 104px;
}
}
.core-sitename {
font-size: 1.2rem;
margin-bottom: 8px;
}
.core-siteurl {
margin-top: 8px;
margin-bottom: 0px;
}
}
.core-login-site + .core-login-user {
margin-top: 24px;
}
}
core-user-avatar.large-avatar {
--core-avatar-size: var(--core-large-avatar-size);
}
.core-login-fullname {
margin-top: 8px;
margin-bottom: 0px;
}
.core-login-methods {
form .item.item-input { form .item.item-input {
margin-bottom: 16px; margin-bottom: 16px;
} }
@ -38,34 +81,17 @@
--background: var(--core-login-input-background); --background: var(--core-login-input-background);
--color: var(--core-login-input-color); --color: var(--core-login-input-color);
} }
.core-login-site-logo img {
max-width: 100%;
} }
.core-sitename + .core-siteurl { ion-button {
margin-top: 0; margin-left: 0px;
} margin-right: 0px;
.core-sitename {
font-size: 1.2rem;
margin-bottom: 0;
}
.core-login-site-logo {
width: 90%;
max-width: 300px;
margin: 5px auto;
} }
.core-login-forgotten-password { .core-login-forgotten-password {
text-decoration: underline; text-decoration: underline;
} }
core-user-avatar.large-avatar {
--core-avatar-size: var(--core-large-avatar-size);
}
@if ($core-login-hide-forgot-password) { @if ($core-login-hide-forgot-password) {
.core-login-forgotten-password { .core-login-forgotten-password {
display: none; display: none;
@ -93,15 +119,59 @@
} }
} }
.core-login-methods-separator {
position: relative;
padding: 8px 0;
span {
background: var(--core-login-background);
padding: 0 8px;
}
&::before {
height: 1px;
position: absolute;
top: 50%;
left: 0px;
right: 0px;
border-bottom: 1px solid var(--gray-300);
content: "";
z-index: -1;
}
}
@if ($core-login-hide-qrcode) { @if ($core-login-hide-qrcode) {
.core-login-site-qrcode, .core-login-site-qrcode,
.core-login-site-qrcode-separator { .core-login-methods-separator {
display: none; display: none;
} }
} }
.core-login-login-button {
margin-top: 32px;
}
.core-login-login-inbrowser-button {
margin-bottom: 8px;
}
p.core-login-inbrowser { p.core-login-inbrowser {
font-size: 12px; font-size: 12px;
margin-top: 8px;
margin-bottom: 8px;
}
.core-login-sign-up {
margin-top: 8px;
border-top: 1px solid var(--gray-300);
}
.core-login-identity-providers h2,
.core-login-sign-up h2 {
margin-top: 16px;
margin-bottom: 8px;
font-size: 16px;
} }
} }

View File

@ -20,24 +20,27 @@
</ion-header> </ion-header>
<ion-content class="ion-padding limited-width"> <ion-content class="ion-padding limited-width">
<core-loading [hideUntil]="pageLoaded"> <core-loading [hideUntil]="pageLoaded">
<div class="ion-text-wrap ion-text-center ion-margin-bottom"> <div class="ion-text-wrap ion-text-center core-login-info-box">
<div class="core-login-site">
<div class="core-login-site-logo"> <div class="core-login-site-logo">
<!-- Show site logo or a default image. --> <!-- Show site logo or a default image. -->
<img *ngIf="logoUrl" [src]="logoUrl" role="presentation" alt="" onError="this.src='assets/img/login_logo.png'"> <img *ngIf="logoUrl" [src]="logoUrl" role="presentation" alt="" onError="this.src='assets/img/login_logo.png'">
<img *ngIf="!logoUrl" src="assets/img/login_logo.png" role="presentation" alt=""> <img *ngIf="!logoUrl" src="assets/img/login_logo.png" role="presentation" alt="">
</div> </div>
<h2 *ngIf="siteName" class="ion-padding core-sitename"> <h2 *ngIf="siteName" class="ion-margin-top ion-no-padding core-sitename">
<core-format-text [text]="siteName" [filter]="false"></core-format-text> <core-format-text [text]="siteName" [filter]="false"></core-format-text>
</h2> </h2>
<p class="core-siteurl">{{siteUrl}}</p> <p class="core-siteurl">{{siteUrl}}</p>
</div> </div>
<core-login-exceeded-attempts *ngIf="exceededAttemptsHTML && supportConfig && loginAttempts >= 3" [supportConfig]="supportConfig" <core-login-exceeded-attempts *ngIf="exceededAttemptsHTML && supportConfig && loginAttempts >= 3"
[supportSubject]="'core.login.exceededloginattemptssupportsubject' | translate"> [supportConfig]="supportConfig" [supportSubject]="'core.login.exceededloginattemptssupportsubject' | translate">
<div [innerHTML]="exceededAttemptsHTML" (click)="exceededAttemptsClicked($event)"></div> <div [innerHTML]="exceededAttemptsHTML" (click)="exceededAttemptsClicked($event)"></div>
</core-login-exceeded-attempts> </core-login-exceeded-attempts>
</div>
<div class="core-login-methods">
<form [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #credentialsForm *ngIf="!isBrowserSSO"> <form [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #credentialsForm *ngIf="!isBrowserSSO">
<ion-item> <ion-item>
<ion-label class="sr-only">{{ 'core.login.username' | translate }}</ion-label> <ion-label class="sr-only">{{ 'core.login.username' | translate }}</ion-label>
@ -49,11 +52,13 @@
<ion-label class="sr-only">{{ 'core.login.password' | translate }}</ion-label> <ion-label class="sr-only">{{ 'core.login.password' | translate }}</ion-label>
<core-show-password name="password"> <core-show-password name="password">
<ion-input name="password" type="password" placeholder="{{ 'core.login.password' | translate }}" <ion-input name="password" type="password" placeholder="{{ 'core.login.password' | translate }}"
formControlName="password" [clearOnEdit]="false" autocomplete="current-password" enterkeyhint="go" required="true"> formControlName="password" [clearOnEdit]="false" autocomplete="current-password" enterkeyhint="go"
required="true">
</ion-input> </ion-input>
</core-show-password> </core-show-password>
</ion-item> </ion-item>
<ion-button expand="block" type="submit" [disabled]="!credForm.valid" class="ion-margin core-login-login-button ion-text-wrap"> <ion-button expand="block" type="submit" [disabled]="!credForm.valid"
class="ion-margin core-login-login-button ion-text-wrap">
{{ 'core.login.loginbutton' | translate }} {{ 'core.login.loginbutton' | translate }}
</ion-button> </ion-button>
<!-- Remove this once Ionic fixes this bug: https://github.com/ionic-team/ionic-framework/issues/19368 --> <!-- Remove this once Ionic fixes this bug: https://github.com/ionic-team/ionic-framework/issues/19368 -->
@ -67,7 +72,7 @@
</form> </form>
<ng-container *ngIf="isBrowserSSO"> <ng-container *ngIf="isBrowserSSO">
<ion-button expand="block" (click)="openBrowserSSO()" class="ion-margin core-login-login-button ion-text-wrap"> <ion-button expand="block" (click)="openBrowserSSO()" class="ion-margin core-login-login-inbrowser-button ion-text-wrap">
{{ 'core.login.loginbutton' | translate }} {{ 'core.login.loginbutton' | translate }}
<ion-icon name="fas-up-right-from-square" slot="end" aria-hidden="true"></ion-icon> <ion-icon name="fas-up-right-from-square" slot="end" aria-hidden="true"></ion-icon>
</ion-button> </ion-button>
@ -76,23 +81,21 @@
<core-login-methods *ngIf="siteConfig" [siteConfig]="siteConfig" [siteUrl]="siteUrl"></core-login-methods> <core-login-methods *ngIf="siteConfig" [siteConfig]="siteConfig" [siteUrl]="siteUrl"></core-login-methods>
</div>
<ion-list *ngIf="canSignup || authInstructions" class="ion-padding-top core-login-sign-up"> <div class="core-login-sign-up" *ngIf="canSignup || authInstructions">
<ion-item class="ion-text-wrap"> <h2>{{ 'core.login.firsttime' | translate }}</h2>
<ion-item class="ion-text-wrap ion-no-padding core-login-instructions">
<ion-label> <ion-label>
<h2 class="item-heading">{{ 'core.login.firsttime' | translate }}</h2> <core-format-text *ngIf="authInstructions" [text]="authInstructions" [filter]="false"></core-format-text>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="authInstructions">
<ion-label>
<p>
<core-format-text [text]="authInstructions" [filter]="false"></core-format-text>
</p>
</ion-label> </ion-label>
</ion-item> </ion-item>
</div>
<ion-button *ngIf="canSignup" expand="block" class="ion-margin ion-text-wrap" fill="outline" (click)="openEmailSignup()"> <ion-button *ngIf="canSignup" expand="block" class="ion-margin ion-text-wrap" fill="outline" (click)="openEmailSignup()">
{{ 'core.login.startsignup' | translate }} {{ 'core.login.startsignup' | translate }}
</ion-button> </ion-button>
</ion-list>
</core-loading> </core-loading>
</ion-content> </ion-content>

View File

@ -20,40 +20,44 @@
<ion-content class="ion-padding" (keydown)="keyDown($event)" (keyup)="keyUp($event)"> <ion-content class="ion-padding" (keydown)="keyDown($event)" (keyup)="keyUp($event)">
<core-loading [hideUntil]="!showLoading"> <core-loading [hideUntil]="!showLoading">
<div class="list-item-limited-width"> <div class="list-item-limited-width">
<ion-card *ngIf="!isLoggedOut" class="core-danger-card core-login-reconnect-warning"> <ion-card *ngIf="!isLoggedOut" class="core-warning-card core-login-reconnect-warning">
<ion-item> <ion-item>
<ion-icon name="fas-circle-exclamation" slot="start" aria-hidden="true"></ion-icon> <ion-icon name="fas-triangle-exclamation" slot="start" aria-hidden="true"></ion-icon>
<ion-label> <ion-label>
<p>{{ 'core.lostconnection' | translate }}</p> <p>{{ 'core.lostconnection' | translate }}</p>
</ion-label> </ion-label>
</ion-item> </ion-item>
</ion-card> </ion-card>
<div class="ion-text-wrap ion-text-center ion-margin-bottom" [ngClass]="{'item-avatar-center': showUserAvatar}"> <div class="ion-text-wrap ion-text-center core-login-info-box">
<div class="core-login-site">
<div class="core-login-site-logo" *ngIf="!showUserAvatar"> <div class="core-login-site-logo" *ngIf="!showUserAvatar">
<!-- Show site logo or a default image. --> <!-- Show site logo or a default image. -->
<img *ngIf="logoUrl" [src]="logoUrl" role="presentation" onError="this.src='assets/img/login_logo.png'" alt=""> <img *ngIf="logoUrl" [src]="logoUrl" role="presentation" onError="this.src='assets/img/login_logo.png'" alt="">
<img *ngIf="!logoUrl" src="assets/img/login_logo.png" role="presentation" alt=""> <img *ngIf="!logoUrl" src="assets/img/login_logo.png" role="presentation" alt="">
</div> </div>
<p *ngIf="siteInfo?.siteName" class="ion-padding core-sitename"> <p *ngIf="siteInfo?.siteName" class="ion-no-margin ion-no-padding core-sitename">
<core-format-text [text]="siteInfo?.siteName" [filter]="false"></core-format-text> <core-format-text [text]="siteInfo?.siteName" [filter]="false"></core-format-text>
</p> </p>
<p class="core-siteurl">{{siteUrl}}</p> <p class="core-siteurl">{{siteUrl}}</p>
</div>
<div class="core-login-user">
<!-- Show user avatar. --> <!-- Show user avatar. -->
<core-user-avatar class="large-avatar" *ngIf="showUserAvatar" [user]="siteInfo" [linkProfile]="false" <core-user-avatar class="large-avatar" *ngIf="showUserAvatar" [user]="siteInfo" [linkProfile]="false"
[siteId]="siteId"></core-user-avatar> [siteId]="siteId"></core-user-avatar>
<p *ngIf="siteInfo?.fullname" class="core-login-fullname"> <p *ngIf="siteInfo?.fullname" class="core-login-fullname">
<core-format-text [text]="siteInfo?.fullname" [filter]="false"></core-format-text> <core-format-text [text]="siteInfo?.fullname" [filter]="false"></core-format-text>
</p> </p>
</div>
<core-login-exceeded-attempts *ngIf="exceededAttemptsHTML && supportConfig && reconnectAttempts >= 3" <core-login-exceeded-attempts *ngIf="exceededAttemptsHTML && supportConfig && reconnectAttempts >= 3"
[supportConfig]="supportConfig" [supportSubject]="'core.login.exceededloginattemptssupportsubject' | translate"> [supportConfig]="supportConfig" [supportSubject]="'core.login.exceededloginattemptssupportsubject' | translate">
<div [innerHTML]="exceededAttemptsHTML" (click)="exceededAttemptsClicked($event)"></div> <div [innerHTML]="exceededAttemptsHTML" (click)="exceededAttemptsClicked($event)"></div>
</core-login-exceeded-attempts> </core-login-exceeded-attempts>
</div> </div>
<div class="core-login-methods">
<form *ngIf="!isBrowserSSO" [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #reconnectForm> <form *ngIf="!isBrowserSSO" [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #reconnectForm>
<ion-item class="ion-margin-bottom"> <ion-item class="ion-margin-bottom">
<ion-label class="sr-only">{{ 'core.login.password' | translate }}</ion-label> <ion-label class="sr-only">{{ 'core.login.password' | translate }}</ion-label>
@ -77,7 +81,8 @@
</form> </form>
<ng-container *ngIf="isBrowserSSO"> <ng-container *ngIf="isBrowserSSO">
<ion-button expand="block" (click)="openBrowserSSO()" class="ion-margin core-login-login-button ion-text-wrap"> <ion-button expand="block" (click)="openBrowserSSO()"
class="ion-margin core-login-login-inbrowser-button ion-text-wrap">
{{ 'core.login.loginbutton' | translate }} {{ 'core.login.loginbutton' | translate }}
<ion-icon name="fas-up-right-from-square" slot="end" aria-hidden="true"></ion-icon> <ion-icon name="fas-up-right-from-square" slot="end" aria-hidden="true"></ion-icon>
</ion-button> </ion-button>
@ -87,7 +92,7 @@
<!-- Additional Login methods --> <!-- Additional Login methods -->
<core-login-methods *ngIf="siteConfig" [siteConfig]="siteConfig" [reconnect]="true" [siteUrl]="siteUrl" <core-login-methods *ngIf="siteConfig" [siteConfig]="siteConfig" [reconnect]="true" [siteUrl]="siteUrl"
[redirectData]="redirectData"></core-login-methods> [redirectData]="redirectData"></core-login-methods>
</div>
</div> </div>
</core-loading> </core-loading>
</ion-content> </ion-content>

View File

@ -902,10 +902,7 @@ img.large-avatar,
height: var(--core-large-avatar-size); height: var(--core-large-avatar-size);
max-width: var(--core-large-avatar-size); max-width: var(--core-large-avatar-size);
max-height: var(--core-large-avatar-size); max-height: var(--core-large-avatar-size);
margin-bottom: 10px;
border-radius: 50%; border-radius: 50%;
padding: 4px;
border: 1px solid var(--stroke);
background-color: transparent; background-color: transparent;
} }

View File

@ -328,7 +328,7 @@ html {
--core-star-color: var(--primary); --core-star-color: var(--primary);
--core-large-avatar-size: 90px; --core-large-avatar-size: 80px;
--core-avatar-size: var(--a11y-min-target-size); --core-avatar-size: var(--a11y-min-target-size);
--core-avatar-radius: 50%; --core-avatar-radius: 50%;