WEB-492: Material Design 3 implementation: Login

This commit is contained in:
Jose Alberto Hernandez
2026-01-04 14:06:28 -05:00
parent 5af11fe757
commit df7274626c
58 changed files with 3396 additions and 855 deletions
+157 -126
View File
@@ -1,148 +1,179 @@
<!-- The viewport is divided into two parts having max-width 70% and 30% -->
<div class="layout-row">
<!--
Content in 70%: (TODO: Allow customization by organization)
Cover Image
Organization/Application Name
Organization/Application Description
This content will be hidden for smaller screens.
-->
<div class="flex-70 layout-column align-center align-items-center hide-lt-sm cover">
<div class="cover-content">
<h1 class="mat-display-1 cover-title">{{ 'APP_NAME' | translate }}</h1>
<p class="mat-headline cover-description">
{{ 'APP_NAME' | translate }} {{ 'labels.text.is designed by the' | translate }}
<a [href]="'mifosHome' | documentationLink" target="_blank" rel="noopener noreferrer" class="cover-link">{{
'labels.text.Mifos Initiative' | translate
}}</a
>. {{ 'labels.text.A' | translate }}
<a [href]="'mifosCommunity' | documentationLink" target="_blank" rel="noopener noreferrer" class="cover-link">{{
'labels.text.global community' | translate
}}</a>
{{ 'labels.text.elimination of poverty' | translate }}
<a [href]="'mifosVolunteer' | documentationLink" target="_blank" rel="noopener noreferrer" class="cover-link"
>{{ 'labels.text.Get involved' | translate }}!</a
>
</p>
<!-- Modern Material Design 3 Login Layout -->
<div class="login-wrapper">
<!-- Left Panel - Hero Section (Hidden on mobile) -->
<div class="hero-panel hide-lt-md">
<div class="hero-overlay"></div>
<div class="hero-content">
<div class="hero-text">
<h1 class="hero-title">{{ 'APP_NAME' | translate }}</h1>
<p class="hero-subtitle">
{{ 'labels.text.A' | translate }}
<span class="hero-highlight">{{ 'labels.text.global community' | translate }}</span>
{{ 'labels.text.elimination of poverty' | translate }}
</p>
<div class="hero-features">
<div class="feature-item">
<fa-icon icon="shield-alt" class="feature-icon"></fa-icon>
<span class="feature-text">{{ 'labels.heading.Secure & Reliable' | translate }}</span>
</div>
<div class="feature-item">
<fa-icon icon="users" class="feature-icon"></fa-icon>
<span class="feature-text">{{ 'labels.heading.Community Driven' | translate }}</span>
</div>
<div class="feature-item">
<fa-icon icon="globe" class="feature-icon"></fa-icon>
<span class="feature-text">{{ 'labels.heading.Global Impact' | translate }}</span>
</div>
</div>
<div class="hero-links">
<a [href]="'mifosHome' | documentationLink" target="_blank" rel="noopener noreferrer" class="hero-link">
{{ 'labels.text.Mifos Initiative' | translate }}
<fa-icon icon="external-link-alt" size="sm"></fa-icon>
</a>
<a [href]="'mifosVolunteer' | documentationLink" target="_blank" rel="noopener noreferrer" class="hero-link">
{{ 'labels.text.Get involved' | translate }}
<fa-icon icon="external-link-alt" size="sm"></fa-icon>
</a>
</div>
</div>
<mifosx-footer variant="compact"></mifosx-footer>
</div>
</div>
<!--
Content in 30%: (TODO: Allow customization of Name, Logo and Contact Information by organization)
Language Selector
Organization/Application Name with Logo
Form
Contact Information/Resources
Footer
-->
<div class="layout-column flex-gt-sm-30 login-container">
<!-- Language Selector to the extreme right -->
<div class="layout-row-reverse">
<mifosx-language-selector class="p-t-10 p-r-10 width-40"></mifosx-language-selector>
<mifosx-theme-toggle class="p-t-10"></mifosx-theme-toggle>
<!-- Right Panel - Login Form -->
<div class="login-panel">
<!-- Header Controls -->
<div class="login-header">
@if (allowServerSwitch()) {
<mifosx-server-selector class="p-t-10"></mifosx-server-selector>
<mifosx-server-selector class="header-control" appearance="outline" [showLabel]="false">
</mifosx-server-selector>
}
<mifosx-theme-toggle class="header-control theme-toggle"></mifosx-theme-toggle>
<mifosx-language-selector class="header-control" appearance="outline" [showLabel]="false">
</mifosx-language-selector>
</div>
<!-- Logo with Organization Name -->
<div class="layout-row align-center-center flex-auto">
<img [src]="logoPath" (error)="onLogoError()" alt="{{ 'APP_NAME' | translate }} Logo" class="img-container" />
</div>
<!-- Main Login Card -->
<div class="login-card-container">
<div class="login-card">
<!-- Logo Section -->
<div class="logo-section">
@if (!themeDarkEnabled) {
<img [src]="logoPath" (error)="onLogoError()" alt="{{ 'APP_NAME' | translate }} Logo" class="logo-image" />
} @else {
<img src="assets/images/white-mifos.png" alt="{{ 'APP_NAME' | translate }} Logo" class="logo-image" />
}
<h2 class="welcome-text">{{ 'labels.heading.Welcome to Mifos' | translate }}</h2>
</div>
<!-- Form Section -->
<div class="layout-column align-center-center">
<!-- Tenant Identifier Name -->
@if (displayTenantSelector()) {
<mifosx-tenant-selector></mifosx-tenant-selector>
}
<!-- Form Section -->
<div class="form-section">
<!-- Tenant Selector -->
@if (displayTenantSelector()) {
<div class="tenant-section">
<mifosx-tenant-selector></mifosx-tenant-selector>
</div>
}
<!--
Type of Form:
Login
Reset Password
Two Factor Authentication
-->
@if (!resetPassword && !twoFactorAuthenticationRequired) {
<mifosx-login-form></mifosx-login-form>
}
<!-- Login Forms -->
@if (!resetPassword && !twoFactorAuthenticationRequired) {
<mifosx-login-form></mifosx-login-form>
}
<div class="layout-row">
@if (resetPassword) {
<mifosx-reset-password></mifosx-reset-password>
}
@if (twoFactorAuthenticationRequired) {
<mifosx-two-factor-authentication></mifosx-two-factor-authentication>
}
@if (resetPassword) {
<mifosx-reset-password></mifosx-reset-password>
}
@if (twoFactorAuthenticationRequired) {
<mifosx-two-factor-authentication></mifosx-two-factor-authentication>
}
</div>
<!-- Resources Links -->
<div class="resources-section">
<div class="resources-divider">
<span class="divider-text">{{ 'labels.links.Resources' | translate }}</span>
</div>
<div class="resources-links">
<button mat-button [matMenuTriggerFor]="resourcesMenu" class="resource-button">
<fa-icon icon="book" size="sm"></fa-icon>
{{ 'labels.links.Resources' | translate }}
</button>
<button mat-button [matMenuTriggerFor]="communityMenu" class="resource-button">
<fa-icon icon="users" size="sm"></fa-icon>
{{ 'labels.links.Community' | translate }}
</button>
<button mat-button [matMenuTriggerFor]="contributeMenu" class="resource-button">
<fa-icon icon="heart" size="sm"></fa-icon>
{{ 'labels.links.Contribute' | translate }}
</button>
</div>
</div>
</div>
</div>
<div class="layout-row">
<!-- Contact Information/Resources (hidden on smaller screens) -->
<mat-list class="information-list align-items-center custom-horizontal-list hide-lt-lg">
<mat-list-item
><button mat-button [matMenuTriggerFor]="resourcesMenu">
{{ 'labels.links.Resources' | translate }}
</button></mat-list-item
<!-- Footer -->
<div class="login-footer">
<div class="layout-column copy-label">
<p class="footer-content align-center">
{{ 'APP_NAME' | translate }} {{ 'labels.text.by' | translate }} Mifos
</p>
</div>
<button
mat-icon-button
(click)="reloadSettings()"
class="reload-button"
matTooltip="Reload Settings"
attr.aria-label="Reload Settings"
>
<mat-list-item
><button mat-button [matMenuTriggerFor]="communityMenu">
{{ 'labels.links.Community' | translate }}
</button></mat-list-item
>
<mat-list-item
><button mat-button [matMenuTriggerFor]="contributeMenu">
{{ 'labels.links.Contribute' | translate }}
</button></mat-list-item
>
</mat-list>
</div>
<!-- Footer -->
<mifosx-footer [styleClass]="'m-t-90'"></mifosx-footer>
<div class="layout-row m-b-20 m-r-10" align="end">
<a (click)="reloadSettings()"><fa-icon icon="refresh"></fa-icon></a>
<mifosx-m3-icon name="refresh"></mifosx-m3-icon>
</button>
</div>
</div>
</div>
</div>
<!-- Contact Information/Resources Menus -->
<mat-menu #resourcesMenu="matMenu">
<a [href]="'userManual' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>{{
'labels.links.User Manual' | translate
}}</a>
<a [href]="'fineractFunctionalSpecs' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>{{
'labels.links.Functional Specifications' | translate
}}</a>
<a [href]="'fineractContributorZone' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>{{
'labels.links.Developer Zone' | translate
}}</a>
<!-- Resource Menus -->
<mat-menu #resourcesMenu="matMenu" class="modern-menu">
<a [href]="'userManual' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>
<fa-icon icon="book-open" class="menu-icon"></fa-icon>
{{ 'labels.links.User Manual' | translate }}
</a>
<a [href]="'fineractFunctionalSpecs' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>
<fa-icon icon="file-alt" class="menu-icon"></fa-icon>
{{ 'labels.links.Functional Specifications' | translate }}
</a>
<a [href]="'fineractContributorZone' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>
<fa-icon icon="code" class="menu-icon"></fa-icon>
{{ 'labels.links.Developer Zone' | translate }}
</a>
</mat-menu>
<mat-menu #communityMenu="matMenu">
<a [href]="'mifosUserGroup' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>{{
'labels.links.User Group' | translate
}}</a>
<a [href]="'mifosDeveloperGroup' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>{{
'labels.links.Developer Group' | translate
}}</a>
<a [href]="'mifosIrc' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>{{
'labels.links.IRC' | translate
}}</a>
<mat-menu #communityMenu="matMenu" class="modern-menu">
<a [href]="'mifosUserGroup' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>
<fa-icon icon="users" class="menu-icon"></fa-icon>
{{ 'labels.links.User Group' | translate }}
</a>
<a [href]="'mifosDeveloperGroup' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>
<fa-icon icon="laptop-code" class="menu-icon"></fa-icon>
{{ 'labels.links.Developer Group' | translate }}
</a>
<a [href]="'mifosIrc' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>
<fa-icon icon="comments" class="menu-icon"></fa-icon>
{{ 'labels.links.IRC' | translate }}
</a>
</mat-menu>
<mat-menu #contributeMenu="matMenu">
<a [href]="'keyDesignPrinciples' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>{{
'labels.links.Key Design Principles' | translate
}}</a>
<a [href]="'sourceforgeMifos' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>{{
'labels.links.Working with Code' | translate
}}</a>
<a [href]="'mifosDonate' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>{{
'labels.links.Donate' | translate
}}</a>
<mat-menu #contributeMenu="matMenu" class="modern-menu">
<a [href]="'keyDesignPrinciples' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>
<fa-icon icon="lightbulb" class="menu-icon"></fa-icon>
{{ 'labels.links.Key Design Principles' | translate }}
</a>
<a [href]="'sourceforgeMifos' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>
<fa-icon icon="code-branch" class="menu-icon"></fa-icon>
{{ 'labels.links.Working with Code' | translate }}
</a>
<a [href]="'mifosDonate' | documentationLink" target="_blank" rel="noopener noreferrer" mat-menu-item>
<fa-icon icon="hand-holding-heart" class="menu-icon"></fa-icon>
{{ 'labels.links.Donate' | translate }}
</a>
</mat-menu>